[lldb-dev] [Bug 43421] New: Prologue computation is incorrect for single-line functions compiled by GCC

via lldb-dev lldb-dev at lists.llvm.org
Mon Sep 23 16:28:21 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=43421

            Bug ID: 43421
           Summary: Prologue computation is incorrect for single-line
                    functions compiled by GCC
           Product: lldb
           Version: 6.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: lldb-dev at lists.llvm.org
          Reporter: brettw at gmail.com
                CC: jdevlieghere at apple.com, llvm-bugs at lists.llvm.org

I compiled this function in g++ (Debian 8.3.0-6) 8.3.0 with the command "gcc -g
eraseme.cc":

  #include <stdio.h>

  void PrologueTest() { int a; scanf("%d", &a); printf("Scanned %d\n", a);
    printf("END\n");
  }

  int main(int argc, char **argv) {
    PrologueTest();
    return 0;
  }

GCC doesn't seem to generate DWARF prologue_end annotations, at least in my
version:

  Address            Line   Column File   ISA Discriminator Flags
  ------------------ ------ ------ ------ --- ------------- -------------
  0x0000000000001155      3     21      1   0             0  is_stmt
  0x000000000000115d      3     35      1   0             0  is_stmt
  0x0000000000001175      3     53      1   0             0  is_stmt
  0x000000000000118b      4      9      1   0             0  is_stmt
  0x0000000000001197      5      1      1   0             0  is_stmt
  0x000000000000119a      7     33      1   0             0  is_stmt
  0x00000000000011a9      8     15      1   0             0  is_stmt
  0x00000000000011ae      9     10      1   0             0  is_stmt
  0x00000000000011b3     10      1      1   0             0  is_stmt
  0x00000000000011b5     10      1      1   0             0  is_stmt
end_sequence

If I set a breakpoint on PrologueTest:

  (lldb) b PrologueTest
  Breakpoint 1: where = a.out`PrologueTest() + 54 at eraseme.cc:4, address =
0x000000000000118b

The LLDB code in Function::GetPrologueByteSize() notices there's no prologue
end markers and hits the condition commented:

          // Check the first few instructions and look for one that has a line
          // number that's different than the first entry.

This then slides the breakpoint address to the next line which is line 4. Note
the address above (0x118b) corresponds to the last "puts" call:

  (lldb) disassemble -name PrologueTest
  a.out`PrologueTest:
  a.out[0x1155] <+0>:  pushq  %rbp
  a.out[0x1156] <+1>:  movq   %rsp, %rbp
  a.out[0x1159] <+4>:  subq   $0x10, %rsp
  a.out[0x115d] <+8>:  leaq   -0x4(%rbp), %rax
  a.out[0x1161] <+12>: movq   %rax, %rsi
  a.out[0x1164] <+15>: leaq   0xe99(%rip), %rdi
  a.out[0x116b] <+22>: movl   $0x0, %eax
  a.out[0x1170] <+27>: callq  0x1050                    ; symbol stub for:
scanf
  a.out[0x1175] <+32>: movl   -0x4(%rbp), %eax
  a.out[0x1178] <+35>: movl   %eax, %esi
  a.out[0x117a] <+37>: leaq   0xe86(%rip), %rdi
  a.out[0x1181] <+44>: movl   $0x0, %eax
  a.out[0x1186] <+49>: callq  0x1040                    ; symbol stub for:
printf
  a.out[0x118b] <+54>: leaq   0xe81(%rip), %rdi
  a.out[0x1192] <+61>: callq  0x1030                    ; symbol stub for: puts
  a.out[0x1197] <+66>: nop    
  a.out[0x1198] <+67>: leave  
  a.out[0x1199] <+68>: retq 

This is not what you expect when you set a breakpoint on a function. Running
the program validates this theory.

GDB seems to use the first line table *entry* as the prologue, giving 0x115d as
the address of the breakpoint. This behaves as expected.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20190923/01ec3040/attachment.html>


More information about the lldb-dev mailing list