步入共享库的条件应该在gdb中工作?

有很多与特定错误相关的问题,为什么用gdb进入共享库不起作用。 他们都没有提供有关如何确定原因的系统答案。 这个问题是关于如何诊断设置。

设置示例

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"); } 

将所有文件放在同一个目录中。

 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 

获取错误

 $ 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不是在function里面踩的

必要但不足够的检查

debugging二进制文件中的符号

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

由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 

确认.gdbinit不是原因

~/.gdbinit包含启动gdb时自动执行的命令。 REF。

使用-nx标志运行gdb可以排除.gdbinit作为问题的根源。

我正在寻找build议,以完成Necessary but not sufficient checks清单。

当前问题[Mark Plotnick更新]

这个步骤错误在Ubuntu 17.04 amd64上是可重现的,包括64位和32位可执行文件和库。

这个bug在Ubuntu 17.04 i386上是不可重现的。 (gcc 6.3.0-12ubuntu2,gdb 7.12.50和8.0,没有.gdbinit。)。

可能有关:17.04 amd64上的gcc已经被build立(由Canonical)来默认生成可执行文件。

可以用gcc编译的标志干扰debugging吗? 你如何确定你的gcc是否是原因?

Solutions Collecting From Web of "步入共享库的条件应该在gdb中工作?"

您的问题是自我强制的:不要这样做: set step-mode onstep将按照您的预期工作。

从GDB 手册 :

 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. 

你有兴趣在上面的对面 – 你想进入 print_from_lib函数,并避免停在PLT跳转存根和动态加载器的符号解析函数。

可以在构建的共享库上进行一些更多的测试:

  1. file libmyshared-ggdb.so应报告该库有调试信息,而不是剥离。
  2. nm libmyshared-ggdb.so | grep print_from_lib nm libmyshared-ggdb.so | grep print_from_lib应该找到print_from_lib函数的符号。

如果上面的所有测试都通过gdb直接加载库并找到这个函数:

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

应该打印函数print_from_lib名字。 如果没有,gdb或gcc有问题。

GDB 7.11不能重现这个问题。 这是我的步骤。 我希望这能帮到您:

 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 

在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) 

我成功进入了print_from_lib函数。