title: Wrong line numbers from addr2line
body: <p>I try to find the exact line of a call in the backtrace in C++ program. Right now I am using these lines (from the man page of backtrace) to get the trace:</p>
  
  <pre><code>  void *bt_buffer[1000];
    char **bt_strings;
    int bt_nptrs = backtrace(bt_buffer, 1000);
    bt_strings = backtrace_symbols(bt_buffer, bt_nptrs);
  </code></pre>
  
  <p>In bt_strings I find lines of the form </p>
  
  <pre><code>./prog() [0x402e42]
  </code></pre>
  
  <p>Now I take the address (the hex string) and feed it to addr2line. That sometimes results in apparently wrong line numbers. Internet search led me to this <a href="http://lists.gnu.org/archive/html/bug-binutils/2006-08/msg00043.html" rel="noreferrer">post</a>, in which it is shown that </p>
  
  <pre><code>readelf -wl ./prog
  </code></pre>
  
  <p>indicates where the line <em>really</em> is, or rather how many lines the symbol has moved to the current line.</p>
  
  <p><strong>edit:</strong> This happens when I compile with <code>-g -O0</code>, i.e. explicetly without optimisations. The compiler is <code>gcc 4.6.3</code> Is there another compiler flag that I miss?</p>
  
  <p>My problem is the following: I need to automate this. I need my program to create a backtrace (done), extract the file (done) and the line number (fail).</p>
  
  <p>I could of course call <code>readelf</code> and parse the output, but that's not really suitable, as the output differs from symbol to symbol depending on what exactly happened. Sometimes The address of a symbol is in one line and the information about the line offset in the next line...</p>
  
  <p>To sum up:</p>
  
  <p><strong>Is there an elegant way to get the exact line number of a function call in the backtrace from within the program during runtime?</strong></p>
  
  <p><strong>edit:</strong> example code:</p>
  
  <pre><code>#define UNW_LOCAL_ONLY
  #include &lt;libunwind.h&gt;
  #include &lt;execinfo.h&gt;
  #include &lt;iostream&gt;
  #include &lt;stdlib.h&gt;
  
  void show_backtrace()
  {
    // get current address
    void* p = __builtin_return_address(0);
    std::cout &lt;&lt; std::hex &lt;&lt; p &lt;&lt; std::endl;
  
    // get callee addresses
    p = __builtin_return_address(1);
    std::cout &lt;&lt; std::hex &lt;&lt; p &lt;&lt; std::endl;
  
    p = __builtin_return_address(2);
    std::cout &lt;&lt; std::hex &lt;&lt; p &lt;&lt; std::endl;
  }
  
  void show_backtrace2()
  {
    void *array[10];
    size_t size;
    char **strings;
    int i;
  
    size = backtrace (array, 10);
    strings = backtrace_symbols ((void *const *)array, size);
  
    for (i = 0; i &lt; size; i++)
      {
        std::cout &lt;&lt; strings[i] &lt;&lt; std::endl;
      }
  
    free (strings);
  }
  
  void show_backtrace3 (void)
  {
    char name[256];
    unw_cursor_t cursor; unw_context_t uc;
    unw_word_t ip, sp, offp;
  
    unw_getcontext (&amp;uc);
    unw_init_local (&amp;cursor, &amp;uc);
  
    while (unw_step(&amp;cursor) &gt; 0)
      {
        char file[256];
        int line = 0;
  
        name[0] = '\0';
        unw_get_proc_name (&amp;cursor, name, 256, &amp;offp);
        unw_get_reg (&amp;cursor, UNW_REG_IP, &amp;ip);
        unw_get_reg (&amp;cursor, UNW_REG_SP, &amp;sp);
  
        std::cout &lt;&lt; std:: hex &lt;&lt; name &lt;&lt; " ip = " &lt;&lt; (long) ip 
                  &lt;&lt; " , sp = " &lt;&lt; (long) sp &lt;&lt; std::endl;
      }
  }
  
  void dummy_function2()
  {
    show_backtrace();
    show_backtrace2();
    show_backtrace3();
  }
  
  void dummy_function1()
  { 
    dummy_function2 (); 
  } // line 73
  
  int main(int argc, char **argv)
  {
    dummy_function1 ();
    return 0;
  }
  </code></pre>
  
  <p>compile and run:</p>
  
  <pre><code>g++ test_unwind.cc -g -O0 -lunwind  &amp;&amp; ./a.out
  </code></pre>
  
  <p>output:</p>
  
  <pre><code>0x400edb
  0x400ef0
  0x400f06
  ./a.out() [0x400cfb]
  ./a.out() [0x400ee0]
  ./a.out() [0x400ef0]
  ./a.out() [0x400f06]
  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f2f044ae76d]
  ./a.out() [0x400b79]
  _Z15dummy_function2v ip = 400ee5 , sp = 7fffdb564580
  _Z15dummy_function1v ip = 400ef0 , sp = 7fffdb564590
  main ip = 400f06 , sp = 7fffdb5645a0
  __libc_start_main ip = 7f2f044ae76d , sp = 7fffdb5645c0
  _start ip = 400b79 , sp = 7fffdb564680
  </code></pre>
  
  <p>testing e.g. 0x400ef0 with addr2line yields</p>
  
  <pre><code>/path/to/code/test_unwind.cc:73
  </code></pre>
  
  <p>which is the correct file, but wrong line number. In real life applications the line number can differ by many lines, forward and backward.</p>
  
  <p><strong>edit:</strong> compiling with <code>-S</code> shows that the relevant part is:</p>
  
  <pre><code>.LCFI34:
    .cfi_def_cfa_register 6
    .loc 2 72 0
    call  _Z15dummy_function2v
    .loc 2 73 0
    popq  %rbp
  </code></pre>
  
  <p>What is displayed by <code>addr2line</code> and alike is the return address, as shown in the line after the <code>call</code>. I would like to get the "entry" line, i.e. what is shown before!</p>