Nic, co próbowałem, nie naprawiłoby tego (wypróbowałem oba kompilatory, oba debuggery itp.) Po uaktualnieniu XCode do aktualizacji iOS 5, żadne ślady stosu wydawały się nie działać.
Jednak znalazłem skuteczne obejście - utworzenie własnego modułu obsługi wyjątków (który jest również przydatny z innych powodów). Najpierw utwórz funkcję, która obsłuży błąd i wyśle ją do konsoli (a także wszystkiego, co chcesz z nią zrobić):
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}
Następnie dodaj procedurę obsługi wyjątków do delegata aplikacji:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// Normal launch stuff
}
Otóż to!
Jeśli to nie zadziała, są tylko dwa możliwe powody :
- Coś nadpisuje twoje
NSSetUncaughtExceptionHandler
wywołanie (może być tylko jeden program obsługi dla całej aplikacji). Na przykład niektóre biblioteki innych firm ustawiają własne uncaughtExceptionHandler. Spróbuj więc ustawić go na końcu swojej didFinishLaunchingWithOptions
funkcji (lub selektywnie wyłącz biblioteki innych firm). Lub jeszcze lepiej, ustaw symboliczny punkt przerwania, NSSetUncaughtExceptionHandler
aby szybko zobaczyć, kto do niego dzwoni. To, co możesz chcieć zrobić, to zmodyfikować bieżącą, zamiast dodawać kolejną.
- Nie jesteś rzeczywiście napotyka wyjątek (na przykład,
EXC_BAD_ACCESS
to nie wyjątek, kredyt komentarze @Erik B, poniżej)
uncaughtExceptionHandler
procedura nigdy nie jest wywoływana.Istnieje przydatna opcja dodania punktu przerwania wyjątku (za pomocą + u dołu nawigatora punktów przerwania). Spowoduje to przerwanie w przypadku każdego wyjątku (lub możesz ustawić warunki). Nie wiem, czy ten wybór jest nowy w 4.2, czy dopiero w końcu zauważyłem, że próbuję obejść problem z brakującymi symbolami.
Po osiągnięciu tego punktu przerwania możesz użyć nawigatora debugowania, aby nawigować po stosie wywołań, badać zmienne itp. Jak zwykle.
Jeśli potrzebujesz symbolicznego stosu wywołań odpowiedniego do kopiowania / wklejania itp., GDB backtrace będzie działał dobrze:
(itp)
źródło
Debugger ma nową funkcję. Możesz ustawić punkt przerwania za każdym razem, gdy zostanie zgłoszony wyjątek i zatrzymać wykonywanie w tym miejscu, tak jak miało to miejsce w 4.0.
W „Nawigatorze punktów przerwania” dodaj „Punkt przerwania wyjątku” i po prostu naciśnij „Gotowe” w wyskakującym okienku opcji.
To wszystko!
PS: W niektórych przypadkach lepiej byłoby przerwać tylko dla wyjątków Cel-C.
źródło
Oto jeszcze jedno rozwiązanie, nie tak eleganckie jak poprzednie, ale jeśli nie dodałeś punktów przerwania lub obsługi wyjątków, może to być tylko jedna droga.
Gdy aplikacja ulegnie awarii i otrzymasz surowy stos wywołań pierwszego rzutu (w liczbach szesnastkowych), wpisz w konsoli Xcode
info line *hex
(nie zapomnij o0x
specyfikatorze gwiazdy i szesnastkowym), na przykład:Jeśli używasz lldb , możesz wpisać
image lookup -a hex
(w tej sytuacji bez gwiazdki), a otrzymasz podobny wynik.Dzięki tej metodzie możesz przejść od góry stosu rzutów (będzie około 5-7 propagatorów wyjątków systemowych) do funkcji, która spowodowała awarię i określić dokładny plik i wiersz kodu.
Aby uzyskać podobny efekt, możesz użyć narzędzia atos w terminalu, po prostu wpisz:
i otrzymujesz symboliczny ślad stosu (przynajmniej dla funkcji masz symbole debugowania). Ta metoda jest bardziej preferowana, ponieważ nie masz dla każdego wywołania adresu
info line
, po prostu skopiuj adresy z wyjścia konsoli i wklej je do terminala.źródło
Możesz dodać punkt przerwania wyjątku (za pomocą + u dołu nawigatora punktów przerwania) i dodać do niego akcję
bt
(kliknij przycisk Dodaj akcję, wybierz polecenie Debugera, wpisz „bt” w polu tekstowym). Spowoduje to wyświetlenie śladu stosu, gdy tylko zostanie zgłoszony wyjątek.źródło
Jest to częsty problem, który nie pozwala na uzyskanie śladów stosu w wersji 4.2. Możesz spróbować zamienić się między LLDB i GDB, aby sprawdzić, czy uzyskasz lepsze wyniki.
Zgłoś błąd tutaj.
http://developer.apple.com/bugreporter/
EDYTOWAĆ:
Wierzę, że jeśli przełączysz się z powrotem na LLVM GCC 4.2, nie zobaczysz tego. Możesz jednak stracić funkcje, których potrzebujesz.
źródło
Użyj tego kodu w swojej głównej funkcji:
źródło
W konsoli debugowania Xcode wpisz:
I pokaże ci coś takiego:
źródło
Włączenie „Kompiluj dla Thumb” (konfiguracja debugowania) działało dla mnie.
źródło