[lldb-dev] lldb test failures on 32bit
Michael Sartain
mikesart at gmail.com
Fri Aug 9 17:39:40 PDT 2013
I'm starting to look at this now. I think there are some symbol issues on
32-bit as well. When running the code below in x64, the "disassemble -n
main" recognizes the symbol stub for printf for the call statement, and the
"disassemble -a addr" works as well.
I'll continue looking at this next week. Thanks Andy.
-Mike
mikesart at mikesart64:~/data/src/blah/build$ lldb -- hello_world
Current executable set to 'hello_world' (i386).
(lldb) b main
Breakpoint 1: where = hello_world`main + 24 at hello_world.cpp:6, address =
0x080485b8
(lldb) r
Process 5933 launched: '/home/mikesart/data/src/blah/build/hello_world'
(i386)
Process 5933 stopped
* thread #1: tid = 5933, 0x080485b8 hello_world`main(argc=1,
argv=0xffe770f4) + 24 at hello_world.cpp:6, name = 'hello_world', stop
reason = breakpoint 1.1
frame #0: 0x080485b8 hello_world`main(argc=1, argv=0xffe770f4) + 24 at
hello_world.cpp:6
3
4 int main( int argc, char *argv[] )
5 {
-> 6 printf("hello world.\n");
7 }
(lldb) disassemble -n main
hello_world`main at hello_world.cpp:5:
0x80485a0: pushl %ebp
0x80485a1: movl %esp, %ebp
0x80485a3: subl $0x18, %esp
0x80485a6: movl 0xc(%ebp), %eax
0x80485a9: movl 0x8(%ebp), %ecx
0x80485ac: leal 0x80486a0, %edx
0x80485b2: movl %ecx, -0x4(%ebp)
0x80485b5: movl %eax, -0x8(%ebp)
-> 0x80485b8: movl %edx, (%esp)
0x80485bb: calll 0x80484d0
0x80485c0: movl $0x0, %ecx
0x80485c5: movl %eax, -0xc(%ebp)
0x80485c8: movl %ecx, %eax
0x80485ca: addl $0x18, %esp
0x80485cd: popl %ebp
0x80485ce: ret
(lldb) disassemble -a 0x80484d0
error: Could not find function bounds for address 0x80484d0
(lldb) disassemble -s 0x80484d0
0x80484d0: jmpl *0x804a008
0x80484d6: pushl $0x10
0x80484db: jmp 0x80484a0 ; hello_world..plt + 0
hello_world`_start + 64:
0x80484e0: xorl %ebp, %ebp
On Tue, Jul 23, 2013 at 2:55 PM, Kaylor, Andrew <andrew.kaylor at intel.com>wrote:
> Hi Mike,****
>
> ** **
>
> I investigated this a little further and it seems that the problem is that
> when LLDB tries to unwind the stack from the point of the ‘jmp’ instruction
> in the printf stub it incorrectly calculates the call frame address. The
> log output indicates that it is using ESP+12 as the call frame address
> based on information from the FDE table. Consequently, it is looking for
> the return address at ESP+8, but that’s wrong. (I believe it’s actually at
> ESP-4.) It’s possible that this is still a matter of the register context
> getting some registers confused because of the 32-bit mapping but if so the
> point of failure is less obvious.****
>
> ** **
>
> It turns out that the variation of the code that I had that seemed to be
> working was actually working for the wrong reason. It was still looking
> for the frame 1 pc in the wrong location, but that location just happened
> to contain a non-zero value so the validity check passed over it.****
>
> ** **
>
> That’s as far as I’ve gotten in my investigation. I’m going to be on
> vacation for a week after tomorrow and I have some other things I need to
> get done before then, so if you want to pick this up from here feel free to
> do so. If not, I’ll try to get back to it in early August.****
>
> ** **
>
> -Andy****
>
> ** **
>
> ** **
>
> *From:* Michael Sartain [mailto:mikesart at gmail.com]
> *Sent:* Friday, July 19, 2013 4:24 PM
> *To:* Kaylor, Andrew
> *Cc:* lldb-dev at cs.uiuc.edu; Malea, Daniel; Kopec, Matt; Thirumurthi, Ashok
> *Subject:* Re: lldb test failures on 32bit****
>
> ** **
>
> I applied both patches, and the 'expr (int)printf("blah\n")' statement now
> works, but "n" over the printf() statement in the code still throws me
> somewhere else entirely. I'm on the call printf() asm instruction down
> below, I type "ni", and I wind up at address 0x80486f0.****
>
> ** **
>
> Is this working for you?****
>
> ** **
>
> And thanks for looking at this Andrew. Very cool we can call functions now
> in 32-bit targets...****
>
> -Mike****
>
> ** **
>
> (lldb) ni****
>
> Process 18815 stopped****
>
> * thread #1: tid = 0x497f, 0x08048855 blah`main(argc=1, argv=0xff985674) +
> 37 at blah.cpp:29, name = 'blah, stop reason = instruction step over****
>
> frame #0: 0x08048855 blah`main(argc=1, argv=0xff985674) + 37 at
> blah.cpp:29****
>
> 26 ****
>
> 27 int main( int argc, char *argv[] )****
>
> 28 {****
>
> -> 29 printf("hello world.\n");****
>
> 30 ****
>
> 31 Set *foo = new Set();****
>
> 32 ****
>
> (lldb) disassemble ****
>
> blah`main at blah.cpp:28:****
>
> 0x8048830: push EBP****
>
> 0x8048831: mov EBP, ESP****
>
> 0x8048833: push ESI****
>
> 0x8048834: sub ESP, 32820****
>
> 0x804883a: mov EAX, DWORD PTR [EBP + 12]****
>
> 0x804883d: mov ECX, DWORD PTR [EBP + 8]****
>
> 0x8048840: mov DWORD PTR [EBP - 8], 0****
>
> 0x8048847: mov DWORD PTR [EBP - 12], ECX****
>
> 0x804884a: mov DWORD PTR [EBP - 16], EAX****
>
> 0x804884d: mov EAX, ESP****
>
> 0x804884f: mov DWORD PTR [EAX], 134515168****
>
> -> 0x8048855: call 0x80486f0****
>
> 0x804885a: mov ECX, ESP****
>
> 0x804885c: mov DWORD PTR [ECX], 1****
>
> 0x8048862: mov DWORD PTR [EBP - 32804], EAX****
>
> 0x8048868: call 0x8048700****
>
> 0x804886d: mov ECX, EAX****
>
> 0x804886f: mov EDX, EAX****
>
> 0x8048871: mov ESI, ESP****
>
> 0x8048873: mov DWORD PTR [ESI], EAX****
>
> 0x8048875: mov DWORD PTR [EBP - 32808], EDX****
>
> 0x804887b: mov DWORD PTR [EBP - 32812], ECX****
>
> 0x8048881: call 0x8048800 ; Set at blah.cpp:23****
>
> 0x8048886: jmp 0x804888b ; main + 91 at blah.cpp:31
> ****
>
> 0x804888b: mov EAX, DWORD PTR [EBP - 32812]****
>
> 0x8048891: mov DWORD PTR [EBP - 20], EAX****
>
> 0x8048894: mov DWORD PTR [EBP - 32800], 0****
>
> 0x804889e: cmp DWORD PTR [EBP - 32800], 8192****
>
> 0x80488a8: jae 0x80488ef ; main + 191 at blah.cpp:38
> ****
>
> 0x80488ae: call 0x8048710****
>
> 0x80488b3: mov ECX, DWORD PTR [EBP - 32800]****
>
> 0x80488b9: mov DWORD PTR [EBP + 4*ECX - 32796], EAX****
>
> 0x80488c0: mov EAX, DWORD PTR [EBP - 32800]****
>
> 0x80488c6: add EAX, 1****
>
> 0x80488cb: mov DWORD PTR [EBP - 32800], EAX****
>
> 0x80488d1: jmp 0x804889e ; main + 110 at blah.cpp:34
> ****
>
> 0x80488d6: mov DWORD PTR [EBP - 24], EAX****
>
> 0x80488d9: mov DWORD PTR [EBP - 28], EDX****
>
> 0x80488dc: mov EAX, DWORD PTR [EBP - 32808]****
>
> 0x80488e2: mov DWORD PTR [ESP], EAX****
>
> 0x80488e5: call 0x80486d0 ; symbol stub for:
> _Unwind_Resume****
>
> 0x80488ea: jmp 0x80488fb ; main + 203 at blah.cpp:31
> ****
>
> 0x80488ef: mov EAX, DWORD PTR [EBP - 8]****
>
> 0x80488f2: add ESP, 32820****
>
> 0x80488f8: pop ESI****
>
> 0x80488f9: pop EBP****
>
> 0x80488fa: ret ****
>
> 0x80488fb: mov EAX, DWORD PTR [EBP - 24]****
>
> 0x80488fe: mov DWORD PTR [ESP], EAX****
>
> 0x8048901: call 0x8048730****
>
> (lldb) ni****
>
> Process 18815 stopped****
>
> * thread #1: tid = 0x497f, 0x080486f0 blah, name = 'blah, stop reason =
> instruction step over****
>
> frame #0: 0x080486f0 blah****
>
> -> 0x80486f0: jmp DWORD PTR [134520844]****
>
> 0x80486f6: push 24****
>
> 0x80486fb: jmp 0x80486b0 ; blah..plt + 0****
>
> 0x8048700: jmp DWORD PTR [134520848]****
>
> ** **
>
> On Fri, Jul 19, 2013 at 3:34 PM, Kaylor, Andrew <andrew.kaylor at intel.com>
> wrote:****
>
> Hi Mike,****
>
> ****
>
> I think I’ve tracked down the sources of both of these problems.****
>
> ****
>
> The problem with not being able to call functions in the target seems to
> be a failure in the MCJIT relocation mechanism. Because LLDB is generating
> IR with absolute addresses for function calls, the JITed code contains
> relocations with absolute values rather than symbols. This is a problem I
> fixed a short time ago, but it seems to have come undone again (at least in
> this particular case). The attached ‘reloc-fix-32.patch’ (to be applied to
> the LLVM repository) should fix that.****
>
> ****
>
> I need to do a bit of investigation to settle some questions about why
> this condition came back or was specific to the 32-bit case before I commit
> this, but I think this is correct.****
>
> ****
>
> The problem where you lose source after stepping seems to be a matter of
> incorrect stack unwinding. There were two problems lurking here.****
>
> ****
>
> First, the RegisterContext::ConvertBetweenRegisterKinds() function wasn’t
> making any provision for a 32-bit inferior running on a 64-bit target. The
> way the x86-64 register context class is implemented it defines 64-bit
> registers and 32-bit registers in the same RegisterInfo structure, and
> there is some overlap in how these get mapped to DWARF/GDB/GCC register
> numbers. RegisterContext::ConvertBetweenRegisterKinds() was just iterating
> through the list and returning the first match it found, which was the
> 64-bit register.****
>
> ****
>
> I added a special case to call
> RegisterContext::ConvertRegisterKindToRegisterNumber() when the target kind
> is eRegisterKindLLDB. This invokes the RegisterContext_x86_64 overload of
> that method which knows how to distinguish the 32-bit and 64-bit
> registers. I’m not convinced that this is the best way to solve this
> problem, but it works.****
>
> ****
>
> The second issue was that the ABIMacOSX_i386 plug-in (which also gets used
> for 32-bit inferiors on Linux) was rejecting call frame addresses that
> weren’t 8-byte aligned whereas, at least on Linux, 4-byte alignment is
> allowed. If 32-bit processes on MacOSX require 8-byte alignment then we’ll
> need to do some additional checking, but for now I just modified it to only
> check for 4-byte alignment.****
>
> ****
>
> Both of the stack unwinding issues should be fixed by the attached
> ‘stack-fix-32.patch’ file.****
>
> ****
>
> Can you try out these patches and verify that they work for you?****
>
> ****
>
> Thanks,****
>
> Andy****
>
> ****
>
> *From:* Michael Sartain [mailto:mikesart at gmail.com] ****
>
> *Sent:* Tuesday, July 16, 2013 6:14 PM
> *To:* Malea, Daniel; Kaylor, Andrew; Kopec, Matt; Thirumurthi, Ashok
> *Cc:* Matthew Sorrels****
>
> *Subject:* Fwd: lldb test failures on 32bit****
>
> ****
>
> I think the below are the largest 32-bit blocking issues right now.****
>
> ****
>
> Is this something any of you have any familiarity with and have time to
> look at?****
>
> ****
>
> If not, let me know and I'll start investigating...****
>
> ****
>
> Thanks much!****
>
> -Mike****
>
> ****
>
> #################################****
>
> ## Can't call functions in target****
>
> #################################****
>
> mikesart at mikesart-rad:~/data/src/blah2/build$ lldb -x -- blah****
>
> Current executable set to 'blah' (i386).****
>
> (lldb) b main****
>
> Breakpoint 1: where = blah`main + 29 at blah.cpp:29, address = 0x0804884d*
> ***
>
> (lldb) r****
>
> Process 6745 launched: '/home/mikesart/data/src/blah2/build/blah' (i386)**
> **
>
> Process 6745 stopped****
>
> * thread #1: tid = 0x1a59, 0x0804884d blah`main(argc=1, argv=0xfffc8c54) +
> 29 at blah.cpp:29, name = 'blah, stop reason = breakpoint 1.1****
>
> frame #0: 0x0804884d blah`main(argc=1, argv=0xfffc8c54) + 29 at
> blah.cpp:29****
>
> 26 ****
>
> 27 int main( int argc, char *argv[] )****
>
> 28 {****
>
> -> 29 printf("hello world.\n");****
>
> 30 ****
>
> 31 Set *foo = new Set();****
>
> 32 ****
>
> (lldb) expr (int)printf("hi there!\n");****
>
> error: Execution was interrupted, reason: invalid address (fault address:
> 0xeef60020).****
>
> The process has been returned to the state before expression evaluation.**
> **
>
> (lldb) n****
>
> Process 6745 exited with status = -1 (0xffffffff) ****
>
> ****
>
> #################################****
>
> ## Lose source with first next command****
>
> #################################****
>
> mikesart at mikesart-rad:~/data/src/blah2/build$ lldb -x -- blah****
>
> Current executable set to 'blah' (i386).****
>
> (lldb) b main****
>
> Breakpoint 1: where = blah`main + 29 at blah.cpp:29, address = 0x0804884d*
> ***
>
> (lldb) r****
>
> Process 7471 launched: '/home/mikesart/data/src/blah2/build/blah' (i386)**
> **
>
> Process 7471 stopped****
>
> * thread #1: tid = 0x1d2f, 0x0804884d blah`main(argc=1, argv=0xffb36464) +
> 29 at blah.cpp:29, name = 'blah, stop reason = breakpoint 1.1****
>
> frame #0: 0x0804884d blah`main(argc=1, argv=0xffb36464) + 29 at
> blah.cpp:29****
>
> 26 ****
>
> 27 int main( int argc, char *argv[] )****
>
> 28 {****
>
> -> 29 printf("hello world.\n");****
>
> 30 ****
>
> 31 Set *foo = new Set();****
>
> 32 ****
>
> (lldb) n****
>
> Process 7471 stopped****
>
> * thread #1: tid = 0x1d2f, 0x080486f0 blah, name = 'blah, stop reason =
> step over****
>
> frame #0: 0x080486f0 blah****
>
> -> 0x80486f0: jmpl *134520844****
>
> 0x80486f6: pushl $24****
>
> 0x80486fb: jmp 0x80486b0 ; blah..plt + 0****
>
> 0x8048700: jmpl *134520848****
>
> (lldb) ****
>
> ** **
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20130809/59a1cd94/attachment.html>
More information about the lldb-dev
mailing list