[Lldb-commits] [PATCH] Register Number in DWARFCallFrameInfo.cpp

Jason Molenda jmolenda at apple.com
Tue Aug 12 16:13:28 PDT 2014


I had to add a call to puts() to get clang to emit eh_frame:

% clang -g -save-temps -fexceptions -Wl,-keep_dwarf_unwind -arch i386 a.c
% dwarfdump --verbose --eh-frame a.out
----------------------------------------------------------------------
 File: a.out {mach32-i386-MH_EXECUTE} (i386)
----------------------------------------------------------------------
Exception handling frame information for section __eh_frame

0x00000000: CIE
        length: 0x00000014
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: "zR"
    code_align: 1
    data_align: -4
   ra_register: 0x08
 aug_arg["zR"]: DW_GNU_EH_PE_pcrel + DW_GNU_EH_PE_absptr
                DW_CFA_def_cfa (5 (esp), 4)
                DW_CFA_offset (8 (eip), -4)
                DW_CFA_nop
                DW_CFA_nop
  Instructions: Init State: CFA=esp+4     eip=[CFA-4]


0x00000018: FDE
        length: 0x00000018
   CIE_pointer: 0x00000000
    start_addr: 0x00001ef0 _f
    range_size: 0x00000029 (end_addr = 0x00001f19)
  Instructions: 0x00001ef0: CFA=esp+4     eip=[CFA-4]
                DW_CFA_advance_loc (1)
                DW_CFA_def_cfa_offset (8)
                DW_CFA_offset (4 (ebp), -8)
                0x00001ef1: CFA=esp+8     ebp=[CFA-8]  eip=[CFA-4]
                DW_CFA_advance_loc (2)
                DW_CFA_def_cfa_register (4 (ebp))
                DW_CFA_nop
                DW_CFA_nop
                DW_CFA_nop
                0x00001ef3: CFA=ebp+8     ebp=[CFA-8]  eip=[CFA-4]


0x00000034: FDE
        length: 0x00000018
   CIE_pointer: 0x00000000
    start_addr: 0x00001f20 _main
    range_size: 0x00000021 (end_addr = 0x00001f41)
  Instructions: 0x00001f20: CFA=esp+4     eip=[CFA-4]
                DW_CFA_advance_loc (1)
                DW_CFA_def_cfa_offset (8)
                DW_CFA_offset (4 (ebp), -8)
                0x00001f21: CFA=esp+8     ebp=[CFA-8]  eip=[CFA-4]
                DW_CFA_advance_loc (2)
                DW_CFA_def_cfa_register (4 (ebp))
                DW_CFA_nop
                DW_CFA_nop
                DW_CFA_nop
                0x00001f23: CFA=ebp+8     ebp=[CFA-8]  eip=[CFA-4]

