How is variable info retrieved in debugging for executables generated by llvm backend?

Hi, all

I ported llvm backend and lldb recently. Both tools can basically work.
lldb is able to debug programs in asm style and frame unwinding is OK.

But “frame variable XX” does not work because lldb is not able to determine the address of
XX from debug info.

Can someone give any clue?

Thanks in advance.

All of this information is contained in the DWARF debug info that you must generate. Are you generating DWARF? If not, you will need to. If so, please attach an example program that contains DWARF and specify which function you are having trouble getting variable information for.

Greg Clayton

Thank you.

Here is an example and the attchment contains extra files including object file and executable file.
I want to print for example the value of “a”, but lldb command “frame variable a” displays “0” and so does “b”, and “c”.
Meanwhile, the value is correct if I directly check registers or memory.

Following content is composed of three part:

  1. C program.
  2. assembly file including directives of dwarf debug info.
  3. dwarf debug info dumpped from executable file with llvm-dwarfdump.

///////////////////////////////////////////////////////////////////////////////////////////
// C

int
main(int argc, char *argv)
{
int a = 11;
int b = 22;
int c = a+b;
return c;
}

Sorry, this is the attachment.

example.tar.bz2 (4.67 KB)

If I had to guess, I would venture to say your problem is one of:
1 - you don't have your registers correctly defined and didn't specify the DWARF register numbers for your register context
2 - your DWARF is incorrect

I am guessing #1 is your issue.

How are you debugging your program? Are you using the GDB remote protocol? If so, how did you tell LLDB about all of your CPU registers? Did you use the LLDB specific GDB remote extensions? Did you specify a target definition python file? You will need to make sure that you tell LLDB about all of your CPU registers and also tell LLDB the DWARF register number for each register accurately.

Variable "a" has debug info:

0x00000054: DW_TAG_variable [4]
                     DW_AT_name( "a" )
                     DW_AT_decl_file( "/home/yangyy/workspace/newlib/test.c" )
                     DW_AT_decl_line( 4 )
                     DW_AT_type( {0x0000007f} ( int ) )
                     DW_AT_location( fbreg +16 )

The location says it is at the frame base register + 16 bytes. The frame base is defined in the parent DIE:

0x00000022: DW_TAG_subprogram [2] *
                 DW_AT_name( "main" )
                 DW_AT_decl_file( "/home/yangyy/workspace/newlib/test.c" )
                 DW_AT_decl_line( 2 )
                 DW_AT_prototyped( true )
                 DW_AT_type( {0x0000007f} ( int ) )
                 DW_AT_external( true )
                 DW_AT_low_pc( 0x00000028 )
                 DW_AT_high_pc( 0x00000084 )
                 DW_AT_frame_base( regx 0x0000003c )

So it says the frame base register is DWARF register 0x3c. In your target definition you will need to have told us which register has the DWARF register number 0x3c, otherwise we will fail to evaluate the expression.

Greg

0x00000097: NULL

.debug_frame contents:

Section .debug_frame is empty. Is it expected?

Thank you, Clayton. This is very helpful.

We use the LLDB specific GDB remote extensions, and our debugger server supports “qRegisterInfo” package. “reg 0x3c” is the frame pointer.

In the example mentioned above, we have SP = FP - 40 for current call frame.
And variable “a” is stored at address (FP + -24) from asm instruction [FP + -24] = R3;;
Thus we can conclude that SP + 16 = FP - 40 + 16 = FP -24 is the desired address. Here “16” is the offset obtained from debug info.

So I guess there is something incompatible between our compiler backend and debug info generator.
Here is my questions:

  1. How can we specify which register should be DW_AT_frame_base?
  2. How can we adjust the offset in DW_AT_location for variables?

Best regards.

You don't need to, there is a DWARF location expression in the DW_AT_frame_base attribute attached to the function:

        DW_AT_frame_base( regx 0x0000003c )

This means:

  DW_OP_regx(0x0000003c)

