addr2line Command in Linux with Examples
Use of addr2line Command
The addr2line command is used to convert addresses to line numbers and file names. This command uses debugging info to check which line number and file name are connected with that address.
We use the -e option to specify the relocatable or executable object that is to be used. The file a.out is the default. The -j option clears the section to be used from the relocatable object.
There are two modes of operation for the addr2line command:
In the first mode of operation, on the command line, hexadecimal addresses are identified, and the line address and file name are shown for each address by the addr2line command.
In the second mode, hexadecimal addresses are read by addr2line through standard input, and on standard output, the line number and file name for each address on standard output are printed.
FILENAME: LINENO is the format in which output is displayed.
To generate additional lines before each FILENAME: LINENO line, two options can be used:
- A line is displayed with the input address if the -e option is used.
- And a line is displayed with the FUNCTIONNAME if the -f option is used. This signifies the function storing the address.
And to generate additional lines after the FILENAME: LINENO line, one option can be used:
- If both, the code at the given address is available there due to inclining by the compiler, and the -i option is used, then after the addr2line line, additional lines are displayed. For each inline function, one or two extra lines are printed.
If addr2line fails to determine the function name or the file name, then two marks (??) are displayed in place of them. And addr2line displays 0, if it fails to determine the line number.
The syntax for the addr2line command:
addr2line [options] [addr addr ...]
Some of the options used in the syntax are:
-a --addresses | This option is used to print the address before the file, line number information, and the function name. To identify the address easily, a 0x prefix is printed along with it. |
-b bfdname --target= bfdname | This option shows that bfdname is the object-code format for the object file. |
-C --dmangle[=style] | This option helps in decoding low-level symbol names to user understandable names. Every compiler has itsmangling style. |
-e filename --exe= filename | This option helps in identifying the name of the executable for which addresses will have to be translated. |
-f --functions | This option prints the name of the function along with the line number information and file name. |
-s --basenames | This option prints the base of every file. |
-i --inlines | This option prints all the source information for all enclosing scopes, even the first inlined function; if the address belongs to a function that was inlined. |
-j --section | This option reads the offsets respective to the specified part in place of the complete address. |
-p --pretty-print | This option helps in making the output more user-friendly i.e., on a single line every location is printed. |
@file | This option reads the command-line option from the file. The options read are placed in the place of the @file option. In the file, options are separated by whitespace. |
Note: For the examples, we are going to use the a.out file, which can be obtained after the compilation of the following C program:
#include<stdio.h>
#include<conio.h>
int main()
{
printf("hello \n");
getch();
return 0;
}
We are also going to use the de-assembled code of the a.out executable file. To get the de-assembled code, the following command is used:
objdump -D a.out | grep -A20 main.
Using Options
- -e: This option helps in identifying the name of the executable for which addresses will have to be translated. The addresses from this file will be converted to their line number and file name.
Note: Press ctrl + c, to exit from the addr2line command.
addr2line -e a.out [addr1] [addr2]...
From this, we can deduce that:
- To produce a proper output, the code segment has to be produced with the debug information.
- All offsets of a program are not able to give the correct line number and file name. As we can see in the above image even though 651 is the offset available in the main function, its file name, and line number cannot be tracked.
- -f: This option prints the name of the function along with the line number information and file.
addr2line -e a.out -f [addr1] [addr2] ....
From this example, we can deduce that:
- The line number and file name are printed along with the function name if the line number and file name can be mapped.
- The function name will be printed even if the line number and file name cannot be mapped.
Example:
#include<stdio.h>
#include<conio.h>
int Yolo()
{
return 10;
}
int main()
{
int a,b;
printf("hello \n");
a= Yolo;
b= Yolo;
getch();
return 0;
}
Output:
Note: To display the unassembled part of the Yolo function and the segment following it, the obj command is used along with grep -A20 Yolo.