Za każdym razem, gdy moja aplikacja ulega awarii, Xcode podświetla wywołanie UIApicationMain () w funkcji main () jako wiersz, który spowodował awarię. W niektórych przypadkach było to normalne (na przykład błąd segmentacji), ale awaria, z którą próbuję sobie poradzić, to prosty SIGABRT ze szczegółowymi informacjami zarejestrowanymi w konsoli:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Date)'
Xcode pokazywał linię poprawnie ze starszymi SDK, ale od czasu aktualizacji do Xocde 4.2 to się zmieniło. Jest całkiem oczywiste, że Xcode dokładnie wie, co spowodowało awarię (lub może wiedzieć), ale nadal nie pokazuje rzeczywistej linii. Czy jest jakieś rozwiązanie lub obejście tego problemu?
objective-c
ios
xcode
cocoa-touch
nsexception
JonasG
źródło
źródło
Odpowiedzi:
Powinieneś również upewnić się, że masz ustawione punkty przerwania dla wszystkich wyjątków. Spowoduje to zatrzymanie Xcode w wierszu, w którym występuje wyjątek. Wykonaj następujące czynności [w Xcode 4]:
W Nawigatorze projektu po lewej stronie Xcode kliknij nawigator punktów przerwania (prawie do prawej strony górnego paska przycisków. Ikona wygląda jak gruba strzałka w prawo).
W dolnej części nawigatora kliknij przycisk „+”.
Kliknij „Dodaj punkt przerwania wyjątku”.
Zostanie utworzony nowy punkt przerwania. Powinien być skonfigurowany zgodnie z potrzebami, ale możesz dostosować jego zachowanie.
Uruchom projekt i odtwórz wyjątek.
Wspomniałeś również, że połączyłeś się z niektórymi bibliotekami / frameworkami stron trzecich. Jeśli wyjątek występuje w tych strukturach, będziesz miał trudności, ponieważ kod jest kompilowany, a Xcode nie może w rzeczywistości pokazać ci wiersza, który spowodował wyjątek. Jeśli tak jest i jesteś pewien, że używasz bibliotek poprawnie, powinieneś zgłosić błąd do opiekunów tych bibliotek.
źródło
Po prostu postępuj zgodnie z instrukcjami w tej odpowiedzi StackOverflow:
Włącz zombie
Zasadniczo wystarczy „włączyć zombie”. Następnie Xcode powinien się zepsuć w dowolnej linii powodującej problem.
(To absolutnie szokujące, że nawet w 2017 roku Xcode nadal ma to domyślnie wyłączone. Dlaczego nie chcesz widzieć linii, która spowodowała problem? I „ Włącz obiekty zombie ”?! Naprawdę?! Czy autorzy Xcode naprawdę wierzysz, że jest to użyteczna nazwa, która miałaby sens dla nowych programistów? To przygnębiające, jak słaba jest ocena Xcode rok po roku w App Store. Nikt nie słucha ...)
źródło
Edycja obecnego systemu i pozwalają
NSZombieEnabled
,MallocStackLogging
orazguard malloc
. Następnie, gdy aplikacja ulegnie awarii, wpisz w konsoli gdb:Zastąp
0x543216
adres obiektu, który spowodował błądNSInvalidArgumentException
i powinien on dać znacznie bardziej użyteczny ślad stosu, pokazujący wiersze kodu, które powodują awarię.źródło
Widziałem to zachowanie w mocno zoptymalizowanym kodzie; Pomocne może być sprawdzanie, dostosowywanie poziomu optymalizacji celu i bibliotek innych firm. (Ustawienie poziomu optymalizacji LLVM 3.0)
Czy generujesz symbole debugowania?
źródło
Napisałem kod, aby wygenerować awarię indeksu poza wiązaniem. Poniżej znajduje się zgłoszony wyjątek.
Jeśli uważnie przeczytasz
First Throw call stack
0 and 1
to procesy systemowe po awarii.2
to linia, która spowodowała wyjątek.3
informuje, że nazwa klasy (ViewController
) i funkcja naem (ComplexFunction
), w której został zgłoszony wyjątek.źródło