Or that the frame base is in register 0x3c. Now qRegisterInfo packets you send back to LLDB must include "DWARF" register numbers. Sometimes the register numbers the compiler uses for EH frame (from the .eh_frame section) differ from the register numbers used in DWARF (any register numbers in .debug_frame, .debug_info, .debug_loc, and more). So you need to explicitly specify these numbers:

At the end of this email is a complete version of the qRegisterInfo packets and responses for x86_64. Be sure to check the gcc:<regnum> (compiler register numbering for EH frame), dwarf:<regnum> (for DWARF mappings, but no all registers get DWARF register numbers because some will never contain variable values), and also look for the "generic" key value pairs like "generic:arg1;" for the first argument to functions as the ABI, and "generic:pc;" for the program counter. If you think you are specifying these all correctly, please attach the output of running your program after doing a:

(lldb) log enable gdb-remote packets
(lldb) gdb-remote ...

Then I might be able to spot something wrong in the register definitions.

. How can we adjust the offset in DW_AT_location for variables?

You don't need to, each variable already has the needed offset from the frame base and you DWARF looks good. Once you get your register info worked out, your variables should display just fine.

x86_64-apple-macosx qRegisterInfo packet log:

$qRegisterInfo0#72
$name:rax;bitsize:64;offset:0;encoding:uint;format:hex;set:General Purpose Registers;gcc:0;dwarf:0;invalidate-regs:0,15,25,35,39;#00
$qRegisterInfo1#73
$name:rbx;bitsize:64;offset:8;encoding:uint;format:hex;set:General Purpose Registers;gcc:3;dwarf:3;invalidate-regs:1,16,26,36,3a;#00
$qRegisterInfo2#74
$name:rcx;alt-name:arg4;bitsize:64;offset:16;encoding:uint;format:hex;set:General Purpose Registers;gcc:2;dwarf:2;generic:arg4;invalidate-regs:2,17,27,37,3b;#00
$qRegisterInfo3#75
$name:rdx;alt-name:arg3;bitsize:64;offset:24;encoding:uint;format:hex;set:General Purpose Registers;gcc:1;dwarf:1;generic:arg3;invalidate-regs:3,18,28,38,3c;#00
$qRegisterInfo4#76
$name:rdi;alt-name:arg1;bitsize:64;offset:32;encoding:uint;format:hex;set:General Purpose Registers;gcc:5;dwarf:5;generic:arg1;invalidate-regs:4,19,29,3d;#00
$qRegisterInfo5#77
$name:rsi;alt-name:arg2;bitsize:64;offset:40;encoding:uint;format:hex;set:General Purpose Registers;gcc:4;dwarf:4;generic:arg2;invalidate-regs:5,1a,2a,3e;#00
$qRegisterInfo6#78
$name:rbp;alt-name:fp;bitsize:64;offset:48;encoding:uint;format:hex;set:General Purpose Registers;gcc:6;dwarf:6;generic:fp;invalidate-regs:6,1b,2b,3f;#00
$qRegisterInfo7#79
$name:rsp;alt-name:sp;bitsize:64;offset:56;encoding:uint;format:hex;set:General Purpose Registers;gcc:7;dwarf:7;generic:sp;invalidate-regs:7,1c,2c,40;#00
$qRegisterInfo8#7a
$name:r8;alt-name:arg5;bitsize:64;offset:64;encoding:uint;format:hex;set:General Purpose Registers;gcc:8;dwarf:8;generic:arg5;invalidate-regs:8,1d,2d,41;#00
$qRegisterInfo9#7b
$name:r9;alt-name:arg6;bitsize:64;offset:72;encoding:uint;format:hex;set:General Purpose Registers;gcc:9;dwarf:9;generic:arg6;invalidate-regs:9,1e,2e,42;#00
$qRegisterInfoa#a3
$name:r10;bitsize:64;offset:80;encoding:uint;format:hex;set:General Purpose Registers;gcc:10;dwarf:10;invalidate-regs:a,1f,2f,43;#00
$qRegisterInfob#a4
$name:r11;bitsize:64;offset:88;encoding:uint;format:hex;set:General Purpose Registers;gcc:11;dwarf:11;invalidate-regs:b,20,30,44;#00
$qRegisterInfoc#a5
$name:r12;bitsize:64;offset:96;encoding:uint;format:hex;set:General Purpose Registers;gcc:12;dwarf:12;invalidate-regs:c,21,31,45;#00
$qRegisterInfod#a6
$name:r13;bitsize:64;offset:104;encoding:uint;format:hex;set:General Purpose Registers;gcc:13;dwarf:13;invalidate-regs:d,22,32,46;#00
$qRegisterInfoe#a7
$name:r14;bitsize:64;offset:112;encoding:uint;format:hex;set:General Purpose Registers;gcc:14;dwarf:14;invalidate-regs:e,23,33,47;#00
$qRegisterInfof#a8
$name:r15;bitsize:64;offset:120;encoding:uint;format:hex;set:General Purpose Registers;gcc:15;dwarf:15;invalidate-regs:f,24,34,48;#00
$qRegisterInfo10#a3
$name:rip;alt-name:pc;bitsize:64;offset:128;encoding:uint;format:hex;set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;#00
$qRegisterInfo11#a4
$name:rflags;alt-name:flags;bitsize:64;offset:136;encoding:uint;format:hex;set:General Purpose Registers;generic:flags;#00
$qRegisterInfo12#a5
$name:cs;bitsize:64;offset:144;encoding:uint;format:hex;set:General Purpose Registers;#00
$qRegisterInfo13#a6
$name:fs;bitsize:64;offset:152;encoding:uint;format:hex;set:General Purpose Registers;#00
$qRegisterInfo14#a7
$name:gs;bitsize:64;offset:160;encoding:uint;format:hex;set:General Purpose Registers;#00
$qRegisterInfo15#a8
$name:eax;bitsize:32;offset:0;encoding:uint;format:hex;set:General Purpose Registers;container-regs:0;invalidate-regs:0,15,25,35,39;#00
$qRegisterInfo16#a9
$name:ebx;bitsize:32;offset:8;encoding:uint;format:hex;set:General Purpose Registers;container-regs:1;invalidate-regs:1,16,26,36,3a;#00
$qRegisterInfo17#aa
$name:ecx;bitsize:32;offset:16;encoding:uint;format:hex;set:General Purpose Registers;container-regs:2;invalidate-regs:2,17,27,37,3b;#00
$qRegisterInfo18#ab
$name:edx;bitsize:32;offset:24;encoding:uint;format:hex;set:General Purpose Registers;container-regs:3;invalidate-regs:3,18,28,38,3c;#00
$qRegisterInfo19#ac
$name:edi;bitsize:32;offset:32;encoding:uint;format:hex;set:General Purpose Registers;container-regs:4;invalidate-regs:4,19,29,3d;#00
$qRegisterInfo1a#d4
$name:esi;bitsize:32;offset:40;encoding:uint;format:hex;set:General Purpose Registers;container-regs:5;invalidate-regs:5,1a,2a,3e;#00
$qRegisterInfo1b#d5
$name:ebp;bitsize:32;offset:48;encoding:uint;format:hex;set:General Purpose Registers;container-regs:6;invalidate-regs:6,1b,2b,3f;#00
$qRegisterInfo1c#d6
$name:esp;bitsize:32;offset:56;encoding:uint;format:hex;set:General Purpose Registers;container-regs:7;invalidate-regs:7,1c,2c,40;#00
$qRegisterInfo1d#d7
$name:r8d;bitsize:32;offset:64;encoding:uint;format:hex;set:General Purpose Registers;container-regs:8;invalidate-regs:8,1d,2d,41;#00
$qRegisterInfo1e#d8
$name:r9d;bitsize:32;offset:72;encoding:uint;format:hex;set:General Purpose Registers;container-regs:9;invalidate-regs:9,1e,2e,42;#00
$qRegisterInfo1f#d9
$name:r10d;bitsize:32;offset:80;encoding:uint;format:hex;set:General Purpose Registers;container-regs:a;invalidate-regs:a,1f,2f,43;#00
$qRegisterInfo20#a4
$name:r11d;bitsize:32;offset:88;encoding:uint;format:hex;set:General Purpose Registers;container-regs:b;invalidate-regs:b,20,30,44;#00
$qRegisterInfo21#a5
$name:r12d;bitsize:32;offset:96;encoding:uint;format:hex;set:General Purpose Registers;container-regs:c;invalidate-regs:c,21,31,45;#00
$qRegisterInfo22#a6
$name:r13d;bitsize:32;offset:104;encoding:uint;format:hex;set:General Purpose Registers;container-regs:d;invalidate-regs:d,22,32,46;#00
$qRegisterInfo23#a7
$name:r14d;bitsize:32;offset:112;encoding:uint;format:hex;set:General Purpose Registers;container-regs:e;invalidate-regs:e,23,33,47;#00
$qRegisterInfo24#a8
$name:r15d;bitsize:32;offset:120;encoding:uint;format:hex;set:General Purpose Registers;container-regs:f;invalidate-regs:f,24,34,48;#00
$qRegisterInfo25#a9
$name:ax;bitsize:16;offset:0;encoding:uint;format:hex;set:General Purpose Registers;container-regs:0;invalidate-regs:0,15,25,35,39;#00
$qRegisterInfo26#aa
$name:bx;bitsize:16;offset:8;encoding:uint;format:hex;set:General Purpose Registers;container-regs:1;invalidate-regs:1,16,26,36,3a;#00
$qRegisterInfo27#ab
$name:cx;bitsize:16;offset:16;encoding:uint;format:hex;set:General Purpose Registers;container-regs:2;invalidate-regs:2,17,27,37,3b;#00
$qRegisterInfo28#ac
$name:dx;bitsize:16;offset:24;encoding:uint;format:hex;set:General Purpose Registers;container-regs:3;invalidate-regs:3,18,28,38,3c;#00
$qRegisterInfo29#ad
$name:di;bitsize:16;offset:32;encoding:uint;format:hex;set:General Purpose Registers;container-regs:4;invalidate-regs:4,19,29,3d;#00
$qRegisterInfo2a#d5
$name:si;bitsize:16;offset:40;encoding:uint;format:hex;set:General Purpose Registers;container-regs:5;invalidate-regs:5,1a,2a,3e;#00
$qRegisterInfo2b#d6
$name:bp;bitsize:16;offset:48;encoding:uint;format:hex;set:General Purpose Registers;container-regs:6;invalidate-regs:6,1b,2b,3f;#00
$qRegisterInfo2c#d7
$name:sp;bitsize:16;offset:56;encoding:uint;format:hex;set:General Purpose Registers;container-regs:7;invalidate-regs:7,1c,2c,40;#00
$qRegisterInfo2d#d8
$name:r8w;bitsize:16;offset:64;encoding:uint;format:hex;set:General Purpose Registers;container-regs:8;invalidate-regs:8,1d,2d,41;#00
$qRegisterInfo2e#d9
$name:r9w;bitsize:16;offset:72;encoding:uint;format:hex;set:General Purpose Registers;container-regs:9;invalidate-regs:9,1e,2e,42;#00
$qRegisterInfo2f#da
$name:r10w;bitsize:16;offset:80;encoding:uint;format:hex;set:General Purpose Registers;container-regs:a;invalidate-regs:a,1f,2f,43;#00
$qRegisterInfo30#a5
$name:r11w;bitsize:16;offset:88;encoding:uint;format:hex;set:General Purpose Registers;container-regs:b;invalidate-regs:b,20,30,44;#00
$qRegisterInfo31#a6
$name:r12w;bitsize:16;offset:96;encoding:uint;format:hex;set:General Purpose Registers;container-regs:c;invalidate-regs:c,21,31,45;#00
$qRegisterInfo32#a7
$name:r13w;bitsize:16;offset:104;encoding:uint;format:hex;set:General Purpose Registers;container-regs:d;invalidate-regs:d,22,32,46;#00
$qRegisterInfo33#a8
$name:r14w;bitsize:16;offset:112;encoding:uint;format:hex;set:General Purpose Registers;container-regs:e;invalidate-regs:e,23,33,47;#00
$qRegisterInfo34#a9
$name:r15w;bitsize:16;offset:120;encoding:uint;format:hex;set:General Purpose Registers;container-regs:f;invalidate-regs:f,24,34,48;#00
$qRegisterInfo35#aa
$name:ah;bitsize:8;offset:1;encoding:uint;format:hex;set:General Purpose Registers;container-regs:0;invalidate-regs:0,15,25,35,39;#00
$qRegisterInfo36#ab
$name:bh;bitsize:8;offset:9;encoding:uint;format:hex;set:General Purpose Registers;container-regs:1;invalidate-regs:1,16,26,36,3a;#00
$qRegisterInfo37#ac
$name:ch;bitsize:8;offset:17;encoding:uint;format:hex;set:General Purpose Registers;container-regs:2;invalidate-regs:2,17,27,37,3b;#00
$qRegisterInfo38#ad
$name:dh;bitsize:8;offset:25;encoding:uint;format:hex;set:General Purpose Registers;container-regs:3;invalidate-regs:3,18,28,38,3c;#00
$qRegisterInfo39#ae
$name:al;bitsize:8;offset:0;encoding:uint;format:hex;set:General Purpose Registers;container-regs:0;invalidate-regs:0,15,25,35,39;#00
$qRegisterInfo3a#d6
$name:bl;bitsize:8;offset:8;encoding:uint;format:hex;set:General Purpose Registers;container-regs:1;invalidate-regs:1,16,26,36,3a;#00
$qRegisterInfo3b#d7
$name:cl;bitsize:8;offset:16;encoding:uint;format:hex;set:General Purpose Registers;container-regs:2;invalidate-regs:2,17,27,37,3b;#00
$qRegisterInfo3c#d8
$name:dl;bitsize:8;offset:24;encoding:uint;format:hex;set:General Purpose Registers;container-regs:3;invalidate-regs:3,18,28,38,3c;#00
$qRegisterInfo3d#d9
$name:dil;bitsize:8;offset:32;encoding:uint;format:hex;set:General Purpose Registers;container-regs:4;invalidate-regs:4,19,29,3d;#00
$qRegisterInfo3e#da
$name:sil;bitsize:8;offset:40;encoding:uint;format:hex;set:General Purpose Registers;container-regs:5;invalidate-regs:5,1a,2a,3e;#00
$qRegisterInfo3f#db
$name:bpl;bitsize:8;offset:48;encoding:uint;format:hex;set:General Purpose Registers;container-regs:6;invalidate-regs:6,1b,2b,3f;#00
$qRegisterInfo40#a6
$name:spl;bitsize:8;offset:56;encoding:uint;format:hex;set:General Purpose Registers;container-regs:7;invalidate-regs:7,1c,2c,40;#00
$qRegisterInfo41#a7
$name:r8l;bitsize:8;offset:64;encoding:uint;format:hex;set:General Purpose Registers;container-regs:8;invalidate-regs:8,1d,2d,41;#00
$qRegisterInfo42#a8
$name:r9l;bitsize:8;offset:72;encoding:uint;format:hex;set:General Purpose Registers;container-regs:9;invalidate-regs:9,1e,2e,42;#00
$qRegisterInfo43#a9
$name:r10l;bitsize:8;offset:80;encoding:uint;format:hex;set:General Purpose Registers;container-regs:a;invalidate-regs:a,1f,2f,43;#00
$qRegisterInfo44#aa
$name:r11l;bitsize:8;offset:88;encoding:uint;format:hex;set:General Purpose Registers;container-regs:b;invalidate-regs:b,20,30,44;#00
$qRegisterInfo45#ab
$name:r12l;bitsize:8;offset:96;encoding:uint;format:hex;set:General Purpose Registers;container-regs:c;invalidate-regs:c,21,31,45;#00
$qRegisterInfo46#ac
$name:r13l;bitsize:8;offset:104;encoding:uint;format:hex;set:General Purpose Registers;container-regs:d;invalidate-regs:d,22,32,46;#00
$qRegisterInfo47#ad
$name:r14l;bitsize:8;offset:112;encoding:uint;format:hex;set:General Purpose Registers;container-regs:e;invalidate-regs:e,23,33,47;#00
$qRegisterInfo48#ae
$name:r15l;bitsize:8;offset:120;encoding:uint;format:hex;set:General Purpose Registers;container-regs:f;invalidate-regs:f,24,34,48;#00
$qRegisterInfo49#af
$name:fctrl;bitsize:16;offset:168;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo4a#d7
$name:fstat;bitsize:16;offset:170;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo4b#d8
$name:ftag;bitsize:8;offset:172;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo4c#d9
$name:fop;bitsize:16;offset:173;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo4d#da
$name:fioff;bitsize:32;offset:175;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo4e#db
$name:fiseg;bitsize:16;offset:179;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo4f#dc
$name:fooff;bitsize:32;offset:181;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo50#a7
$name:foseg;bitsize:16;offset:185;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo51#a8
$name:mxcsr;bitsize:32;offset:187;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo52#a9
$name:mxcsrmask;bitsize:32;offset:191;encoding:uint;format:hex;set:Floating Point Registers;#00
$qRegisterInfo53#aa
$name:stmm0;bitsize:80;offset:195;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:33;dwarf:33;#00
$qRegisterInfo54#ab
$name:stmm1;bitsize:80;offset:205;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:34;dwarf:34;#00
$qRegisterInfo55#ac
$name:stmm2;bitsize:80;offset:215;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:35;dwarf:35;#00
$qRegisterInfo56#ad
$name:stmm3;bitsize:80;offset:225;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:36;dwarf:36;#00
$qRegisterInfo57#ae
$name:stmm4;bitsize:80;offset:235;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:37;dwarf:37;#00
$qRegisterInfo58#af
$name:stmm5;bitsize:80;offset:245;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:38;dwarf:38;#00
$qRegisterInfo59#b0
$name:stmm6;bitsize:80;offset:255;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:39;dwarf:39;#00
$qRegisterInfo5a#d8
$name:stmm7;bitsize:80;offset:265;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:40;dwarf:40;#00
$qRegisterInfo5b#d9
$name:ymm0;bitsize:256;offset:275;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:17;dwarf:17;#00
$qRegisterInfo5c#da
$name:ymm1;bitsize:256;offset:307;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:18;dwarf:18;#00
$qRegisterInfo5d#db
$name:ymm2;bitsize:256;offset:339;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:19;dwarf:19;#00
$qRegisterInfo5e#dc
$name:ymm3;bitsize:256;offset:371;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:20;dwarf:20;#00
$qRegisterInfo5f#dd
$name:ymm4;bitsize:256;offset:403;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:21;dwarf:21;#00
$qRegisterInfo60#a8
$name:ymm5;bitsize:256;offset:435;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:22;dwarf:22;#00
$qRegisterInfo61#a9
$name:ymm6;bitsize:256;offset:467;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:23;dwarf:23;#00
$qRegisterInfo62#aa
$name:ymm7;bitsize:256;offset:499;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:24;dwarf:24;#00
$qRegisterInfo63#ab
$name:ymm8;bitsize:256;offset:531;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:25;dwarf:25;#00
$qRegisterInfo64#ac
$name:ymm9;bitsize:256;offset:563;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:26;dwarf:26;#00
$qRegisterInfo65#ad
$name:ymm10;bitsize:256;offset:595;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:27;dwarf:27;#00
$qRegisterInfo66#ae
$name:ymm11;bitsize:256;offset:627;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:28;dwarf:28;#00
$qRegisterInfo67#af
$name:ymm12;bitsize:256;offset:659;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:29;dwarf:29;#00
$qRegisterInfo68#b0
$name:ymm13;bitsize:256;offset:691;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:30;dwarf:30;#00
$qRegisterInfo69#b1
$name:ymm14;bitsize:256;offset:723;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:31;dwarf:31;#00
$qRegisterInfo6a#d9
$name:ymm15;bitsize:256;offset:755;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:32;dwarf:32;#00
$qRegisterInfo6b#da
$name:xmm0;bitsize:128;offset:275;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:17;dwarf:17;container-regs:5b;#00
$qRegisterInfo6c#db
$name:xmm1;bitsize:128;offset:307;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:18;dwarf:18;container-regs:5c;#00
$qRegisterInfo6d#dc
$name:xmm2;bitsize:128;offset:339;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:19;dwarf:19;container-regs:5d;#00
$qRegisterInfo6e#dd
$name:xmm3;bitsize:128;offset:371;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:20;dwarf:20;container-regs:5e;#00
$qRegisterInfo6f#de
$name:xmm4;bitsize:128;offset:403;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:21;dwarf:21;container-regs:5f;#00
$qRegisterInfo70#a9
$name:xmm5;bitsize:128;offset:435;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:22;dwarf:22;container-regs:60;#00
$qRegisterInfo71#aa
$name:xmm6;bitsize:128;offset:467;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:23;dwarf:23;container-regs:61;#00
$qRegisterInfo72#ab
$name:xmm7;bitsize:128;offset:499;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:24;dwarf:24;container-regs:62;#00
$qRegisterInfo73#ac
$name:xmm8;bitsize:128;offset:531;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:25;dwarf:25;container-regs:63;#00
$qRegisterInfo74#ad
$name:xmm9;bitsize:128;offset:563;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:26;dwarf:26;container-regs:64;#00
$qRegisterInfo75#ae
$name:xmm10;bitsize:128;offset:595;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:27;dwarf:27;container-regs:65;#00
$qRegisterInfo76#af
$name:xmm11;bitsize:128;offset:627;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:28;dwarf:28;container-regs:66;#00
$qRegisterInfo77#b0
$name:xmm12;bitsize:128;offset:659;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:29;dwarf:29;container-regs:67;#00
$qRegisterInfo78#b1
$name:xmm13;bitsize:128;offset:691;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:30;dwarf:30;container-regs:68;#00
$qRegisterInfo79#b2
$name:xmm14;bitsize:128;offset:723;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:31;dwarf:31;container-regs:69;#00
$qRegisterInfo7a#da
$name:xmm15;bitsize:128;offset:755;encoding:vector;format:vector-uint8;set:Floating Point Registers;gcc:32;dwarf:32;container-regs:6a;#00
$qRegisterInfo7b#db
$name:trapno;bitsize:32;offset:787;encoding:uint;format:hex;set:Exception State Registers;#00
$qRegisterInfo7c#dc
$name:err;bitsize:32;offset:791;encoding:uint;format:hex;set:Exception State Registers;#00
$qRegisterInfo7d#dd
$name:faultvaddr;bitsize:64;offset:795;encoding:uint;format:hex;set:Exception State Registers;#00
$qRegisterInfo7e#de
$E45#00

