Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

objective c - Xcode/LLDB: How to get information about an exception that was just thrown?

OK, so imagine that my breakpoint in objc_exception_throw has just triggered. I'm sitting at the debugger prompt, and I want to get some more information about the exception object. Where do I find it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The exception object is passed in as the first argument to objc_exception_throw. LLDB provides $arg1..$argn variables to refer to arguments in the correct calling convention, making it simple to print the exception details:

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

Make sure to select the objc_exception_throw frame in the call stack before executing these commands. See the "Advanced Debugging and the Address Sanitizer" in the WWDC15 session videos to see this performed on stage.

Outdated Information

If you're on GDB, the syntax to refer to the first argument depends on the calling conventions of the architecture you're running on. If you're debugging on an actual iOS device, the pointer to the object is in register r0. To print it or send messages to it, use the following simple syntax:

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

On the iPhone Simulator, all function arguments are passed on the stack, so the syntax is considerably more horrible. The shortest expression I could construct that gets to it is *(id *)($ebp + 8). To make things less painful, I suggest using a convenience variable:

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

You can also set $exception automatically whenever the breakpoint is triggered by adding a command list to the objc_exception_throw breakpoint.

(Note that in all cases I tested, the exception object was also present in the eax and edx registers at the time the breakpoint hit. I'm not sure that'll always be the case, though.)

Added from comment below:

In lldb, select the stack frame for objc_exception_throw and then enter this command:

(lldb) po *(id *)($esp + 4)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...