[lldb-dev] lldb test failures on 32bit

Michael Sartain mikesart at gmail.com
Fri Aug 9 18:09:20 PDT 2013


For the Linux 64-bit hello_world, it looks like the below. Is this what you
would expect?

(lldb) disassemble -n main
hello_world`main at hello_world.cpp:5:
   0x400770:  pushq  %rbp
   0x400771:  movq   %rsp, %rbp
   0x400774:  subq   $0x20, %rsp
   0x400778:  leaq   0x40089c, %rax
   0x400780:  movl   %edi, -0x4(%rbp)
   0x400783:  movq   %rsi, -0x10(%rbp)
-> 0x400787:  movq   %rax, %rdi
   0x40078a:  movb   $0x0, %al
   0x40078c:  callq  0x400660                  ; symbol stub for: printf
   0x400791:  movl   $0x0, %ecx
   0x400796:  movl   %eax, -0x14(%rbp)
   0x400799:  movl   %ecx, %eax
   0x40079b:  addq   $0x20, %rsp
   0x40079f:  popq   %rbp
   0x4007a0:  ret

(lldb) disassemble -a 0x400660
hello_world`symbol stub for: printf:
   0x400660:  jmpq   *0x20099a(%rip)           ; _GLOBAL_OFFSET_TABLE_ + 24
   0x400666:  pushq  $0x0
   0x40066b:  jmpq   0x400650                  ; hello_world..plt + 0

For reference, gdb 7.6 looks like this:

(gdb) disassemble main
Dump of assembler code for function main(int, char**):
   0x0000000000400770 <+0>:     push   rbp
   0x0000000000400771 <+1>:     mov    rbp,rsp
   0x0000000000400774:  sub    rsp,0x20
   0x0000000000400778:  lea    rax,ds:0x40089c
   0x0000000000400780:  mov    DWORD PTR [rbp-0x4],edi
   0x0000000000400783:  mov    QWORD PTR [rbp-0x10],rsi
=> 0x0000000000400787:  mov    rdi,rax
   0x000000000040078a:  mov    al,0x0
   0x000000000040078c:  call   0x400660 <printf at plt>
   0x0000000000400791:  mov    ecx,0x0
   0x0000000000400796:  mov    DWORD PTR [rbp-0x14],eax
   0x0000000000400799:  mov    eax,ecx
   0x000000000040079b:  add    rsp,0x20
   0x000000000040079f:  pop    rbp
   0x00000000004007a0:  ret
End of assembler dump.

(gdb) disassemble 0x400660
Dump of assembler code for function printf at plt:
   0x0000000000400660 <+0>:     jmp    QWORD PTR [rip+0x20099a]        #
0x601000 <printf at got.plt>
   0x0000000000400666:  push   0x0
   0x000000000040066b:  jmp    0x400650
End of assembler dump.


On Fri, Aug 9, 2013 at 5:58 PM, Greg Clayton <gclayton at apple.com> wrote:

> In the ObjectFileMachO, we tend to make up symbols for all of the PLT
> stubs that we have and we give them a type of eSymbolTypeTrampoline. We do
> this by parsing the data in the mach-o binary and making synthetic symbols.
> We actually take all undefined symbols (which are useless to us in the
> debugger) and turn them into trampoline symbols to make the symbols useful.
> This sounds like a fix that needs to happen in ObjectFileELF.cpp.
>
> Greg
>
> On Aug 9, 2013, at 5:39 PM, Michael Sartain <mikesart at gmail.com> wrote:
>
> > 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)
> >
> >
> >
> >
> > _______________________________________________
> > lldb-dev mailing list
> > lldb-dev at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20130809/1d54a45d/attachment.html>


More information about the lldb-dev mailing list