c-如何在没有共享库的情况下挂接gdb漂亮的打印机



我发现的所有关于编写gdb漂亮打印机的文档基本上都是这个网站:https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002打印机。

它告诉我,当加载共享库时,漂亮的打印机就被加载了。

但我没有共享库,可以说我的库只是头。我想为编程语言Nim的NimStringDesc写一个漂亮的打印机。它编译为C,因此以下是生成到C文件中的所有相关部分。

#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
#  define SEQ_DECL_SIZE /* empty is correct! */
#else
#  define SEQ_DECL_SIZE 1000000
#endif
typedef char NIM_CHAR;
typedef long long int NI64;
typedef NI64 NI;
struct TGenericSeq {NI len; NI reserved; };
struct NimStringDesc {TGenericSeq Sup; NIM_CHAR data[SEQ_DECL_SIZE]; };

以下是我编写的测试程序的加载库:

ldd nim-debug-test
linux-vdso.so.1 (0x00007ffed8052000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f4f1bf8e000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f4f1bbed000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4f1c192000)

所以我不能使用类似/home/user/gdb/nim-gdb.py的东西,因为没有加载的libnim。那么,我该怎么办,无论如何都要加载这个文件?

编辑:

nim创建了几个c文件,然后通过普通的c链接器将这些文件编译并链接在一起。以下是由nim编译器生成的文件:

~/proj/nim-debug-test/nimcache/ ls
nim_debug_test_foobar.c  stdlib_os.o          stdlib_posix.c     stdlib_strutils.o  stdlib_times.c
nim_debug_test_foobar.o  stdlib_parseutils.c  stdlib_posix.o     stdlib_system.c    stdlib_times.o
stdlib_os.c              stdlib_parseutils.o  stdlib_strutils.c  stdlib_system.o

我知道stdlib_system会自动导入到每个nim项目中,所以我可以说,当加载对象文件stdlib_system.o时,它就是一个nim项目。

我有一个gdb-init脚本:

~/gdb/ ls
stdlib_system-gdb.py

但它不会加载。这是stdlib_system-gdb.py的内容:

class NimStringPrinter(object):
    "Print a Nim string"
    def __init__(self, val):
        self.val = val
    def to_string(self):
        return self.val['data']
    def display_hint(self):
        return 'string'
def string_lookup_function(val):
    lookup_tag = val.type.tag
    if lookup_tag == None:
        return None
    regex = re.compile("^NimStringDesc$")
    if regex.match(lookup_tag):
        return StdStringPrinter(val)
    return None
def register_printers(objfile):
    objfile.pretty_printers.append(string_lookup_function)

以下是一些gdb输出:

~/proj/nim_debug_test/ gdb nim_debug_test 
GNU gdb (GDB) 7.11
[...]
Reading symbols from nim_debug_test...done.
(gdb) info auto-load 
gdb-scripts:  No auto-load scripts.
guile-scripts:  No auto-load scripts.
libthread-db:  No auto-loaded libthread-db.
local-gdbinit:  Local .gdbinit file was not found.
python-scripts:  No auto-load scripts.
(gdb) show auto-load
gdb-scripts:  Auto-loading of canned sequences of commands scripts is on.
guile-scripts:  Auto-loading of Guile scripts is on.
libthread-db:  Auto-loading of inferior specific libthread_db is on.
local-gdbinit:  Auto-loading of .gdbinit script from current directory is on.
python-scripts:  Auto-loading of Python scripts is on.
safe-path:  List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load.
scripts-directory:  List of directories from which to load auto-loaded scripts is $debugdir:$datadir/auto-load.
(gdb) info pretty-printer 
global pretty-printers:
  builtin
    mpx_bound128
(gdb) 

问题是,我不知道我做错了什么。

文档实际上应该说objfile。可执行文件和共享库的处理方式完全相同,只是共享库可以是dlopen ed,因此在这种情况下可以稍后调用脚本。

在任何一种情况下,只需创建一个名为$objfile-gdb.py的文件;只要加载objfile,就会执行该代码。该脚本可以,也可以将其中一个调试根预先设置为完整路径(通常为/usr/share/gdb/auto-load/usr/lib/debug)。

请注意,如果一个objfile被加载不止一次(通常是如果您使用run重新启动应用程序-如果dlopen-dlclose-dlopen序列也发生这种情况,我还没有测试),或者如果您使用split debuginfo(因为这是一个单独的objfile,但使用相同的脚本),都会有一些不正确的地方。

我对一个带有自定义__path__的虚拟python包有一些模糊的想法,它在每次执行时都会发生变化,可以解决这个问题。。。

最新更新