Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

Current issue [Update from Mark Plotnick]

This step bug is reproducible on Ubuntu 17.04 amd64 with both a 64- and 32-bit executable and library.

The bug isn't reproducible on Ubuntu 17.04 i386. (gcc 6.3.0-12ubuntu2, gdb 7.12.50 and 8.0, no .gdbinit.).

Possibly relevant: gcc on 17.04 amd64 has been built (by Canonical) to generate pie executables by default.

Question

Can flags with which gcc was build with interfere with debugging? How can you identify if your gcc is the cause?

like image 953
TheMeaningfulEngineer Avatar asked Jul 23 '17 22:07

TheMeaningfulEngineer


People also ask

What is the purpose of using shared libraries?

Shared Libraries are the libraries that can be linked to any program at run-time. They provide a means to use code that can be loaded anywhere in the memory. Once loaded, the shared library code can be used by any number of programs.

What is the need of GDB How can debugging be done using GDB?

Gdb is a debugger for C (and C++). It allows you to do things like run the program up to a certain point then stop and print out the values of certain variables at that point, or step through the program one line at a time and print out the values of each variable after executing each line.

What is the GDB command that will show the address of the next instruction to execute when the current function reaches its one return statement?

It is often useful to do ' display/i $pc ' when stepping by machine instructions. This makes GDB automatically display the next instruction to be executed, each time your program stops.

How do I enable GDB?

Go to your Linux command prompt and type “gdb”. Gdb open prompt lets you know that it is ready for commands. To exit out of gdb, type quit or q.


1 Answers

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.

like image 200
Employed Russian Avatar answered Oct 21 '22 05:10

Employed Russian