llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.7k stars 11.87k forks source link

Debug information for inline constructor not proper. #13689

Closed llvmbot closed 12 years ago

llvmbot commented 12 years ago
Bugzilla Link 13317
Resolution INVALID
Resolved on Jul 16, 2012 23:56
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @asl,@DougGregor,@echristo,@rjmccall

Extended Description

In case of inline default constructor debug information in wrongly generated. For e.g. for the below code-

class Apple { public: Apple () { int b = 0; } };

int main (void) { Apple b; return 0; }

Debug info for the default constructor in the assembly is as follows contains 2 entries i.e.

_ZN5AppleC1Ev: .Lfunc_begin1: .loc 2 5 0
@ BB#0: @ %entry push {r7, lr} mov r7, sp sub sp, #​24 str r0, [sp, #​16] str r0, [sp, #​20] sub sp, #​4 .loc 2 7 2 prologue_end
.Ltmp3: str r0, [sp, #​12] @ 4-byte Spill bl _ZN5AppleC2Ev(PLT) ldr r1, [sp, #​20] ldr r2, [sp, #​12] @ 4-byte Reload str r0, [sp, #​8] @ 4-byte Spill mov r0, r1 str r2, [sp, #​4] @ 4-byte Spill add sp, #​28 pop {r7, pc} .Ltmp4: .Ltmp5: .size _ZN5AppleC1Ev, .Ltmp5-_ZN5AppleC1Ev .Lfunc_end1:

.section    .text._ZN5AppleC2Ev,"axG",%progbits,_ZN5AppleC2Ev,comdat
.weak   _ZN5AppleC2Ev
.align  2
.type   _ZN5AppleC2Ev,%function
.code   16                      @ @​_ZN5AppleC2Ev
.thumb_func

_ZN5AppleC2Ev: .Lfunc_begin2: .loc 2 5 0
@ BB#0: @ %entry sub sp, #​16 @DEBUG_VALUE: Apple:this <- undef str r0, [sp, #​8] str r0, [sp, #​12] movs r1, #​0 sub sp, #​4 .loc 2 6 16 prologue_end
.Ltmp6: str r1, [sp, #​4] .loc 2 7 2
ldr r1, [sp, #​12] str r0, [sp] @ 4-byte Spill mov r0, r1 add sp, #​20 bx lr .Ltmp7: .Ltmp8: .size _ZN5AppleC2Ev, .Ltmp8-_ZN5AppleC2Ev .Lfunc_end2:

As shown in the assembly snippet. For the default constructor we get 2 entries one by name _ZN5AppleC1Ev and another by _ZN5AppleC2Ev.

llvmbot commented 12 years ago

Thanks a lot Eric and Douglas.

echristo commented 12 years ago

No, I agree completely. The debug info is merely explaining what's going on so there's no difference there. In addition, Daniel's comments in the thread you pointed me at are compelling and explain why we don't want to do anything.

DougGregor commented 12 years ago

Dear Eric,Douglas Thanks for the quick reply. I had one quick query.

As Douglas mentioned 'C1' name is the complete object constructor and the 'C2' name is the base object constructor. But in the example

class Apple { public: Apple () { int b = 0; } };

int main (void) { Apple b; return 0; }

This class has no base. Why does it have a "complete object constructor" and a "base object constructor" for each?

The Itanium C++ ABI I linked to describes this in detail, but essentially the "complete object constructor" is used when we're building a complete object of type Apple, as in

Apple a;

while the "base object constructor" is used when the Apple object is a base of another class, e.g.,

class Banana : public Apple { }; Banana b;

This dual emission of constructor results in problem with setting breakpoints in constructors as we have two info for same location.

For e.g. In the above code if we run the gdb session as follows-

/opt/home/blitz # gdb a.out GNU gdb (Linaro GDB) 7.2-2011.03-0-SLP Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabi". For bug reporting instructions, please see: http://bugs.launchpad.net/gdb-linaro/... Reading symbols from /opt/home/blitz/a.out...done. (gdb) b main Breakpoint 1 at 0x83ca: file ./class.cpp, line 13. (gdb) b 6 Breakpoint 2 at 0x8406: file ./class.cpp, line 6. (gdb) r Starting program: /opt/home/blitz/a.out

Breakpoint 1, main () at ./class.cpp:13 warning: Source file is more recent than executable. 13 Apple a; (gdb) c Continuing.

Breakpoint 2, Apple::Apple (this=0xbe811ab8) at ./class.cpp:6 6 int b = 0; (gdb) bt

​0 Apple::Apple (this=0xbe811ab8) at ./class.cpp:6

​1 0x000083f2 in Apple::Apple (this=0xbe811ab8) at ./class.cpp:7

​2 0x000083d8 in main () at ./class.cpp:13

(gdb) Quit (gdb)

In the above session we can find that we had set break point at line 6 and have not yet reached line 7. But the bt command when run at line 6 also emits the wrong info -

​1 0x000083f2 in Apple::Apple (this=0xbe811ab8) at ./class.cpp:7

(line 7 info which comes from C1 constructors prologue_end .loc)

There are few other GDB problems as well when we debug the constructor.

When we looked up we found that the same issue was reported in case of GCC. We can refer-

http://stackoverflow.com/questions/6921295/dual-emission-of-constructor-symbols http://gcc.gnu.org/bugs/#known,

Personally, I don't consider this a bug in either GCC or Clang. This behavior is mandated by the Itanium C++ ABI, and it's GDB that needs to learn to handle C++ constructors emitted for the Itanium C++ ABI properly.

When we checked the same in case of gcc it seems it actually alias the symbols to the same code for both. A temporary patch seems to have been given as per http://sources.redhat.com/ml/gdb/2004-07/msg00163.html

We might need to do something similar in case of clang. Please let us know if our analysis is correct.

Clang does perform this optimization on some platforms, when possible. However, it can't always be done (because the constructors will behave differently when, e.g., there are virtual base classes involved), and therefore can't be relied upon to improve the debugging situation.

Unless Eric thinks there is something specific that the compiler can do here (which I doubt), I think this is not a Clang bug.

llvmbot commented 12 years ago

Dear Eric,Douglas Thanks for the quick reply. I had one quick query.

As Douglas mentioned 'C1' name is the complete object constructor and the 'C2' name is the base object constructor. But in the example

class Apple { public: Apple () { int b = 0; } };

int main (void) { Apple b; return 0; }

This class has no base. Why does it have a "complete object constructor" and a "base object constructor" for each?

This dual emission of constructor results in problem with setting breakpoints in constructors as we have two info for same location.

For e.g. In the above code if we run the gdb session as follows-

/opt/home/blitz # gdb a.out GNU gdb (Linaro GDB) 7.2-2011.03-0-SLP Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabi". For bug reporting instructions, please see: http://bugs.launchpad.net/gdb-linaro/... Reading symbols from /opt/home/blitz/a.out...done. (gdb) b main Breakpoint 1 at 0x83ca: file ./class.cpp, line 13. (gdb) b 6 Breakpoint 2 at 0x8406: file ./class.cpp, line 6. (gdb) r Starting program: /opt/home/blitz/a.out

Breakpoint 1, main () at ./class.cpp:13 warning: Source file is more recent than executable. 13 Apple a; (gdb) c Continuing.

Breakpoint 2, Apple::Apple (this=0xbe811ab8) at ./class.cpp:6 6 int b = 0; (gdb) bt

​0 Apple::Apple (this=0xbe811ab8) at ./class.cpp:6

​1 0x000083f2 in Apple::Apple (this=0xbe811ab8) at ./class.cpp:7

​2 0x000083d8 in main () at ./class.cpp:13

(gdb) Quit (gdb)

In the above session we can find that we had set break point at line 6 and have not yet reached line 7. But the bt command when run at line 6 also emits the wrong info -

​1 0x000083f2 in Apple::Apple (this=0xbe811ab8) at ./class.cpp:7

(line 7 info which comes from C1 constructors prologue_end .loc)

There are few other GDB problems as well when we debug the constructor.

When we looked up we found that the same issue was reported in case of GCC. We can refer-

http://stackoverflow.com/questions/6921295/dual-emission-of-constructor-symbols http://gcc.gnu.org/bugs/#known,

When we checked the same in case of gcc it seems it actually alias the symbols to the same code for both. A temporary patch seems to have been given as per http://sources.redhat.com/ml/gdb/2004-07/msg00163.html

We might need to do something similar in case of clang. Please let us know if our analysis is correct. Thanks

echristo commented 12 years ago

You know, I think that's the second time that's come up. I should remember it for next time. Thanks :)

DougGregor commented 12 years ago

The dwarf is successfully describing the two functions that are there in the assembly. My knowledge of C++ constructor semantics is a bit lacking so I'm going to punt to John or Doug on this...

Multiple versions of the constructors are required by the C++ ABI as documented here:

http://sourcery.mentor.com/public/cxx-abi/abi.html

The 'C1' name is the complete object constructor and the 'C2' name is the base object constructor.

echristo commented 12 years ago

The dwarf is successfully describing the two functions that are there in the assembly. My knowledge of C++ constructor semantics is a bit lacking so I'm going to punt to John or Doug on this...

echristo commented 12 years ago

Here's the dwarf for this:

0x0000008b: TAG_subprogram [10] * AT_MIPS_linkage_name( "_ZN5AppleC1Ev" ) AT_specification( {0x00000074} ( "Apple" ) ) AT_low_pc( 0x00000000000002d0 ) AT_high_pc( 0x00000000000002eb ) AT_frame_base( rbp )

0x000000a6: TAG_formal_parameter [11]
AT_name( "this" ) AT_decl_file( "/Users/echristo/foo.cpp" ) AT_decl_line( 4 ) AT_type( {0x00000101} ( Apple* ) ) AT_artificial( 0x01 ) AT_location( fbreg -8 )

0x000000b5: NULL

0x000000b6: TAG_subprogram [10] * AT_MIPS_linkage_name( "_ZN5AppleC2Ev" ) AT_specification( {0x00000074} ( "Apple" ) ) AT_low_pc( 0x00000000000002f0 ) AT_high_pc( 0x0000000000000301 ) AT_frame_base( rbp )

0x000000d1: TAG_formal_parameter [11]
AT_name( "this" ) AT_decl_file( "/Users/echristo/foo.cpp" ) AT_decl_line( 4 ) AT_type( {0x00000101} ( Apple* ) ) AT_artificial( 0x01 ) AT_location( fbreg -8 )

0x000000e0: TAG_lexical_block [3] * AT_low_pc( 0x00000000000002f8 ) AT_high_pc( 0x0000000000000301 )

0x000000f1: TAG_variable [4]
AT_name( "b" ) AT_decl_file( "/Users/echristo/foo.cpp" ) AT_decl_line( 6 ) AT_type( {0x00000065} ( int ) ) AT_location( fbreg -12 )

0x000000ff: NULL

0x00000100: NULL