I recently did some work with the debug info as generated by llvm, and there are a lot of bugs. LLVM writes wrong DWARF info. My impression is that DWARF writer is barely passable with clang-generated code, or maybe it malfunctions with clang as well. People don't hold debug info to the same high standard as the code itself.

Here is an example when variable info generated is plain wrong: 18866 – Debug info for function argument has a wrong span

Yuri

I ported llvm backend and lldb recently. Both tools can basically work.
lldb is able to debug programs in asm style and frame unwinding is OK.

But "frame variable XX" does not work because lldb is not able to
determine
the address of
XX from debug info.

I recently did some work with the debug info as generated by llvm, and
there are a lot of bugs. LLVM writes wrong DWARF info. My impression is
that DWARF writer is barely passable with clang-generated code, or maybe it
malfunctions with clang as well. People don't hold debug info to the same
high standard as the code itself.

Here is an example when variable info generated is plain wrong:
18866 – Debug info for function argument has a wrong span

Certainly there are bugs, but practically speaking I wouldn't characterize
clang-generated debug info to be "barely passable". It generally works for
me - it passes much of the GDB 7.5 test suite successfully.

(this is all predicated on: "at -O0" - optimized debug info is another
story entirely. Though there are even issues with locations (and sometimes
even types!) at -O0, but they're pretty rare in my experience - I use Clang
to debug Clang day-to-day and only every few months do I hit a bug)

Certainly there are bugs, but practically speaking I wouldn't characterize
clang-generated debug info to be "barely passable". It generally works for
me - it passes much of the GDB 7.5 test suite successfully.

Clang works, but I am getting an impression that any deviations from what clang does causes troubles.
I don't know, every time I look, I find something wrong with resulting DWARF.

(this is all predicated on: "at -O0" - optimized debug info is another
story entirely. Though there are even issues with locations (and sometimes
even types!) at -O0, but they're pretty rare in my experience - I use Clang
to debug Clang day-to-day and only every few months do I hit a bug)

Yes, my test case is for -O0 and CL=Large. Debug info for optimized code is a different issue, you are right.

Yuri

Certainly there are bugs, but practically speaking I wouldn't characterize
clang-generated debug info to be "barely passable". It generally works for
me - it passes much of the GDB 7.5 test suite successfully.

Clang works, but I am getting an impression that any deviations from what
clang does causes troubles.
I don't know, every time I look, I find something wrong with resulting
DWARF.

(this is all predicated on: "at -O0" - optimized debug info is another
story entirely. Though there are even issues with locations (and sometimes
even types!) at -O0, but they're pretty rare in my experience - I use
Clang
to debug Clang day-to-day and only every few months do I hit a bug)

Yes, my test case is for -O0 and CL=Large.

