[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 

frame.regs[0].GetChildMemberWithName("arg1")

Jim
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