Wednesday, August 2, 2017

Conditions under which stepping into shared library should work in gdb?

Leave a Comment

There are many questions related to specific errors why stepping into a shared library with gdb isn't working. None of them provide a systematic answer on how to confirm where the the cause is. This questions is about the ways to diagnose the setup.

Setup example

main.c

#include <stdio.h> #include "myshared.h"  int main(void) {     int a = 3;     print_from_lib();     return 0; } 

myshared.h

void print_from_lib(); 

myshared.c

#include <stdio.h>  void print_from_lib() {     printf("Printed from shared library\n"); } 

Place all the files in the same directory.

export LIBRARY_PATH=$PWD:$LIBRARY_PATH export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH gcc -ggdb -c -Wall -Werror -fpic myshared.c -o myshared-ggdb.o gcc -ggdb -shared -o libmyshared-ggdb.so myshared-ggdb.o gcc -ggdb main.c -lmyshared-ggdb -o app-ggdb 

Getting the error

$ gdb ./app-ggdb  GNU gdb (Ubuntu 7.12.50.20170314-0ubuntu1) 7.12.50.20170314-git ...### GDB STARTING TEXT Reading symbols from app-ggdb...done. (gdb) break 7 Breakpoint 1 at 0x78f: file main.c, line 7. (gdb) run Starting program: /home/user/share-lib-example/app-ggdb   Breakpoint 1, main () at main.c:7 7       print_from_lib(); (gdb) s Printed from shared library 8       return 0; 

gdb is not stepping inside of the function

Necessary but not sufficient checks

Debug symbols in the binaries

$ objdump --syms libmyshared-ggdb.so | grep debug 0000000000000000 l    d  .debug_aranges 0000000000000000              .debug_aranges 0000000000000000 l    d  .debug_info    0000000000000000              .debug_info 0000000000000000 l    d  .debug_abbrev  0000000000000000              .debug_abbrev 0000000000000000 l    d  .debug_line    0000000000000000              .debug_line 0000000000000000 l    d  .debug_str     0000000000000000              .debug_str 

Symbols recognized by gdb

$ gdb ./app-ggdb ...### GDB STARTING TEXT Reading symbols from app-ggdb...done. (gdb) break 7 Breakpoint 1 at 0x78f: file main.c, line 7. (gdb) run Starting program: /home/user/share-lib-example/app-ggdb   Breakpoint 1, main () at main.c:7 7       print_from_lib(); (gdb)(gdb) info sharedlibrary From                To                  Syms Read   Shared Object Library 0x00007ffff7dd7aa0  0x00007ffff7df55c0  Yes         /lib64/ld-linux-x86-64.so.2 0x00007ffff7bd5580  0x00007ffff7bd5693  Yes         /home/user/share-lib-example/libmyshared-ggdb.so 0x00007ffff782d9c0  0x00007ffff797ed43  Yes         /lib/x86_64-linux-gnu/libc.so.6 

Confirm .gdbinit isn't the cause

~/.gdbinit contains commands automatically executed upon starting gdb. ref.

Running gdb with the -nx flags can exclude .gdbinit as the source of the problem.

Question

Am looking for suggestions to complete the list of Necessary but not sufficient checks.

Update

The exact same steps seem to work in normal debug for user haolee. See answer below.

3 Answers

Answers 1

Your problem is self-imposed: don't do this: set step-mode on, and step will work as you expect.

From the GDB manual:

set step-mode set step-mode on The set step-mode on command causes the step command to stop at the first instruction of a function which contains no debug line information rather than stepping over it.  This is useful in cases where you may be interested in inspecting the machine instructions of a function which has no symbolic info and do not want GDB to automatically skip over this function. 

You are interested in the opposite of the above -- you want to step into the print_from_lib function and avoid stopping inside the PLT jump stub and the dynamic loader's symbol resolution function.

Answers 2

GDB 7.11 can't reproduce this problem. This is my steps. I hope this will help you:

1.gcc -ggdb -c -Wall -Werror -fpic myshared.c -o myshared-ggdb.o 2.gcc -ggdb -shared -o libmyshared-ggdb.so myshared-ggdb.o 3.gcc -ggdb main.c -lmyshared-ggdb -o app-ggdb -L. 4.gdb ./app-ggdb 

In GDB,

(gdb) set env LD_LIBRARY_PATH=. (gdb) b main.c:7 Breakpoint 1 at 0x4006a5: file main.c, line 7. (gdb) r Starting program: /home/haolee/tmp/app-ggdb   Breakpoint 1, main () at main.c:7 7       print_from_lib(); (gdb) s print_from_lib () at myshared.c:5 5       printf("Printed from shared library\n"); (gdb)  

I step into the function print_from_lib successfully.

Answers 3

Some more tests you can do on built shared library:

  1. file libmyshared-ggdb.so should report that library has debug info and not stripped.
  2. nm libmyshared-ggdb.so | grep print_from_lib should find the symbol for print_from_lib function.

If all above tests passed try to load the library directly in gdb and find the function:

gdb libmyshared-ggdb.so (gdb) info functions print_from_lib 

Function print_from_lib name should be printed. If not, something is wrong with gdb or gcc.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment