[PATCH] PR19864: Revert r209764 in favor of the fix in r215766 (loop backedge jump attributed to confusing location when the last source line of a loop is inside a conditional)

David Blaikie dblaikie at gmail.com
Fri Aug 22 16:51:54 PDT 2014


On Mon, Aug 18, 2014 at 5:09 PM, Adrian Prantl <aprantl at apple.com> wrote:
> [+]Jim,
>
> I wonder what the LLDB perspective on this is:
> For code like this example from http://reviews.llvm.org/D4956:
>
>> 300 if (foo f = foo())
>> 301        body(); // this might throw
>
> where foo is a C++ class with a destructor, and body() may need a cleanup, which line table entry would the debugger prefer to see for the implicit call to ~foo()?
>
> // Pseudo-expanded code for the above example:
> foo f = foo();       // 300
> if (f) {             // 300
>    body();           // 301
>    _cleanups();      // 301
> }
> ~foo();              // ???
>
> According to David, GCC emits both the cleanup and the call to ~foo() on line 301,

Sorry, perhaps I misspoke (not sure) - there are 3 things: the body of
the if, the unexceptional dtor call and the EH dtor call. (I'll avoid
the term cleanup since the unexceptional dtor call and the EH dtor
call are both "cleanup" of a sort)

GCC emits them in this order:

  body // line 301
  unexceptional dtor call // line 301
  EH dtor call // end-of-function

Clang does:

  body // line 301
  EH dtor call // end-of-function
  unexceptional dtor call // line 301

But without any exceptions, these devolve to the same behavior and
Clang and GCC's output matches (and GDB's behavior matches).

> and GDB apparently has some heuristic that makes it skip 301 if the condition is false. (For reference, if I am on line 300 in LLDB and “next”, it will (unsurprisingly) unconditionally go to line 301.)
>
> -- adrian
>
> On Aug 18, 2014, at 3:24 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>> On Mon, Aug 18, 2014 at 2:23 PM, Adrian Prantl <aprantl at apple.com> wrote:
>>> I tested the patch with LLDB, and it takes the line table literally:
>>
>> What about in the non-exception test case?
>>
>> What's the nexting behavior in LLDB without the patch? In GDB I find I
>> have to "next" twice on the 'if' line as it is today.
>>
>>>
>>> ```
>>> void body() { printf("body\n"); }
>>> foo::operator bool() throw() { return false; }
>>> foo::~foo() { printf("~foo\n"); }
>>>
>>> * thread #1: tid = 0x2a38e9, 0x0000000100000d8d debug-info-line-if`main + 221 at debug-info-line-if.cpp:51, queue = 'com.apple.main-thread', stop reason = step over
>>>    frame #0: 0x0000000100000d8d debug-info-line-if`main + 221 at debug-info-line-if.cpp:51
>>>   48     // CHECK: call void @_ZN3fooD1Ev{{.*}}, !dbg [[DBG3:!.*]]
>>>   49
>>>   50     //#line 400
>>> -> 51     if (foo f = foo())
>>>   52       body(); // this might throw
>>>   53
>>>   54     // GDB currently steps from the 'foo f' line to the 'body()' line, even if 'f'
>>> (lldb)
>>> Process 10528 stopped
>>> * thread #1: tid = 0x2a38e9, 0x0000000100000dc9 debug-info-line-if`main + 281 at debug-info-line-if.cpp:52, queue = 'com.apple.main-thread', stop reason = step over
>>>    frame #0: 0x0000000100000dc9 debug-info-line-if`main + 281 at debug-info-line-if.cpp:52
>>>   49
>>>   50     //#line 400
>>>   51     if (foo f = foo())
>>> -> 52       body(); // this might throw
>>>   53
>>>   54     // GDB currently steps from the 'foo f' line to the 'body()' line, even if 'f'
>>>   55     // is false, because the call to 'f's dtor is attribute to the 'body()' line.
>>> (lldb)
>>> ~foo
>>> Process 10528 stopped
>>> * thread #1: tid = 0x2a38e9, 0x0000000100000dce debug-info-line-if`main + 286 at debug-info-line-if.cpp:78, queue = 'com.apple.main-thread', stop reason = step over
>>>    frame #0: 0x0000000100000dce debug-info-line-if`main + 286 at debug-info-line-if.cpp:78
>>>   75     // CHECK: [[DBG5]] = metadata !{i32 401, i32 0, metadata !{{.*}}, null}
>>>   76
>>>   77     //#line 404
>>> -> 78   }
>>> (lldb)
>>> ```
>>> I know there is no satisfying line number for the call to ~foo, but putting it on a line that may not even get executed feels wrong to me. If necessary, I'd rather associate it with line 0, which is what the standard "no such location" location for the debugger to ignore.
>>
>> That seems kind of awkward if you backtrace through a function with
>> more than one 'foo' object - having the location information would
>> help you know which 'foo' was being destroyed. (though arguably this
>> applies to the cleanup/EH dtor call too - having it attributed to the
>> end of the function is weird too - I'd sort of rather attribute it to
>> the end of its scope but don't know what ramifications that has)
>>
>> Might need to talk to the GDB folks about what GDB does here and/or
>> what the overall DWARF solution should be for both producers and
>> consumers.
>>
>>>
>>> http://reviews.llvm.org/D4956
>>>
>>>
>




More information about the cfe-commits mailing list