[PATCH] D49426: [DEBUG_INFO] fix .loc directives emitted for missing prologues

Tom Weaver via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 9 08:40:22 PST 2019


TWeaver added a comment.

  > So GAS does the same thing as Clang's integrated assembler currently (pre-patch) and that behavior is problematic for GDB and LLDB?
  
  GAS has the same behaviour as Clang's integrated assembler. When an assembly file with multiple .loc directives with no interveaning instructions are assembled, GAS produces a DWARF line table that maps one instruction to multiple entries.
  
  Commit r184357 copied this behaviour from GAS/GCC to Clang. Before this commit Clang would only produce a line table entry for the last .loc directive read for a particular instruction.
  
  This behaviour is not problematic for LLDB or GDB, having tested both debuggers and single stepped through the disassembly, source and set break points on the "troublesome" lines that correspond to the line entries, both LLDB and GDB handle the issue gracefully by stepping to the line corresponding to first bit of user code.
  
  I've tried this with and without a prologue_end flag and both GDB and LLDB handle this case fine.
  
  > (only for LLDB) so this difference is that the assembly clang generates includes these zero-address-length locations, but GCC doesn't?
  
  GCC and Clang share the same behaviour. Both produce .loc directives and subsequent line table entries for missing prologues and user code that map to the same assembly instruction.
  
  0 // simple.cpp
  1 #include "basic.h"
  2 int main(int argc, const char * argv[])
  3 {
  4   int result = basic(argc);
  5   return result;
  6 }
  
  0 // basic.cpp
  1 int basic(const int arg)
  2 {
  3   int result = arg + arg;
  4   return result;
  5 }
  
  Then the following line table dumps for both clang and gcc builds:
  
  Clang bleeding edge with -O2 -g -fno-inline:
  > snipped
  <pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
  0x00400480  [   3, 0] NS uri: "/home/clangbox/dev/temp/./simple.cpp"
  0x00400483  [   4,16] NS PE
  0x00400488  [   5,17] NS
  > snipped
  
  > snipped
  <pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
  0x00400490  [   2, 0] NS uri: "/home/clangbox/dev/temp/./basic.cpp"
  0x00400490  [   4,17] NS PE
  0x00400493  [   4, 3]
  > snipped
  
  GCC version 7.3.0 on Ubuntu 1~18.04 with -O2 -g -fno-inline:
  > snipped
  <pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
  0x000004f0  [   3, 0] NS uri: "/home/clangbox/dev/temp/simple.cpp"
  0x000004f1  [   3, 0] NS
  0x000004f3  [   4, 0] NS
  > snipped
  
  > snipped
  <pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
  0x00000610  [   2, 0] NS uri: "/home/clangbox/dev/temp/basic.cpp"
  0x00000610  [   4, 0] NS
  0x00000613  [   5, 0] NS
  > snipped
  
  > What's the problematic cases/behaviour in the debuggers or other DWARF consumer's?
  
  as stated above, GDB and LLDB both handle this case, line table entries for missing prologue, gracefully. I've tested several ways of stepping and setting break points and both debuggers always manage to figure out that the instruction with 2 mappings is, in fact, mapped to the first line of source, not the curly brace denoted by the prologue line entry.
  
  However, our internal debugger, on the example above, when stepping into basic.cpp pauses on the curly brace at line 2, then skips over the expression on line 3 straight to the return value. Giving the user a "wonky" optimized debugging experience.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D49426/new/

https://reviews.llvm.org/D49426





More information about the llvm-commits mailing list