Re: Determine nested return value from asm in debugger
Re: Determine nested return value from asm in debugger
- Subject: Re: Determine nested return value from asm in debugger
- From: Ken Thomases <email@hidden>
- Date: Thu, 30 Apr 2009 01:55:10 -0500
On Apr 30, 2009, at 1:06 AM, Trygve Inda wrote:
if ([lock lockWhenCondition:kConditionThreadMustExit beforeDate:[self
blockUntil]])
I need to be able to see the return value of blockUntil while I am
stepping
through the asm of the above "if" statement.
It looks like the last asm lines of the blockUntil method are:
0x0000a5bd <+0241> call 0x2d288 <dyld_stub_objc_msgSend>
0x0000a5c2 <+0246> mov êx,-0xc(ëp)
0x0000a5c5 <+0249> mov -0xc(ëp),êx
0x0000a5c8 <+0252> add $0x24,%esp
0x0000a5cb <+0255> pop ëx
0x0000a5cc <+0256> leave
0x0000a5cd <+0257> ret
It then comes back to finish the rest of the if statement
You don't show the call of objc_sendMsg which corresponds to the
invocation of [self blockUntil].
On x86, simple return values (non-floating-point and non-struct) are
always in êx. Just after the call to objc_msgSend is where the
value can be checked. I'm guessing that's the next line:
0x0000a400 <+0820> mov êx,íx
0x0000a402 <+0822> lea 0x21219(ëx),êx
0x0000a408 <+0828> mov (êx),êx
0x0000a40a <+0830> mov íx,0xc(%esp)
0x0000a40e <+0834> movl $0x2,0x8(%esp)
0x0000a416 <+0842> mov êx,0x4(%esp)
0x0000a41a <+0846> mov %esi,(%esp)
0x0000a41d <+0849> call 0x2d288 <dyld_stub_objc_msgSend>
You can also reverse engineer this message send, which would be [lock
lockWhenCondition:kConditionThreadMustExit beforeDate:<something>].
Going backward:
0x0000a41d <+0849> call 0x2d288 <dyld_stub_objc_msgSend>
0x0000a41a <+0846> mov %esi,(%esp) # %esp + 0 == the first
argument == the receiver == lock
0x0000a416 <+0842> mov êx,0x4(%esp) # %esp + 4 == the second
argument == the selector. It's in êx.
0x0000a40e <+0834> movl $0x2,0x8(%esp) # %esp + 8 == the first non-
hidden method argument, kConditionThreadMustExit
0x0000a40a <+0830> mov íx,0xc(%esp) # %esp + 12 == the second
non-hidden method argument, your date. Make a note: it's in íx
0x0000a408 <+0828> mov (êx),êx # Together, this and...
0x0000a402 <+0822> lea 0x21219(ëx),êx # ... this load the
selector @selector(lockWhenCondition:beforeDate:) into êx
0x0000a400 <+0820> mov êx,íx # The loading of íx, which we
now know gets passed as the date. This confirms my earlier guess.
Which register is the pointer to the NSDate in and how can I print its
description to the console?
If you break at 0x0000a400:
(gdb) b *0x0000a400
you can print the date object which is pointed to by êx like this:
(gdb) po $eax
Of course, you have other opportunities. At any point after
0x0000a400, you can 'po $edx' because the pointer has been copied to
that register. At the point of the call to objc_sendMsg, you can 'po
*(id*)($esp + 0xc)' to actually read it out of the stack.
If you set a breakpoint in -[NSConditionLock
lockWhenCondition:beforeDate:], you can 'po *(id*)($ebp + 20)'. $ebp
is the frame pointer. $ebp + 4 points to the return address. $ebp +8
points to the first argument which, for methods, is always the hidden
'self' parameter. $ebp + 12 points to the second argument which is
the hidden _cmd parameter. $ebp + 16 points to the first non-hidden
method argument, the condition in this case. And finally, $ebp + 20
points to the second non-hidden method argument, the date in this case.
Cheers,
Ken
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden