gdb:在特定库中设置断点

时间:2018-07-06 16:15:56

标签: c gdb shared-libraries dlopen

假设我有一个名为library.c的文件

#include <stdio.h>
void someFunc(int n)
{
    printf("%s: %d\n", LIBNAME, n);
}

我使用不同的宏将其编译成两个共享的对象文件(因此生成的代码是不同的)。在此示例中,我提供了其他LIBNAME:

gcc -DLIBNAME=\"lib1\" -fPIC -shared -g -Og library.c -o library1.so
gcc -DLIBNAME=\"lib2\" -fPIC -shared -g -Og library.c -o library2.so

然后我从可执行文件中加载两个库:

#include <dlfcn.h>
#include <stdio.h>

typedef void (*functype)(int);

int callFunc(const char* libname, int n)
{
    void* lib = dlopen(libname, RTLD_NOW|RTLD_LOCAL);
    if (!lib) {
        fprintf(stderr, "%s\n", dlerror());
        return -1;
    }
    functype func = dlsym(lib, "someFunc");
    if (!func) {
        fprintf(stderr, "%s\n", dlerror());
        dlclose(lib);
        return -1;
    }
    func(n);
    dlclose(lib);
    return 0;
}

int main()
{
    int res = callFunc("./library1.so", 42);
    if (res == 0)
        return callFunc("./library2.so", 13);
    else
        return res;
}

在gdb中,我想从某个库(例如,library1.so)调试功能,而不必担心另一个库(library2.so)。我无法通过函数名称设置断点,因为两个库中的断点相同。我也不能用sourcefile:linenumber来做,因为两个库的源文件都是相同的。如何告诉gdb仅在一个库中设置断点?

2 个答案:

答案 0 :(得分:1)

  

在gdb中,我想从某个库中调试功能(例如   library1.so),而不必担心另一个(library2.so)

您可以在someFunc上设置挂起的断点,如果从library2.so中调用了它,则可以手动忽略它。您可以从info sharedlibrary的输出中了解到这一点:如果从someFunc调用了library2.so,则会加载library2.so,并在info sharedlibrary的输出中看到它。

(gdb) info sharedlibrary 
From                To                  Syms Read   Shared Object Library
0x00007ffff7dd6f60  0x00007ffff7df5030  Yes (*)     /lib64/ld-linux-x86-64.so.2
0x00007ffff7bd2ee0  0x00007ffff7bd3bbe  Yes (*)     /lib64/libdl.so.2
0x00007ffff7834340  0x00007ffff797b27f  Yes (*)     /lib64/libc.so.6
0x00007ffff7611550  0x00007ffff761162c  Yes         ./library2.so
(*): Shared library is missing debugging information.
(gdb) 

看到它已加载时,可以忽略此断点并继续执行。尽管它不是全自动的someFunc调试方式,但在这种情况下,这可能是您最好的选择。

答案 1 :(得分:0)

您为什么不使用“如果...中断”?像

<A, (321, 21)>

如果libname不起作用,您也可以使用第二个参数n。