iOS
Błędy debugowania
Szukaj…
Znajdowanie informacji o awarii
Gdy aplikacja ulegnie awarii, Xcode wejdzie do debuggera i wyświetli więcej informacji o awarii:
Najważniejsze części to:
Czerwona strzałka
Czerwona strzałka pokazuje, która linia kodu uległa awarii i dlaczego się zawiesiła.
Konsola debuggera
Wiele awarii rejestruje więcej informacji w konsoli debuggera. Powinien pojawić się automatycznie po awarii aplikacji, ale jeśli go nie ma, pokaż debuger, wybierając opcję
przycisk w prawym górnym rogu Xcode i wyświetl konsolę, klikając
przycisk w prawym dolnym rogu debuggera.
Ślad stosu
Śledzenie stosu zawiera listę funkcji, z których pochodzi program, zanim dotarł do kodu, który się zawiesił.
Część śladu stosu jest wyświetlana w Nawigatorze debugowania po lewej stronie ekranu, a elementy sterujące debugera pozwalają wybrać ramkę stosu do wyświetlenia w debuggerze:
Jeśli wpiszesz polecenie bt wierszu polecenia (lldb) w debuggerze i naciśniesz return , otrzymasz tekstową reprezentację śladu stosu, którą możesz skopiować i wkleić:
(lldb) bt
* thread #1: tid = 0x3aaec5, 0x00007fff91055f06 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00007fff91055f06 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x000000010008142d libsystem_pthread.dylib`pthread_kill + 90
frame #2: 0x00007fff96dc76e7 libsystem_c.dylib`abort + 129
frame #3: 0x00007fff8973bf81 libc++abi.dylib`abort_message + 257
frame #4: 0x00007fff89761a47 libc++abi.dylib`default_terminate_handler() + 267
frame #5: 0x00007fff94f636ae libobjc.A.dylib`_objc_terminate() + 103
frame #6: 0x00007fff8975f19e libc++abi.dylib`std::__terminate(void (*)()) + 8
frame #7: 0x00007fff8975ec12 libc++abi.dylib`__cxa_throw + 121
frame #8: 0x00007fff94f6108c libobjc.A.dylib`objc_exception_throw + 318
frame #9: 0x00007fff8d067372 CoreFoundation`-[__NSPlaceholderArray initWithObjects:count:] + 290
frame #10: 0x00007fff8d0eaa1f CoreFoundation`+[NSArray arrayWithObject:] + 47
* frame #11: 0x0000000100001b54 test`main(argc=1, argv=0x00007fff5fbff808) + 68 at main.m:15
frame #12: 0x00007fff8bea05ad libdyld.dylib`start + 1
frame #13: 0x00007fff8bea05ad libdyld.dylib`start + 1
Debugowanie SIGABRT i EXC_BAD_INSTRUCTION ulega awarii
SIGABRT lub EXC_BAD_INSTRUCTION zwykle oznacza, że aplikacja celowo uległa awarii, ponieważ niektóre testy zakończyły się niepowodzeniem. Powinny one zalogować komunikat do konsoli debugera z dodatkowymi informacjami; sprawdź tam, aby uzyskać więcej informacji.
Wiele SIGABRT jest spowodowanych nieprzechwyconymi wyjątkami Celu C. Istnieje wiele powodów, dla których można zgłaszać wyjątki i zawsze rejestrują one wiele przydatnych informacji w konsoli.
-
NSInvalidArgumentException, co oznacza, że aplikacja przekazała nieprawidłowy argument do metody -
NSRangeException, co oznacza, że aplikacja próbowała uzyskać dostęp do indeksu poza zakresem obiektu, takiego jakNSArraylubNSString -
NSInternalInconsistencyExceptionoznacza, że obiekt wykrył, że był w nieoczekiwanym stanie. -
NSUnknownKeyExceptionzwykle oznacza, że masz złe połączenie w XIB. Wypróbuj niektóre odpowiedzi na to pytanie .
Debugowanie EXC_BAD_ACCESS
EXC_BAD_ACCESS oznacza, że proces próbował uzyskać dostęp do pamięci w niepoprawny sposób, na przykład wyrejestrowanie wskaźnika NULL lub zapis do pamięci tylko do odczytu. Jest to najtrudniejszy rodzaj awarii do debugowania, ponieważ zwykle nie zawiera komunikatu o błędzie, a niektóre awarie mogą być bardzo trudne do odtworzenia i / lub występują w kodzie całkowicie niezwiązanym z problemem. Ten błąd występuje bardzo rzadko w Swift, ale jeśli wystąpi, często można uzyskać łatwiejsze do debugowania awarie poprzez zmniejszenie optymalizacji kompilatora.
Większość błędów EXC_BAD_ACCESS jest spowodowana próbą wyłuskiwania wskaźnika NULL . W takim przypadku adres wymieniony w czerwonej strzałce będzie zwykle liczbą szesnastkową niższą niż normalny adres pamięci, często 0x0 . Ustaw punkty przerwania w debuggerze lub dodaj okazjonalne instrukcje printf / NSLog , aby dowiedzieć się, dlaczego ten wskaźnik ma NULL .
EXC_BAD_ACCESS który występuje mniej niezawodnie lub nie ma żadnego sensu, może być wynikiem problemu z zarządzaniem pamięcią. Typowe problemy, które mogą to powodować:
- Używanie pamięci, która została zwolniona
- Próba zapisu poza końcem tablicy C lub innego rodzaju bufora
- Korzystanie ze wskaźnika, który nie został zainicjowany
W sekcji Diagnostyka edytora schematów Xcode zawiera kilka przydatnych narzędzi ułatwiających debugowanie problemów z pamięcią:
Address Sanitizer dodaje wiele kontroli, które zatrzymają aplikację za każdym razem, gdy wystąpią problemy z pamięcią i dostarczą pomocnego komunikatu o błędzie szczegółowo opisującego, co się stało. Zombie Objects wykrywa problemy z cofniętymi obiektami Objective-C, ale nie powinieneś mieć tego typu problemów z włączonym automatycznym zliczaniem odniesień.


