162306a36Sopenharmony_ci.. include:: ../disclaimer-zh_CN.rst 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci:Original: :doc:`../../../admin-guide/bug-hunting` 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci:译者: 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci 吴想成 Wu XiangCheng <bobwxc@email.cn> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci追踪缺陷 1062306a36Sopenharmony_ci========= 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci内核错误报告通常附带如下堆栈转储:: 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci ------------[ cut here ]------------ 1562306a36Sopenharmony_ci WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70 1662306a36Sopenharmony_ci 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] 1762306a36Sopenharmony_ci CPU: 1 PID: 28102 Comm: rmmod Tainted: P WC O 4.8.4-build.1 #1 1862306a36Sopenharmony_ci Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009 1962306a36Sopenharmony_ci 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6 2062306a36Sopenharmony_ci c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10 2162306a36Sopenharmony_ci f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617 2262306a36Sopenharmony_ci Call Trace: 2362306a36Sopenharmony_ci [<c12ba080>] ? dump_stack+0x44/0x64 2462306a36Sopenharmony_ci [<c103ed6a>] ? __warn+0xfa/0x120 2562306a36Sopenharmony_ci [<c109e8a7>] ? module_put+0x57/0x70 2662306a36Sopenharmony_ci [<c109e8a7>] ? module_put+0x57/0x70 2762306a36Sopenharmony_ci [<c103ee33>] ? warn_slowpath_null+0x23/0x30 2862306a36Sopenharmony_ci [<c109e8a7>] ? module_put+0x57/0x70 2962306a36Sopenharmony_ci [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk] 3062306a36Sopenharmony_ci [<c109f617>] ? symbol_put_addr+0x27/0x50 3162306a36Sopenharmony_ci [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] 3262306a36Sopenharmony_ci [<f80bb3bf>] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb] 3362306a36Sopenharmony_ci [<c13d03bc>] ? usb_disable_endpoint+0x7c/0xb0 3462306a36Sopenharmony_ci [<f80bb48a>] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb] 3562306a36Sopenharmony_ci [<c13d2882>] ? usb_unbind_interface+0x62/0x250 3662306a36Sopenharmony_ci [<c136b514>] ? __pm_runtime_idle+0x44/0x70 3762306a36Sopenharmony_ci [<c13620d8>] ? __device_release_driver+0x78/0x120 3862306a36Sopenharmony_ci [<c1362907>] ? driver_detach+0x87/0x90 3962306a36Sopenharmony_ci [<c1361c48>] ? bus_remove_driver+0x38/0x90 4062306a36Sopenharmony_ci [<c13d1c18>] ? usb_deregister+0x58/0xb0 4162306a36Sopenharmony_ci [<c109fbb0>] ? SyS_delete_module+0x130/0x1f0 4262306a36Sopenharmony_ci [<c1055654>] ? task_work_run+0x64/0x80 4362306a36Sopenharmony_ci [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90 4462306a36Sopenharmony_ci [<c10013f0>] ? do_fast_syscall_32+0x80/0x130 4562306a36Sopenharmony_ci [<c1549f43>] ? sysenter_past_esp+0x40/0x6a 4662306a36Sopenharmony_ci ---[ end trace 6ebc60ef3981792f ]--- 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci这样的堆栈跟踪提供了足够的信息来识别内核源代码中发生错误的那一行。根据问题的 4962306a36Sopenharmony_ci严重性,它还可能包含 **“Oops”** 一词,比如:: 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci BUG: unable to handle kernel NULL pointer dereference at (null) 5262306a36Sopenharmony_ci IP: [<c06969d4>] iret_exc+0x7d0/0xa59 5362306a36Sopenharmony_ci *pdpt = 000000002258a001 *pde = 0000000000000000 5462306a36Sopenharmony_ci Oops: 0002 [#1] PREEMPT SMP 5562306a36Sopenharmony_ci ... 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci尽管有 **Oops** 或其他类型的堆栈跟踪,但通常需要找到出问题的行来识别和处理缺 5862306a36Sopenharmony_ci陷。在本章中,我们将参考“Oops”来了解需要分析的各种堆栈跟踪。 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci如果内核是用 ``CONFIG_DEBUG_INFO`` 编译的,那么可以使用文件: 6162306a36Sopenharmony_ci`scripts/decode_stacktrace.sh` 。 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci链接的模块 6462306a36Sopenharmony_ci----------- 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci受到污染或正在加载/卸载的模块用“(…)”标记,污染标志在 6762306a36Sopenharmony_ci`Documentation/admin-guide/tainted-kernels.rst` 文件中进行了描述,“正在被加 6862306a36Sopenharmony_ci载”用“+”标注,“正在被卸载”用“-”标注。 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ciOops消息在哪? 7262306a36Sopenharmony_ci--------------- 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci通常,Oops文本由klogd从内核缓冲区读取,然后交给 ``syslogd`` ,后者将其写入 7562306a36Sopenharmony_cisyslog文件,通常是 ``/var/log/messages`` (取决于 ``/etc/syslog.conf`` )。 7662306a36Sopenharmony_ci在使用systemd的系统上,它也可以由 ``journald`` 守护进程存储,并通过运行 7762306a36Sopenharmony_ci``journalctl`` 命令进行访问。 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci有时 ``klogd`` 会挂掉,这种情况下您可以运行 ``dmesg > file`` 从内核缓冲区 8062306a36Sopenharmony_ci读取数据并保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必须适时 8162306a36Sopenharmony_ci中断以停止传输,因为 ``kmsg`` 是一个“永无止境的文件”。 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci如果机器严重崩溃,无法输入命令或磁盘不可用,那还有三个选项: 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci(1) 手动复制屏幕上的文本,并在机器重新启动后输入。很难受,但这是突然崩溃下 8662306a36Sopenharmony_ci 唯一的选择。或者你可以用数码相机拍下屏幕——虽然不那么好,但总比什么都没 8762306a36Sopenharmony_ci 有好。如果消息滚动超出控制台顶部,使用更高分辨率(例如 ``vga=791`` ) 8862306a36Sopenharmony_ci 引导启动将允许您阅读更多文本。(警告:这需要 ``vesafb`` ,因此对“早期” 8962306a36Sopenharmony_ci 的Oppses没有帮助) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci(2) 从串口终端启动(参见 9262306a36Sopenharmony_ci :ref:`Documentation/admin-guide/serial-console.rst <serial_console>` ), 9362306a36Sopenharmony_ci 在另一台机器上运行调制解调器然后用你喜欢的通信程序捕获输出。 9462306a36Sopenharmony_ci Minicom运行良好。 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci(3) 使用Kdump(参阅 Documentation/admin-guide/kdump/kdump.rst ),使用 9762306a36Sopenharmony_ci Documentation/admin-guide/kdump/gdbmacros.txt 中的dmesg gdbmacro从旧内存 9862306a36Sopenharmony_ci 中提取内核环形缓冲区。 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci找到缺陷位置 10162306a36Sopenharmony_ci------------- 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci如果你能指出缺陷在内核源代码中的位置,则报告缺陷的效果会非常好。这有两种方法。 10462306a36Sopenharmony_ci通常来说使用 ``gdb`` 会比较容易,不过内核需要用调试信息来预编译。 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cigdb 10762306a36Sopenharmony_ci^^^^ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ciGNU 调试器(GNU debugger, ``gdb`` )是从 ``vmlinux`` 文件中找出OOPS的确切 11062306a36Sopenharmony_ci文件和行号的最佳方法。 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci在使用 ``CONFIG_DEBUG_INFO`` 编译的内核上使用gdb效果最好。可通过运行以下命令 11362306a36Sopenharmony_ci进行设置:: 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci在用 ``CONFIG_DEBUG_INFO`` 编译的内核上,你可以直接从OOPS复制EIP值:: 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci EIP: 0060:[<c021e50e>] Not tainted VLI 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci并使用GDB来将其翻译成可读形式:: 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci $ gdb vmlinux 12462306a36Sopenharmony_ci (gdb) l *0xc021e50e 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci如果没有启用 ``CONFIG_DEBUG_INFO`` ,则使用OOPS的函数偏移:: 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci EIP is at vt_ioctl+0xda8/0x1482 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci并在启用 ``CONFIG_DEBUG_INFO`` 的情况下重新编译内核:: 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO 13362306a36Sopenharmony_ci $ make vmlinux 13462306a36Sopenharmony_ci $ gdb vmlinux 13562306a36Sopenharmony_ci (gdb) l *vt_ioctl+0xda8 13662306a36Sopenharmony_ci 0x1888 is in vt_ioctl (drivers/tty/vt/vt_ioctl.c:293). 13762306a36Sopenharmony_ci 288 { 13862306a36Sopenharmony_ci 289 struct vc_data *vc = NULL; 13962306a36Sopenharmony_ci 290 int ret = 0; 14062306a36Sopenharmony_ci 291 14162306a36Sopenharmony_ci 292 console_lock(); 14262306a36Sopenharmony_ci 293 if (VT_BUSY(vc_num)) 14362306a36Sopenharmony_ci 294 ret = -EBUSY; 14462306a36Sopenharmony_ci 295 else if (vc_num) 14562306a36Sopenharmony_ci 296 vc = vc_deallocate(vc_num); 14662306a36Sopenharmony_ci 297 console_unlock(); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci或者若您想要更详细的显示:: 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci (gdb) p vt_ioctl 15162306a36Sopenharmony_ci $1 = {int (struct tty_struct *, unsigned int, unsigned long)} 0xae0 <vt_ioctl> 15262306a36Sopenharmony_ci (gdb) l *0xae0+0xda8 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci您也可以使用对象文件作为替代:: 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci $ make drivers/tty/ 15762306a36Sopenharmony_ci $ gdb drivers/tty/vt/vt_ioctl.o 15862306a36Sopenharmony_ci (gdb) l *vt_ioctl+0xda8 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci如果你有调用跟踪,类似:: 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci Call Trace: 16362306a36Sopenharmony_ci [<ffffffff8802c8e9>] :jbd:log_wait_commit+0xa3/0xf5 16462306a36Sopenharmony_ci [<ffffffff810482d9>] autoremove_wake_function+0x0/0x2e 16562306a36Sopenharmony_ci [<ffffffff8802770b>] :jbd:journal_stop+0x1be/0x1ee 16662306a36Sopenharmony_ci ... 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci这表明问题可能在 :jbd: 模块中。您可以在gdb中加载该模块并列出相关代码:: 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci $ gdb fs/jbd/jbd.ko 17162306a36Sopenharmony_ci (gdb) l *log_wait_commit+0xa3 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci.. note:: 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci 您还可以对堆栈跟踪处的任何函数调用执行相同的操作,例如:: 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci 上述调用发生的位置可以通过以下方式看到:: 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci $ gdb drivers/media/usb/dvb-usb/dvb-usb.o 18262306a36Sopenharmony_ci (gdb) l *dvb_usb_adapter_frontend_exit+0x3a 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ciobjdump 18562306a36Sopenharmony_ci^^^^^^^^ 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci要调试内核,请使用objdump并从崩溃输出中查找十六进制偏移,以找到有效的代码/汇 18862306a36Sopenharmony_ci编行。如果没有调试符号,您将看到所示例程的汇编程序代码,但是如果内核有调试 18962306a36Sopenharmony_ci符号,C代码也将可见(调试符号可以在内核配置菜单的hacking项中启用)。例如:: 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci $ objdump -r -S -l --disassemble net/dccp/ipv4.o 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci.. note:: 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci 您需要处于内核树的顶层以便此获得您的C文件。 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci如果您无法访问源代码,仍然可以使用以下方法调试一些崩溃转储(如Dave Miller的 19862306a36Sopenharmony_ci示例崩溃转储输出所示):: 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci EIP is at +0x14/0x4c0 20162306a36Sopenharmony_ci ... 20262306a36Sopenharmony_ci Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00 20362306a36Sopenharmony_ci 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08 20462306a36Sopenharmony_ci <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci Put the bytes into a "foo.s" file like this: 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci .text 20962306a36Sopenharmony_ci .globl foo 21062306a36Sopenharmony_ci foo: 21162306a36Sopenharmony_ci .byte .... /* bytes from Code: part of OOPS dump */ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci Compile it with "gcc -c -o foo.o foo.s" then look at the output of 21462306a36Sopenharmony_ci "objdump --disassemble foo.o". 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci Output: 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci ip_queue_xmit: 21962306a36Sopenharmony_ci push %ebp 22062306a36Sopenharmony_ci push %edi 22162306a36Sopenharmony_ci push %esi 22262306a36Sopenharmony_ci push %ebx 22362306a36Sopenharmony_ci sub $0xbc, %esp 22462306a36Sopenharmony_ci mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb) 22562306a36Sopenharmony_ci mov 0x8(%ebp), %ebx ! %ebx = skb->sk 22662306a36Sopenharmony_ci mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci`scripts/decodecode` 文件可以用来自动完成大部分工作,这取决于正在调试的CPU 22962306a36Sopenharmony_ci体系结构。 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci报告缺陷 23262306a36Sopenharmony_ci--------- 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci一旦你通过定位缺陷找到了其发生的地方,你可以尝试自己修复它或者向上游报告它。 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci为了向上游报告,您应该找出用于开发受影响代码的邮件列表。这可以使用 ``get_maintainer.pl`` 。 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci例如,您在gspca的sonixj.c文件中发现一个缺陷,则可以通过以下方法找到它的维护者:: 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci $ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c 24262306a36Sopenharmony_ci Hans Verkuil <hverkuil@xs4all.nl> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%) 24362306a36Sopenharmony_ci Mauro Carvalho Chehab <mchehab@kernel.org> (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%) 24462306a36Sopenharmony_ci Tejun Heo <tj@kernel.org> (commit_signer:1/1=100%) 24562306a36Sopenharmony_ci Bhaktipriya Shridhar <bhaktipriya96@gmail.com> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%) 24662306a36Sopenharmony_ci linux-media@vger.kernel.org (open list:GSPCA USB WEBCAM DRIVER) 24762306a36Sopenharmony_ci linux-kernel@vger.kernel.org (open list) 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci请注意它将指出: 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci- 最后接触源代码的开发人员(如果这是在git树中完成的)。在上面的例子中是Tejun 25262306a36Sopenharmony_ci 和Bhaktipriya(在这个特定的案例中,没有人真正参与这个文件的开发); 25362306a36Sopenharmony_ci- 驱动维护人员(Hans Verkuil); 25462306a36Sopenharmony_ci- 子系统维护人员(Mauro Carvalho Chehab); 25562306a36Sopenharmony_ci- 驱动程序和/或子系统邮件列表(linux-media@vger.kernel.org); 25662306a36Sopenharmony_ci- Linux内核邮件列表(linux-kernel@vger.kernel.org)。 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci通常,修复缺陷的最快方法是将它报告给用于开发相关代码的邮件列表(linux-media 25962306a36Sopenharmony_ciML),抄送驱动程序维护者(Hans)。 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci如果你完全不知道该把报告寄给谁,且 ``get_maintainer.pl`` 也没有提供任何有用 26262306a36Sopenharmony_ci的信息,请发送到linux-kernel@vger.kernel.org。 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci感谢您的帮助,这使Linux尽可能稳定:-) 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci修复缺陷 26762306a36Sopenharmony_ci--------- 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci如果你懂得编程,你不仅可以通过报告错误来帮助我们,还可以提供一个解决方案。 27062306a36Sopenharmony_ci毕竟,开源就是分享你的工作,你不想因为你的天才而被认可吗? 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci如果你决定这样做,请在制定解决方案后将其提交到上游。 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci请务必阅读 27562306a36Sopenharmony_ci:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` , 27662306a36Sopenharmony_ci以帮助您的代码被接受。 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci--------------------------------------------------------------------------- 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci用 ``klogd`` 进行Oops跟踪的注意事项 28262306a36Sopenharmony_ci------------------------------------ 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci为了帮助Linus和其他内核开发人员, ``klogd`` 对保护故障的处理提供了大量支持。 28562306a36Sopenharmony_ci为了完整支持地址解析,至少应该使用 ``sysklogd`` 包的1.3-pl3版本。 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci当发生保护故障时, ``klogd`` 守护进程会自动将内核日志消息中的重要地址转换为 28862306a36Sopenharmony_ci它们的等效符号。然后通过 ``klogd`` 使用的任何报告机制来转发这个已翻译的内核 28962306a36Sopenharmony_ci消息。保护错误消息可以直接从消息文件中剪切出来并转发给内核开发人员。 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci``klogd`` 执行两种类型的地址解析,静态翻译和动态翻译。静态翻译使用System.map 29262306a36Sopenharmony_ci文件。为了进行静态转换, ``klogd`` 守护进程必须能够在守护进程初始化时找到系 29362306a36Sopenharmony_ci统映射文件。有关 ``klogd`` 如何搜索映射文件的信息,请参见klogd手册页。 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci当使用内核可加载模块时,动态地址转换非常重要。由于内核模块的内存是从内核的 29662306a36Sopenharmony_ci动态内存池中分配的,因此无论是模块的开头还是模块中的函数和符号都没有固定的 29762306a36Sopenharmony_ci位置。 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci内核支持系统调用,允许程序确定加载哪些模块及其在内存中的位置。klogd守护进程 30062306a36Sopenharmony_ci使用这些系统调用构建了一个符号表,可用于调试可加载内核模块中发生的保护错误。 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ciklogd至少会提供产生保护故障的模块的名称。如果可加载模块的开发人员选择从模块 30362306a36Sopenharmony_ci导出符号信息,则可能会有其他可用的符号信息。 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci由于内核模块环境可以是动态的,因此当模块环境发生变化时,必须有一种通知 30662306a36Sopenharmony_ci``klogd`` 守护进程的机制。有一些可用的命令行选项允许klogd向当前正在执行的守 30762306a36Sopenharmony_ci护进程发出信号示意应该刷新符号信息。有关更多信息,请参阅 ``klogd`` 手册页。 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_cisysklogd发行版附带了一个补丁,它修改了 ``modules-2.0.0`` 包,以便在加载或 31062306a36Sopenharmony_ci卸载模块时自动向klogd发送信号。应用此补丁基本上可无缝支持调试内核可加载模块 31162306a36Sopenharmony_ci发生的保护故障。 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci以下是 ``klogd`` 处理的可加载模块中的保护故障示例:: 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc 31662306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 31762306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: *pde = 00000000 31862306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: Oops: 0002 31962306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: CPU: 0 32062306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] 32162306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 32262306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c 32362306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c 32462306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 32562306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) 32662306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 32762306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 32862306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 32962306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] 33062306a36Sopenharmony_ci Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci--------------------------------------------------------------------------- 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci:: 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci Dr. G.W. Wettstein Oncology Research Div. Computing Facility 33762306a36Sopenharmony_ci Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com 33862306a36Sopenharmony_ci 820 4th St. N. 33962306a36Sopenharmony_ci Fargo, ND 58122 34062306a36Sopenharmony_ci Phone: 701-234-7556 341