<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Prologue computation is incorrect for single-line functions compiled by GCC"
   href="https://bugs.llvm.org/show_bug.cgi?id=43421">43421</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Prologue computation is incorrect for single-line functions compiled by GCC
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lldb
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>6.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>lldb-dev@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>brettw@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>jdevlieghere@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>