% lldb a.out
(lldb) target create "a.out"
Current executable set to 'a.out' (i386).
(lldb) log enable lldb unwind
(lldb) br s -n f
Breakpoint 1: where = a.out`f + 18 at a.c:2, address = 0x00001f02
(lldb) r
<lldb.process.internal-state(pid=5746)> th1/fr0 using architectural default unwind method
<lldb.process.internal-state(pid=5746)> th1/fr0 0x00007fff5fc01000: CFA=rdi +8 => rsi=rdi+8 rdi=[rdi] r8=[rdi+4] 

<lldb.process.internal-state(pid=5746)> th1/fr0 cfa_regval = 0x0000000000000008 (cfa_regval = 0x0000000000000000, cfa_offset = 8)
<lldb.process.internal-state(pid=5746)> th1/fr0 initialized frame current pc is 0x7fff5fc01000 cfa is 0x8 using i386 default unwind plan UnwindPlan
<lldb.process.internal-state(pid=5746)> th1/fr0 using architectural default unwind method
<lldb.process.internal-state(pid=5746)> th1/fr0 0x00007fff5fc01000: CFA=rdi +8 => rsi=rdi+8 rdi=[rdi] r8=[rdi+4] 

<lldb.process.internal-state(pid=5746)> th1/fr0 cfa_regval = 0x0000000000000008 (cfa_regval = 0x0000000000000000, cfa_offset = 8)
<lldb.process.internal-state(pid=5746)> th1/fr0 initialized frame current pc is 0x7fff5fc01000 cfa is 0x8 using i386 default unwind plan UnwindPlan
<lldb.process.internal-state(pid=5746)> th1/fr0 0x000000008fe01000: CFA=esp +4 => esp=esp+4 eip=[esp] 

<lldb.process.internal-state(pid=5746)> th1/fr0 cfa_regval = 0x00000000bffffa88 (cfa_regval = 0x00000000bffffa84, cfa_offset = 4)
<lldb.process.internal-state(pid=5746)> th1/fr0 initialized frame current pc is 0x8fe01000 cfa is 0xbffffa88 using assembly insn profiling UnwindPlan
Process 5746 launched: '/private/tmp/a.out' (i386)
<lldb.process.internal-state(pid=5746)> th1/fr0 0x000000008fe0dda0: CFA=esp +4 => esp=esp+4 eip=[esp] 

<lldb.process.internal-state(pid=5746)> th1/fr0 cfa_regval = 0x00000000bfffedf0 (cfa_regval = 0x00000000bfffedec, cfa_offset = 4)
<lldb.process.internal-state(pid=5746)> th1/fr0 initialized frame current pc is 0x8fe0dda0 cfa is 0xbfffedf0 using assembly insn profiling UnwindPlan
<lldb.process.internal-state(pid=5746)> th1/fr0 using architectural default unwind method
<lldb.process.internal-state(pid=5746)> th1/fr0 0x000000008fe0dda1: CFA=ebp +8 => esp=ebp+8 ebp=[ebp] eip=[ebp+4] 

<lldb.process.internal-state(pid=5746)> th1/fr0 cfa_regval = 0x00000000bfffee10 (cfa_regval = 0x00000000bfffee08, cfa_offset = 8)
<lldb.process.internal-state(pid=5746)> th1/fr0 initialized frame current pc is 0x8fe0dda1 cfa is 0xbfffee10 using i386 default unwind plan UnwindPlan
<lldb.process.internal-state(pid=5746)> th1/fr0 0x0000000000001ef3: CFA=ebp +8 => ebp=[ebp] esp=ebp+8 eip=[ebp+4] 

<lldb.process.internal-state(pid=5746)> th1/fr0 cfa_regval = 0x00000000bffffa50 (cfa_regval = 0x00000000bffffa48, cfa_offset = 8)
<lldb.process.internal-state(pid=5746)> th1/fr0 initialized frame current pc is 0x1f02 cfa is 0xbffffa50 using assembly insn profiling UnwindPlan
Process 5746 stopped
* thread #1: tid = 0x10193, 0x00001f02 a.out`f + 18 at a.c:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    #0: 0x00001f02 a.out`f + 18 at a.c:2
   1   	#include <stdio.h>
-> 2   	int f() { puts ("H"); return 5; }
   3   	int main() {
   4   	  f();
   5   	  return 0;
   6   	}
(lldb) image show-unwind -n f
<lldb.driver.main-thread> (i386) /private/tmp/a.out: Reading EH frame info
First non-prologue instruction is at address 0x1ef6 or offset 6 into the function.

Asynchronous (not restricted to call-sites) UnwindPlan for a.out`f (start addr 0x1ef0):
This UnwindPlan originally sourced from assembly insn profiling
Address range of this UnwindPlan: [a.out.__TEXT.__text + 0-0x00000029)
row[0]: 0x00000000: CFA=esp +4 => esp=esp+4 eip=[esp] 
row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] esp=esp+8 eip=[esp+4] 
row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] esp=ebp+8 eip=[ebp+4] 
row[3]: 0x00000028: CFA=esp +4 => esp=esp+4 eip=[esp] 

Synchronous (restricted to call-sites) UnwindPlan for a.out`f (start addr 0x1ef0):
This UnwindPlan originally sourced from eh_frame CFI
Address range of this UnwindPlan: [a.out.__TEXT.__text + 0-0x00000029)
row[0]: 0x00000000: CFA=esp +4 => eip=[esp] 
row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] eip=[esp+4] 
row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] eip=[ebp+4] 

