Debug shared library code using GDB (Turn)

Source: Internet
Author: User

Original posted Address: http://hi.baidu.com/colin719/blog/item/bd48351fff396ac8a786699e.html

I believe there are a lot of comrades debugging a program that contains shared library code, this time the most headaches is not to do a single step tracking (of course, you do not know how to solve the case ^_^), this article based on an example to tell how to solve this problem. First look at our program, which contains two files: Dyn.c, MAIN.C, where Dyn.c is compiled into a shared library libdyn.so, which is used when linking. One thing you must declare is that your shared library code must be with debugging information (for example, using the-G option).
$cat DYN.C
Dyn ()
{
Puts ("Hello.");
}

$cat MAIN.C
Main ()
{
Puts ("before");
Dyn ();
Puts ("after");
}

$cat Makefile
Main
Gcc-g-save-temps-c Main.c-o MAIN.O
Gcc-g-save-temps-c-fpic-ffunction-sections dyn.c
Gcc-g-save-temps-shared Dyn.o-o libdyn.so
GCC-G-save-temps MAIN.O Libdyn.so-o Main

Clean
RM-RF *.O *.so Main

Here we will compile and debug the program:
$make main This will then generate our libdyn.so and main program in the current directory.
If we enter $./main directly as usual to execute the program, this is not going to work, it will give us the wrong hint:
Before
./main:relocation error:./main:undefined Symbol:dyn
Why. It turns out we used shared libraries libdyn.so didn't tell the dynamic link program where to find him. Well, this time we'll tell it:
$LD _library_path= ' pwd './main
Before
Hello.
After
How about the results we want?
These are some pediatrics, cattle people do not joke ah, the following is to be said. Normally when we use GDB for debugging:
$ gdb-q Main
(GDB) B main
Breakpoint 1 at 0x8048478:file main.c, line 3.
(GDB) R
Starting program:/home/lirui/test/main

Breakpoint 1, Main () at Main.c:3
3 puts ("before");
(GDB) Next
Before
4 dyn ();
(GDB)
/home/lirui/test/main:relocation Error:/home/lirui/test/main:undefined Symbol:dyn

Program exited with code 0177.
(GDB) According to our intention, we want to trace to the dyn () function inside to see some of the drum, but it can not find the corresponding symbolic information, how to do.
Method One: Set the GDB environment variable ld_preload, before executing the program, the shared library code load comes in, can you find it?
$GDB-Q Main
(GDB) Set environment ld_preload./libdyn.so
(GDB) Break dyn
Breakpoint 1 at 0x80483a8
(GDB) Run
Starting program:/home/lirui/test/main
Breakpoint 1 at 0x400176ff:file dyn.c, line 3.
Before

Breakpoint 1, dyn () at Dyn.c:3
3 puts ("Hello.");
(GDB) List
1 dyn ()
2 {
3 puts ("Hello.");
4}
(GDB) This does not find the Dyn () function, so you can be very comfortable debugging it.

Method Two: If you use the GDB version of the "Pending breakpoint" support (V6.3 support), then congratulations, you can set a pending breakpoint, and then have gdb to determine when the breakpoint will work. Here's one thing to note that you have to specify the location of your link library, which can be implemented by setting the environment variable Ld_library_path. Before executing GDB, we can do this: $ export ld_libary_path= ' pwd ', tell GDB to look for shared library files in the current directory, and then debug the program as usual:
$ export ld_library_path= ' pwd '
$ gdb-q Main
The Using host libthread_db the Library "/lib/libthread_db.so.1".
(GDB) b dyn
Function "dyn" not defined.
Make breakpoint pending on future shared library load? (Y or [n]) y
Breakpoint 1 (dyn) pending.
(GDB) R
Starting program:/home/lirui/test/tmp/main
Reading symbols from shared object, read from Target Memory...done.
Loaded system supplied DSO at 0xffffe000
Breakpoint 2 at 0xb7f4853a:file dyn.c, line 3.
Pending breakpoint "dyn" resolved
Before

Breakpoint 2, Dyn () at Dyn.c:3
3 puts ("Hello.");
(GDB) L
1 dyn ()
2 {
3 puts ("Hello.");
4}
(GDB)

Is that okay, ^_^?
Method Three: This situation is only for the program you want to debug the whole is a dynamic link executable program, it in the load to memory, the entry address is dynamic change, if you use GDB for debugging, the initial time you use B function_name words, It sets the breakpoint on offset with 0x0 as the base address, and after the program is load to memory, the base address has changed, so it is always impossible to set a success breakpoint. (I ran into this when I was debugging Qemu). The simplest way is not to compile the program into a reusable, like a normal program to compile it, do not add-wl,-shared for GCC, such as parameters, this time the compilation is very easy to debug.
In response to this situation, I think there should be a way, but I did not test success, is in the use of GDB, the original symbol table load, if the load came in, the use of the Symbol-file command (followed without parameters) to have loaded the symbol table discarded, Then use the add_symbol_file filename start_address command to load the symbol table from filename to the address starting with start_address, and you can debug it. I've experimented with programs that do not apply to shared libraries in this way, because we know that the starting address for a generic program is 0x8048000, but for shared objects, we don't know what the start address is, so it's hard to do, If there's a way to tell us the starting address of its. Text, it's easy to do it this way.

There should be other ways, if you know, please tell me colin719@126.com, thank you.

Another type of makefile is:

. Phony:all Clean

All:main

Main
Gcc-g-C Main.c-o MAIN.O
Gcc-g-c-fpic-ffunction-sections DYN.C
Gcc-g-shared Dyn.o-o libdyn.so
Gcc-g-wl,-rpath./MAIN.O./libdyn.so-o Main

Clean
RM-RF *.O *.so Main

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.