How to use the addr2line command in Linux?
Asked Answered
M

4

64

I am trying to use addr2line command in Unix but everytime it is giving the same output as ??:0. I am giving command as addr2line -e a.out 0x4005BDC . I got this address while running this a.out executable with valgrind tool to find the memory leakage. I also compiled the source code with -g option.

Metrify answered 4/10, 2011 at 13:28 Comment(0)
S
41

You can also use gdb instead of addr2line to examine memory address. Load executable file in gdb and print the name of a symbol which is stored at the address. 16 Examining the Symbol Table.

(gdb) info symbol 0x4005BDC 
Spencerspencerian answered 4/10, 2011 at 13:45 Comment(3)
Good idea. Also running the program in gdb with a breakpoint at that address and getting the backtrace could give good information about what exactly is happening there.Dimension
See also (gdb) info line * 0x4005BDCEquidistant
The (library) code address would be the same or different, between compiling with "-g" flag and without the flag ?Zooid
F
33

You need to specify an offset to addr2line, not a virtual address (VA). Presumably if you had address space randomization turned off, you could use a full VA, but in most modern OSes, address spaces are randomized for a new process.

Given the VA 0x4005BDC by valgrind, find the base address of your process or library in memory. Do this by examining the /proc/<PID>/maps file while your program is running. The line of interest is the text segment of your process, which is identifiable by the permissions r-xp and the name of your program or library.

Let's say that the base VA is 0x0x4005000. Then you would find the difference between the valgrind supplied VA and the base VA: 0xbdc. Then, supply that to add2line:

addr2line -e a.out -j .text 0xbdc

And see if that gets you your line number.

Florri answered 4/10, 2011 at 15:35 Comment(3)
wait, what offsets ? Isn't addr2line just takes addresses from symtab (or dyntab) ?Merganser
I got the correct addresses by subtracting the start of the very first range in the map file, which had permissions r--p. And in my case at least there was an offset even with ALSR off.Monostrophe
Also worth noting that within the process itself you can use /proc/self/mapsMonostrophe
D
16

That's exactly how you use it. There is a possibility that the address you have does not correspond to something directly in your source code though.

For example:

$ cat t.c
#include <stdio.h>
int main()
{
    printf("hello\n");
    return 0;
}
$ gcc -g t.c
$ addr2line -e a.out 0x400534
/tmp/t.c:3
$ addr2line -e a.out 0x400550
??:0

0x400534 is the address of main in my case. 0x400408 is also a valid function address in a.out, but it's a piece of code generated/imported by GCC, that has no debug info. (In this case, __libc_csu_init. You can see the layout of your executable with readelf -a your_exe.)

Other times when addr2line will fail is if you're including a library that has no debug information.

Dimension answered 4/10, 2011 at 13:40 Comment(1)
In my code I am using pthread and libconfing library. I don't know these libraries has debug info or not.Metrify
Y
13

Try adding the -f option to show the function names :

addr2line -f -e a.out 0x4005BDC
Yesima answered 24/4, 2015 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.