Architecture default UnwindPlan for a.out`f (start addr 0x1ef0):
This UnwindPlan originally sourced from i386 default unwind plan
row[0]: 0x00000000: CFA=ebp +8 => esp=ebp+8 ebp=[ebp] eip=[ebp+4] 

Fast UnwindPlan for a.out`f (start addr 0x1ef0):
This UnwindPlan originally sourced from fast unwind assembly profiling
Address range of this UnwindPlan: [a.out.__TEXT.__text + 0-0x00000029)
row[0]: 0x00000000: CFA=esp +4 => esp=esp+4 eip=[esp] 
row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] esp=esp+8 eip=[esp+4] 
row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] esp=ebp+8 eip=[ebp+4] 


(lldb) image show-unwind -n main
First non-prologue instruction is at address 0x1f26 or offset 6 into the function.

Asynchronous (not restricted to call-sites) UnwindPlan for a.out`main (start addr 0x1f20):
This UnwindPlan originally sourced from assembly insn profiling
Address range of this UnwindPlan: [a.out.__TEXT.__text + 48-0x00000051)
row[0]: 0x00000000: CFA=esp +4 => esp=esp+4 eip=[esp] 
row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] esp=esp+8 eip=[esp+4] 
row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] esp=ebp+8 eip=[ebp+4] 
row[3]: 0x00000020: CFA=esp +4 => esp=esp+4 eip=[esp] 

Synchronous (restricted to call-sites) UnwindPlan for a.out`main (start addr 0x1f20):
This UnwindPlan originally sourced from eh_frame CFI
Address range of this UnwindPlan: [a.out.__TEXT.__text + 48-0x00000051)
row[0]: 0x00000000: CFA=esp +4 => eip=[esp] 
row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] eip=[esp+4] 
row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] eip=[ebp+4] 

Architecture default UnwindPlan for a.out`main (start addr 0x1f20):
This UnwindPlan originally sourced from i386 default unwind plan
row[0]: 0x00000000: CFA=ebp +8 => esp=ebp+8 ebp=[ebp] eip=[ebp+4] 

Fast UnwindPlan for a.out`main (start addr 0x1f20):
This UnwindPlan originally sourced from fast unwind assembly profiling
Address range of this UnwindPlan: [a.out.__TEXT.__text + 48-0x00000051)
row[0]: 0x00000000: CFA=esp +4 => esp=esp+4 eip=[esp] 
row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] esp=esp+8 eip=[esp+4] 
row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] esp=ebp+8 eip=[ebp+4] 


(lldb) 


