步入共享库的条件应该在gdb中运行?

时间:2017-07-23 22:48:20

标签: c linux debugging gdb

有很多与特定错误相关的问题,为什么单独使用gdb进入共享库是行不通的。他们都没有就如何确定原因在哪里提供系统的答案。这个问题是关于诊断设置的方法。

设置示例

的main.c

fan_count

myshared.h

#include <stdio.h>
#include "myshared.h"

int main(void)
{
    int a = 3;
    print_from_lib();
    return 0;
}

myshared.c

void print_from_lib();

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

#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没有踩到函数内部

必要但不充分的检查

二进制文件中的调试符号

$ 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识别的符号

$ 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

确认.gdbinit不是原因

$ 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 包含启动gdb时自动执行的命令。 ref.

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

问题

我正在寻找完成.gdbinit列表的建议。

当前问题[Mark Plotnick更新]

此步骤错误在Ubuntu 17.04 amd64上可重现,同时具有64位和32位可执行文件和库。

该错误在Ubuntu 17.04 i386上无法重现。 (gcc 6.3.0-12ubuntu2,gdb 7.12.50和8.0,没有.gdbinit。)。

可能相关:默认情况下,已经构建了17.04 amd64的gcc(由Canonical制作)以生成饼形可执行文件。

问题

构建gcc的标志是否会干扰调试?你怎么能确定你的gcc是否是原因?

3 个答案:

答案 0 :(得分:6)

您的问题是自我强加的:请勿执行此操作:set step-mode onstep将按预期工作。

来自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.

您对以上反面感兴趣 - 您希望将转入 print_from_lib函数并避免在PLT跳转存根内停止动态加载器的符号解析功能。

答案 1 :(得分:5)

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

答案 2 :(得分:4)

您可以对构建的共享库执行更多测试:

  1. file libmyshared-ggdb.so应报告该库具有调试信息且未剥离。
  2. nm libmyshared-ggdb.so | grep print_from_lib应找到print_from_lib函数的符号。
  3. 如果所有上述测试都通过,请尝试直接在gdb中加载库并找到函数:

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

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