Yes. It is.
There are two solutions to this question.
I going to explain the first solution in this post. The other solution I will explain in the next post.
You can load debuging information from an debug enabled version of executable file.
In order to better explain the first solution, I will setup my sample environment as follows:
- released.c: source code of the program we wish to debug (listing 1).
- ~/estudo/: Source code of our program will be put here.
- ~/local/bin: The stripped off version of binary program will stay here.
- ~/local/symbols: In this place are all files that contain debuging information.
#include <stdio.h> #include <stdlib.h> int division(int a, int b); int m; int main(void) { int i; int j; printf("vou setar i\n"); i = 10; printf("vou setar j\n"); j = 1; printf ("i = %d, j = %d\n", i, j); m = division(i, j); printf("m = %d / %d = %d\n", i, j, m); return 0; } int division(int a, int b) { return a / b; }
Listing 1 - sample program source code
I have two versions of the program: with and without debuging information.
1 - You compile your program with debug information. In our sample:
gcc -Wall -g -release release.c <ENTER>
2 - You make a copy of your program. In our sample:
cp release release.full <ENTER>
3 - You strip off debuging information:
strip -s release <ENTER>
As you can see on Figure 1, we have two programs. released.full has debuging symbols but release doesn't have them.
4 - Move file release to ~/local/bin/:
mv release ~/local/bin <ENTER>
5 - Move file released.full to ~/local/symbols/
mv release.full ~/local/symbols <ENTER>
6 - Go to directory ~/local/bin
cd ~/local/bin <ENTER>
7 - Run GDB:
gdb ./release <ENTER>
8 - Try list command to see that release executable file doesn't have symbols in it.
Note: if the program was already running you could get its PID then attach GDB to it.
Figure 2 shows us two windows. The first one shows that our executable file has no debug information. In the other window we can see that release is not yet loaded.
9 - Let GDB to load symbols from executable file named release.full. This binary version of our program has all symbols that we need to debug.
Please notice that GDB will not replace the release executable by release.full version of our program. It will just import symbols from release.full into release debugging session.
But GDB needs to know in advance where it must put the symbols it will load. How can you determine the correct memory address?
It is quite simple. You issue command maint inside GDB:
maint info sections
Then you look for .text section. The address that is in the first column is what you want. In our sample, it is 0x08048320. See figure 3.
10 - The next step is to instruct GDB to load debug symbols into .text section. To achieve it you do this:
add-symbol-file ~/local/symbols/release.full <.text section address>
In our sample it means to type:
add-symbol-file ~/local/symbols/release.full 0x08048320
From now on you can debug your program as usual.
Figure 4 shows us that debugging symbols where imported successfully and that now the list command (abbreviated as l) shows us the program source code.
As you can see in figure 5, I set a break point at line 17 and I ran the program that stopped there. Then I printed i variable.
In the other terminal I issued ps command. It was done just to show you that the only program running was release executable. There is no instance of release.full program.
I hope this post will make your life easier. In the next time I will teach you another way to import debugging symbols.
6 comentários:
Awesome post, Márcio! Besides explaining the whole thing, now we have a step-by-step guide for real life use.
I've found rather flexible the way GDB loads debug information into a loaded process, asking for the address. It seems even more flexible than WinDbg way.
Congratulations, and thank you =)
[]s
Muito bom. Thank you very much.
http://stackoverflow.com/questions/5089829/offset-of-shared-libries-on-android - I am looking for information how to get offset without root privileges. Can anyone help?
How would you do the same for a shared library?
How would you do the same for a shared library? I have a program that dlopens a share library, which in turn loads other shared libraries. One of these don't contain debug symbols, and I'd like to load them manually.
@runeks the same procedure should work, but you need the library version with full symbols to import them.
Postar um comentário