> On Aug 12, 2014, at 4:10 PM, Tong Shen <endlessroad at google.com> wrote:
> 
> Source code:
> int f() { return 5; }
> int main() {
>   f();
>   return 0;
> }
> 
> Can you execute the following commands on lldb:
> 
> log enable lldb unwind
> b f
> r
> bt
> 
> and see what it outputs?
> 
> 
> On Tue, Aug 12, 2014 at 3:51 PM, Jason Molenda <jmolenda at apple.com> wrote:
> Hm, on my Mac I'm getting the correct registers from the eh_frame.
> 
> * thread #1: tid = 0xce36, 0x00001f30 a.out`main, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
>     #0: 0x00001f30 a.out`main
> a.out`main:
> -> 0x1f30:  pushl  %ebp
>    0x1f31:  movl   %esp, %ebp
>    0x1f33:  subl   $0x8, %esp
>    0x1f36:  calll  0x1f3b                    ; main + 11
> (lldb) image show-unwind -n main
> <lldb.driver.main-thread> (i386) /private/tmp/a.out: Reading EH frame info
> First non-prologue instruction is at address 0x1f36 or offset 6 into the function.
> 
> Asynchronous (not restricted to call-sites) UnwindPlan for a.out`main (start addr 0x1f30):
> This UnwindPlan originally sourced from assembly insn profiling
> Address range of this UnwindPlan: [a.out.__TEXT.__text + 0-0x00000029)
> row[0]: 0x00000000: CFA=esp +4 => esp=esp+4 eip=[esp]
> row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] esp=esp+8 eip=[esp+4]
> row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] esp=ebp+8 eip=[ebp+4]
> row[3]: 0x00000028: CFA=esp +4 => esp=esp+4 eip=[esp]
> 
> Synchronous (restricted to call-sites) UnwindPlan for a.out`main (start addr 0x1f30):
> This UnwindPlan originally sourced from eh_frame CFI
> Address range of this UnwindPlan: [a.out.__TEXT.__text + 0-0x00000029)
> row[0]: 0x00000000: CFA=esp +4 => eip=[esp]
> row[1]: 0x00000001: CFA=esp +8 => ebp=[esp] eip=[esp+4]
> row[2]: 0x00000003: CFA=ebp +8 => ebp=[ebp] eip=[ebp+4]
> 
> 
> The UnwindAssembly_x86 generated UnwindPlan and the clang-generated eh_frame cfi match up...
> 
> 
> 
> > On Aug 12, 2014, at 3:38 PM, Tong Shen <endlessroad at google.com> wrote:
> >
> > In i386 .eh_frame, esp=4, ebp=5. I confirmed it by cfi directives gcc generates and objdump -W.
> >
> > So it's either we chose the wrong eRegisterKindXXX, or we put {dwarf, gcc}_{esp, ebp}_i386 in wrong order in source/Plugins/Process/Utility/RegisterContext_x86.h :-)
> >
> >
> > On Tue, Aug 12, 2014 at 3:23 PM, Jason Molenda <jmolenda at apple.com> wrote:
> > Hi Tong, sorry for not replying earlier.
> >
> > I don't understand why the current code is wrong.
> >
> >         eRegisterKindGCC = 0,    // the register numbers seen in eh_frame
> >         eRegisterKindDWARF,      // the register numbers seen DWARF
> >
> > and
> >
> >         SectionSP sect = sl->FindSectionByType (eSectionTypeEHFrame, true);
> >         if (sect.get())
> >         {
> >             m_eh_frame = new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindGCC, true);
> >         }
> >
> > We create a DWARFCallFrameInfo object to read the eh_frame information and we tell it that the register kind to use for the reg numbers is eRegisterKindGCC - aka the eh_frame register numbering domain.
> >
> > This all looks correct to me, and designed specifically to handle the case of that ancient gcc register numbering bug in the eh_frame section for i386.
> >
> > We never read the actual DWARF debug_frame (today) because I've never seen a case where it had more information than the eh_frame unwind info.
> >
> >
> >
> > > On Aug 12, 2014, at 1:36 PM, Tong Shen <endlessroad at google.com> wrote:
> > >
> > > Aha, got it.
> > > Patch confirmed and attached.
> > >
> > >
> > > On Tue, Aug 12, 2014 at 12:51 PM, Ed Maste <emaste at freebsd.org> wrote:
> > > On 12 August 2014 15:43, Todd Fiala <tfiala at google.com> wrote:
> > > >
> > > > Hey Tong,
> > > >
> > > > Ah interesting.  The register infos in lldb have a vector of different register numbers (I think we call them "register kinds") based on the type of encoding you're using.  Let's have a look at that to see if we can adjust the code to query for the right register kind.  We'll look at this today!
> > >
> > > There was a thread on this topic on this list a while back, and I
> > > think the two register sets in question here are DWARF and GCC, which
> > > are identical in all cases except that i386 swaps esp and ebp between
> > > the two.  This is all the legacy of an ancient GCC bug.  So I think
> > > you're right Todd, just picking the other set should solve this.
> > >
> > >
> > >
> > > --
> > > Best Regards, Tong Shen
> > > <fix_register_kind.patch>_______________________________________________
> > > lldb-commits mailing list
> > > lldb-commits at cs.uiuc.edu
> > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
> >
> >
> >
> >
> > --
> > Best Regards, Tong Shen
> 
> 
> 
> 
> -- 
> Best Regards, Tong Shen




More information about the lldb-commits mailing list