llvm / llvm-project

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

clang emits code for constructors that causes debuggers to behave unexpectedly #29968

Open llvmbot opened 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 30620
Version unspecified
OS MacOS X
Reporter LLVM Bugzilla Contributor
CC @pogo59

Extended Description

This is reported by jacdavis@microsoft.com (he's waiting for his account on lldvm.org/bugs to be created):

clang emits a wrapper constructor whose purpose is to invoke child constructors, copy constructors, and ultimately, the real constructor of a class. This wrapper constructor is mapped to the same source code as the real constructor and is not marked with a trampoline symbol (which would tell the debugger to continue stepping through that code) or the target no-stmt flag in the line info.

Unfortunately, this means that both gdb and lldb (when debugging this clang compiled binary) stop in the wrapper constructor rather than the targets. Now, when a bp is set in the source of the real constructor, the debugger will stop when that bp is hit. The logical callstack (not displayed in the window) then looks like this:

real_ctor

wrapper_ctor

main

Stepping off the end of the real constructor stops in the wrapper constructor.

Interesting symbols:

wrapper constructor disassem

a.out`CSquid::CSquid: 0x100000f60 <+0>: pushq %rbp 0x100000f61 <+1>: movq %rsp, %rbp 0x100000f64 <+4>: subq $0x10, %rsp 0x100000f68 <+8>: movq %rdi, -0x8(%rbp) 0x100000f6c <+12>: movq -0x8(%rbp), %rdi 0x100000f70 <+16>: callq 0x100000fa0 ; call to real constructor CSquid::CSquid at constructorbug.cpp:8 0x100000f79 <+25>: popq %rbp 0x100000f7a <+26>: retq 0x100000f7b <+27>: nopl (%rax,%rax)

real constructor disassem:

.out`CSquid::CSquid: 0x100000fa0 <+0>: pushq %rbp 0x100000fa1 <+1>: movq %rsp, %rbp 0x100000fa4 <+4>: movq %rdi, -0x8(%rbp) 0x100000fa8 <+8>: movq -0x8(%rbp), %rdi 0x100000fb2 <+18>: popq %rbp 0x100000fb3 <+19>: req

Wrapper constructor subprogram symbol:

0x000000b8: TAG_subprogram [11] * AT_low_pc( 0x0000000100000f60 ) AT_high_pc( 0x0000000100000f7b ) AT_frame_base( rbp ) AT_object_pointer( {0x000000db} ) AT_MIPS_linkage_name( "_ZN6CSquidC1Ev" ) AT_specification( {0x0000000000000044}"CSquid" )

0x000000db: TAG_formal_parameter [12]
AT_location( fbreg -8 ) AT_name( "this" ) AT_type( {0x0000000000000165} ( CSquid* ) ) AT_artificial( 0x01 )

0x000000ec: NULL

Real constructor subprogram symbol:

0x00000130: TAG_subprogram [11] * AT_low_pc( 0x0000000100000fa0 ) AT_high_pc( 0x0000000100000fb4 ) AT_frame_base( rbp ) AT_object_pointer( {0x00000153} ) AT_MIPS_linkage_name( "_ZN6CSquidC2Ev" ) AT_specification( {0x0000000000000044}"CSquid" )

0x00000153: TAG_formal_parameter [12]
AT_location( fbreg -8 ) AT_name( "this" ) AT_type( {0x0000000000000165} ( CSquid* ) ) AT_artificial( 0x01 )

0x00000164: NULL

Line table for both:

0x0000004f: DW_LNE_set_address( 0x0000000100000f60 ) 0x0000005a: address += 0, line += 7 0x0000000100000f60 1 8 0 is_stmt

0x0000005b: DW_LNS_set_column( 5 ) 0x0000005d: DW_LNS_set_prologue_end

0x0000005e: address += 10, line += 0 0x0000000100000f70 1 8 5 is_stmt prologue_end

0x0000005f: address += 5, line += 2 0x0000000100000f75 1 10 5 is_stmt

0x00000060: DW_LNS_advance_pc( 6 ) 0x00000062: DW_LNE_end_sequence 0x0000000100000f7b 1 10 5 is_stmt

0x00000082: DW_LNE_set_address( 0x0000000100000fa0 ) 0x0000008d: address += 0, line += 7 0x0000000100000fa0 1 8 0 is_stmt

0x0000008e: DW_LNS_set_column( 13 ) 0x00000090: DW_LNS_set_prologue_end 0x00000091: address += c, line += 1 0x0000000100000fac 1 9 13 is_stmt prologue_end

0x00000092: DW_LNS_set_column( 5 ) 0x00000094: address += 6, line += 1 0x0000000100000fb2 1 10 5 is_stmt

0x00000095: DW_LNS_advance_pc( 2 ) 0x00000097: DW_LNE_end_sequence 0x0000000100000fb4 1 10 5 is_stmt

pogo59 commented 7 years ago

Well, the is_stmt flag is generated pretty naively (and late) so it's unlikely we can get that turned off for these wrappers. I assume marking them artificial isn't sufficient? (although it should not be hard.)

Inventing a trampoline link might not be too hard.