Xcode/LLDB: jak uzyskać informacje o wyjątku, który właśnie został wyrzucony?

Ok, więc wyobraź sobie, że mój breakpoint w objc_exception_throw właśnie się uruchomił. Siedzę przy monicie debuggera i chcę uzyskać więcej informacji o obiekcie exception. Gdzie go znajdę?

Author: Karoy Lorentey, 2010-07-25

4 answers

Obiekt exception jest przekazywany jako pierwszy argument do objc_exception_throw. LLDB dostarcza $arg1..$argn zmienne odwołujące się do argumentów w poprawnej konwencji wywołania, co ułatwia wypisanie szczegółów wyjątku:

(lldb) po $arg1
(lldb) po [$arg1 name]
(lldb) po [$arg1 reason]

Upewnij się, że wybrałeś ramkę objc_exception_throw w stosie wywołań przed wykonaniem tych poleceń. Zobacz "zaawansowane debugowanie i dezynfekcja adresu" w filmach sesji WWDC15, aby zobaczyć to na scenie.

Nieaktualne Informacje

Jeśli korzystasz z GDB, składnia odnosząca się do pierwszego argumentu zależy od konwencji wywołania architektury, na której działasz. Jeśli debugujesz na rzeczywistym urządzeniu z systemem iOS, wskaźnik do obiektu znajduje się w rejestrze r0. Aby go wydrukować lub wysłać do niego wiadomości, użyj następującej prostej składni:

(gdb) po $r0
(gdb) po [$r0 name]
(gdb) po [$r0 reason]

W symulatorze iPhone ' a wszystkie argumenty funkcji są przekazywane na stos, więc składnia jest znacznie straszniejsza. Najkrótsze wyrażenie, jakie mogłem konstrukt, który do niego dociera to *(id *)($ebp + 8). Aby uczynić rzeczy mniej bolesnymi, proponuję użyć zmiennej wygody:

(gdb) set $exception = *(id *)($ebp + 8)
(gdb) po $exception
(gdb) po [$exception name]
(gdb) po [$exception reason]

Można również ustawić $exception automatycznie po uruchomieniu punktu przerwania przez dodanie listy poleceń do punktu przerwania objc_exception_throw.

(zauważ, że we wszystkich testowanych przeze mnie przypadkach obiekt exception był również obecny w rejestrach eax i edx w momencie trafienia punktu przerwania. Nie jestem pewien, czy zawsze tak będzie.)

Dodany z komentarza poniżej:

W lldb wybierz ramkę stosu dla objc_exception_throw, a następnie wprowadź polecenie:

(lldb) po *(id *)($esp + 4)
 149
Author: Karoy Lorentey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 16:18:10

Na nowych symulatorach (iOS 8, 64bit) xcode 6 im za pomocą w ramce wyjątku: objc_exception_throw

po $rax

W 32bit:

po $eax

Co to jest rax?

Rax jest 64-bitowym rejestrem, który zastępuje stary eax

Jak znaleźć wszystkie rejestry?

register read

Źródło wikipedia

 10
Author: João Nunes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-23 07:35:58

W momencie pisania tego postu, ten post jest moim najlepszym hitem w Google: LLDB Print exception . Dlatego dodaję tę odpowiedź do konta lldb i x86_64.

Moje próby znalezienia wyjątku za pomocą po $eax nie powiodły się z error: Couldn't materialize struct: Couldn't read eax (materialize). Inne próby opisane w linkowanych dokumentach z wcześniejszych odpowiedzi również nie powiodły się.

Kluczem było to, że najpierw musiałem kliknąć na ramkę objc_exception_throw w moim głównym wątku. lldb nie zaczyna się w tej ramce.

We wszystkich moich poszukiwaniach i podążaniu przykłady, ten wpis na blogu był pierwszym, który wyjaśnił rzeczy w sposób, który działał dla mnie. Jest bardziej nowoczesny, jest opublikowany w sierpniu 2012.

 4
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-10 19:37:20

Jeśli masz polecenie catch, umieść tam punkt przerwania i możesz sprawdzić obiekt wyjątku w tym punkcie.

Jeśli nie masz deklaracji catch, Kontynuuj.

Otrzymasz wiadomość w terminalu w następujący sposób:

Zamykanie aplikacji z powodu nieautoryzowanego wyjątku 'NSInvalidArgumentException', powód: '* -[__NSPlaceholderDictionary initWithObjects: forKeys: count:]: próba Wstawienia nil obiektu z obiektów [0] '

Jednak , prawdopodobnie jesteś szukam sposobu na sprawdzenie go bez kontynuowania, ponieważ stracisz ładny ślad stosu po zakończeniu aplikacji.

Do tego brzmi jak odpowiedź Fnord jest najlepsza, ale nie byłem w stanie uruchomić go w LLDB.

 0
Author: funroll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-15 11:20:47