【问题标题】:kgdb refused to be able to access symbols for just one certain driver, nor do those symbols appear in vmlinuxkgdb 拒绝只能访问某个特定驱动程序的符号,这些符号也不会出现在 vmlinux 中
【发布时间】:2013-10-23 21:06:36
【问题描述】:

我正在尝试调试驱动程序。

gdb 说...
(gdb) 中断 i2c-hid.c:i2c_hid_suspend
没有名为 i2c-hid.c 的源文件。
断点 9 (i2c-hid.c:i2c_hid_suspend) 挂起。

nm vmlinux --- 在该文件中没有找到任何函数名。

cat /proc/kallsyms --- 显示该文件中包含的所有函数名称。

我将此添加到 Makefile "EXTRA_CFLAGS += -DI2C-HID_DEBUG -g" 无济于事。

有谁知道我需要做什么才能让 gdb 能够看到这个文件中的符号?

我得到了许多其他驱动程序的符号级调试。

【问题讨论】:

    标签: linux-kernel linux-device-driver


    【解决方案1】:

    看起来 i2c-hid.c 不是 vmlinux 的一部分,这意味着它在基本内核之外。这就是为什么 nm vmlinux 不显示与该文件相关的符号。

    cat /proc/kallsyms 将显示这些符号,因为它显示了所有内核符号,包括不属于 vmlinux 的驱动程序符号。

    我不确定你使用的是gdb还是kgdb,但我认为要调试驱动程序,你需要使用kgdb,而不是gdb。

    如果您已经在使用 kgdb,请在其下使用 add-symbol-file 命令。它将帮助您加载 vmlinux 之外的符号。简单的谷歌搜索会给你很多add-symbol-file的信息。

    【讨论】:

    • 好的,我想这是一篇关于如何使用 add-symbol-files 的好文章。 freebsd.unixtech.be/doc/en/books/developers-handbook/…。谢谢
    • 顺便说一句,“不是 vmlinux 的一部分”也许最好的措辞是“它是一个可加载的模块”,正确的。 IE。我可以用这个内置模块重新编译内核,然后它的符号将成为 vmlinux 的一部分,对吗?
    • 是的,我自己没试过,但是是的,理论上通过内置模块可以解决你的问题。
    • 毫无疑问你给出了正确的答案,但我的系统似乎还缺少其他东西。我无法获得应有的解析地址。我试过这个: kldstat -- 说没有找到。猫/proc/kallsyms | grep i2c_hid -- 在每个符号旁边显示所有 0000000000。 cat /sys/module/i2c_hid/sections/.text -- 只是一个 0x0000000000000000 我还缺少什么?
    【解决方案2】:

    在调试 Linux 内核时,GDB 不会像为用户模式共享库那样为内核模块自动加载符号。相反,您需要使用以下命令手动加载它们:

    add-symbol-file <kernel module>.o <core address> -s <sectionX> <addressX> -s <...>
    

    您可以通过在do_init_module() 函数中设置断点并在断点被命中后检查mod 变量来找出模块的核心地址(以及所有部分的地址):

    print mod->name
    print mod->module_core
    print *mod->sect_attrs->attrs@mod->sect_attrs->nsections
    

    您可以在Linux kernel symbol overview 中阅读有关加载内核模块符号的更多信息。

    【讨论】:

      猜你喜欢
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多