[lldb-dev] sniffing the exception in objc_exception_throw

jingham at apple.com jingham at apple.com
Wed Jun 19 10:22:34 PDT 2013

That's cool.  Note that for x86_64 and arm (and any other architecture that passes arguments in registers) lldb provides a register alias "arg1" for whatever register is used for passing the first argument.  So you have to treat i386 separately, but for other architectures you can just use 


On Jun 16, 2013, at 11:03 PM, Rob Mayoff <mayoff at dqd.com> wrote:

> When I don't put a breakpoint on objc_exception_throw, I get the
> exception description in my console, along with addresses of the
> return pointers in the call stack.  These addresses aren't
> particularly useful for debugging (for me, anyway).
> When I put a breakpoint on objc_exception_throw to debug Objective-C
> exceptions, I can inspect the call stack properly, but I don't get the
> exception description in the console.
> Setting a breakpoint command is no good because I need different
> commands for each of the arm, i386, and x86_64 architectures.  I want
> to set up the breakpoint once as an Xcode user breakpoint.
> Enrico Granata and Sean Callanan helped me implement a new command in
> Python that works across all three architectures (thanks again!), and
> asked that I send it to this mailing list.
> # ~/.lldbinit
> command script import ~/Library/lldb/sniff_objc_exception_throw.py
> # ~/Library/lldb/sniff_objc_exception_throw.py
> import lldb
> def GetFirstArgumentAsValue(target, frame):
>    # Note: I assume the PC is at the first instruction of the
> function, before the stack and registers have been modified.
>    if target.triple.startswith('x86_64'):
>        return frame.regs[0].GetChildMemberWithName("rdi")
>    elif target.triple.startswith('i386'):
>        espValue = frame.regs[0].GetChildMemberWithName("esp")
>        address = espValue.GetValueAsUnsigned() + target.addr_size
>        return espValue.CreateValueFromAddress('arg0', address,
> target.FindFirstType('id'))
>    else:
>        return frame.regs[0].GetChildMemberWithName("r0")
> def command(debugger, user_input, result, unused):
>    target = debugger.GetSelectedTarget()
>    frame = target.GetProcess().GetSelectedThread().GetFrameAtIndex(0)
>    description = GetFirstArgumentAsValue(target, frame).GetObjectDescription()
>    if description is None:
>        output = "I couldn't get the description of the exception being thrown."
>    else:
>        output = "Description of exception being thrown: " + repr(description)
>    result.PutCString(output)
>    return None
> def __lldb_init_module(debugger, unused):
>    debugger.HandleCommand('command script add --function
> sniff_objc_exception_throw.command sniff_objc_exception_throw')
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

More information about the lldb-dev mailing list