Not sure what you mean by "CL=Large". Another caveat to -O0, is that's
Clang's style of -O0 (this is one of those "what Clang generates is what
works best" cases): emitting allocas for each variable to keep track of the
location easily.

Also, it's not clear that Yang even has the issues you have - no mention of
a custom frontend, just a custom backend (granted no mention that Yang is
using Clang either, so it could go either way).

- David

dwarf 3 says: “… The virtual unwind information is encoded in a self-contained section called .debug_frame. …”

So I guess it is irrelative to my problem.

Bset regards.

Thank you, Clayton. It works now!

Our debugger server responds “name:J28;generic:fp;bitsize:32;encoding:uint;format:hex;gcc:60;dwarf:60”.
And I also set other “generic” attributes like sp, pc, ra, arg1~arg8 to related registers.

I dig a little and find llvm dwarf generator uses TargetRegisterInfo::getFrameRegister() to obtain frame base, and uses TargetFrameLowering::getFrameIndexReference() to obtain frame base as well as frame offset of a variable.

lldb is OK to check value of variable including both formal arguments and locals, although some line numbers are still improper.
For example, in the case mentioned above, “.loc 1 2 0 prologue_end” is actually the start point of prologue. Any suggestions?

Best regards.

Thank you, Clayton. It works now!

Our debugger server responds "name:J28;generic:fp;bitsize:32;encoding:uint;format:hex;gcc:60;dwarf:60".
And I also set other "generic" attributes like sp, pc, ra, arg1~arg8 to related registers.

I dig a little and find llvm dwarf generator uses TargetRegisterInfo::getFrameRegister() to obtain frame base, and uses TargetFrameLowering::getFrameIndexReference() to obtain frame base as well as frame offset of a variable.

lldb is OK to check value of variable including both formal arguments and locals

Great, I am glad you have variables working!

although some line numbers are still improper.
For example, in the case mentioned above, ".loc 1 2 0 prologue_end" is actually the start point of prologue. Any suggestions?

I don't know who to talk to about the DWARF line tables. You might check the LLVM sources that generate this code and then do an "svn annotate" on those files to see who mostly created and is maintaining them. Sorry I can't help much on this front.

Greg

Hey Eric,

Any thoughts on this part for triple.yang@gmail.com?