Debug linux kernel

內核錯誤報告通常附帶如下堆棧轉儲:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70
Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core]
CPU: 1 PID: 28102 Comm: rmmod Tainted: P        WC O 4.8.4-build.1 #1
Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6
 c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10
 f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617
Call Trace:
 [<c12ba080>] ? dump_stack+0x44/0x64
 [<c103ed6a>] ? __warn+0xfa/0x120
 [<c109e8a7>] ? module_put+0x57/0x70
 [<c109e8a7>] ? module_put+0x57/0x70
 [<c103ee33>] ? warn_slowpath_null+0x23/0x30
 [<c109e8a7>] ? module_put+0x57/0x70
 [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk]
 [<c109f617>] ? symbol_put_addr+0x27/0x50
 [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]
 [<f80bb3bf>] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb]
 [<c13d03bc>] ? usb_disable_endpoint+0x7c/0xb0
 [<f80bb48a>] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb]
 [<c13d2882>] ? usb_unbind_interface+0x62/0x250
 [<c136b514>] ? __pm_runtime_idle+0x44/0x70
 [<c13620d8>] ? __device_release_driver+0x78/0x120
 [<c1362907>] ? driver_detach+0x87/0x90
 [<c1361c48>] ? bus_remove_driver+0x38/0x90
 [<c13d1c18>] ? usb_deregister+0x58/0xb0
 [<c109fbb0>] ? SyS_delete_module+0x130/0x1f0
 [<c1055654>] ? task_work_run+0x64/0x80
 [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
 [<c10013f0>] ? do_fast_syscall_32+0x80/0x130
 [<c1549f43>] ? sysenter_past_esp+0x40/0x6a
---[ end trace 6ebc60ef3981792f ]---

這樣的堆棧跟蹤提供了足夠的信息來識別內核源代碼中發生錯誤的那一行。根據問題的 嚴重性,它還可能包含 “Oops” 一詞,比如:

BUG: unable to handle kernel NULL pointer dereference at   (null)
IP: [<c06969d4>] iret_exc+0x7d0/0xa59
*pdpt = 000000002258a001 *pde = 0000000000000000
Oops: 0002 [#1] PREEMPT SMP
...

儘管有 Oops 或其他類型的堆棧跟蹤,但通常需要找到出問題的行來識別和處理缺 陷。在本章中,我們將參考“Oops”來了解需要分析的各種堆棧跟蹤。

如果內核是用 CONFIG_DEBUG_INFO 編譯的,那麼可以使用文件: 

### Linux 内核中使用 debugfs 进行调试的方法 在 Linux 内核开发驱动调试过程中,`debugfs` 提供了一种轻量级的文件系统接口,使得开发者能够通过用户空间访问内核变量或执行特定操作,而无需实现完整的字符设备驱动。与传统的字符设备相比,`debugfs` 简化了注册流程,仅需实现一个 `file_operations` 结构体,并调用相应的创建函数即可[^1]。 #### 创建 debugfs 文件目录 为了组织 `debugfs` 中的调试条目,可以先创建一个目录,再在该目录下添加具体的调试文件节点。例如: ```c struct dentry *pcie_dir; pcie_dir = debugfs_create_dir("pcie", NULL); if (pcie_dir != NULL) { debugfs_create_u32("pcie0_linked", 0644, pcie_dir, &pcie0_linked); } ``` 这段代码展示了如何创建名为 `pcie` 的目录,并在其下创建一个用于读写 `u32` 类型变量的文件节点 `pcie0_linked`。类似地,也可以直接在根目录下创建文件节点,而不必嵌套在子目录中[^4]。 #### 实现 file_operations 操作 每个 `debugfs` 文件节点都对应一组操作函数,通常包括 `read`, `write`, `open`, `release` 等。这些函数通过 `file_operations` 结构体注册到内核中。例如,以下是一个简单的读写实现: ```c static ssize_t my_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { // 实现从内核空间复制数据到用户空间 } static ssize_t my_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { // 实现从用户空间复制数据到内核空间 } static const struct file_operations fops = { .owner = THIS_MODULE, .read = my_read, .write = my_write, }; struct dentry *entry = debugfs_create_file("my_debug", 0644, NULL, NULL, &fops); ``` 上述示例中的 `my_read` `my_write` 函数分别用于处理对 `/sys/kernel/debug/my_debug` 文件的读写请求。尽管某些实现中可能并未使用 `open` 回调函数,但仍然可以通过 `filp->private_data` 来传递上下文信息[^5]。 #### 删除 debugfs 节点 当模块卸载时,应及时清理所创建的 `debugfs` 文件节点以避免资源泄漏。对于单个文件节点,可使用 `debugfs_remove()`;若需递归删除整个目录及其内容,则应调用 `debugfs_remove_recursive()`: ```c debugfs_remove(entry); // 删除单个文件节点 debugfs_remove_recursive(dir); // 递归删除目录及其中所有文件 ``` 这种方式确保了即使存在多个相关联的调试节点,也能一次性安全清除,防止后续加载时出现冲突[^3]。 #### 用户空间访问 debugfs 文件 一旦模块加载成功并在内核中注册了 `debugfs` 节点,用户空间程序便可通过标准 I/O 接口(如 `open()`, `read()`, `write()`)对其进行访问。例如: ```bash cat /sys/kernel/debug/my_debug echo "test" > /sys/kernel/debug/my_debug ``` 此类操作会触发内核中对应的 `read` 或 `write` 回调函数,从而实现双向通信。此外,还可以结合工具链(如 `gdb` 或专用脚本)进一步增强调试能力。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值