1*b1b381e2SWu XiangCheng.. include:: ../disclaimer-zh_CN.rst 2*b1b381e2SWu XiangCheng 3*b1b381e2SWu XiangCheng:Original: :doc:`../../../admin-guide/bug-hunting` 4*b1b381e2SWu XiangCheng 5*b1b381e2SWu XiangCheng:译者: 6*b1b381e2SWu XiangCheng 7*b1b381e2SWu XiangCheng 吴想成 Wu XiangCheng <bobwxc@email.cn> 8*b1b381e2SWu XiangCheng 9*b1b381e2SWu XiangCheng追踪缺陷 10*b1b381e2SWu XiangCheng========= 11*b1b381e2SWu XiangCheng 12*b1b381e2SWu XiangCheng内核错误报告通常附带如下堆栈转储:: 13*b1b381e2SWu XiangCheng 14*b1b381e2SWu XiangCheng ------------[ cut here ]------------ 15*b1b381e2SWu XiangCheng WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70 16*b1b381e2SWu XiangCheng 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] 17*b1b381e2SWu XiangCheng CPU: 1 PID: 28102 Comm: rmmod Tainted: P WC O 4.8.4-build.1 #1 18*b1b381e2SWu XiangCheng Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009 19*b1b381e2SWu XiangCheng 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6 20*b1b381e2SWu XiangCheng c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10 21*b1b381e2SWu XiangCheng f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617 22*b1b381e2SWu XiangCheng Call Trace: 23*b1b381e2SWu XiangCheng [<c12ba080>] ? dump_stack+0x44/0x64 24*b1b381e2SWu XiangCheng [<c103ed6a>] ? __warn+0xfa/0x120 25*b1b381e2SWu XiangCheng [<c109e8a7>] ? module_put+0x57/0x70 26*b1b381e2SWu XiangCheng [<c109e8a7>] ? module_put+0x57/0x70 27*b1b381e2SWu XiangCheng [<c103ee33>] ? warn_slowpath_null+0x23/0x30 28*b1b381e2SWu XiangCheng [<c109e8a7>] ? module_put+0x57/0x70 29*b1b381e2SWu XiangCheng [<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk] 30*b1b381e2SWu XiangCheng [<c109f617>] ? symbol_put_addr+0x27/0x50 31*b1b381e2SWu XiangCheng [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] 32*b1b381e2SWu XiangCheng [<f80bb3bf>] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb] 33*b1b381e2SWu XiangCheng [<c13d03bc>] ? usb_disable_endpoint+0x7c/0xb0 34*b1b381e2SWu XiangCheng [<f80bb48a>] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb] 35*b1b381e2SWu XiangCheng [<c13d2882>] ? usb_unbind_interface+0x62/0x250 36*b1b381e2SWu XiangCheng [<c136b514>] ? __pm_runtime_idle+0x44/0x70 37*b1b381e2SWu XiangCheng [<c13620d8>] ? __device_release_driver+0x78/0x120 38*b1b381e2SWu XiangCheng [<c1362907>] ? driver_detach+0x87/0x90 39*b1b381e2SWu XiangCheng [<c1361c48>] ? bus_remove_driver+0x38/0x90 40*b1b381e2SWu XiangCheng [<c13d1c18>] ? usb_deregister+0x58/0xb0 41*b1b381e2SWu XiangCheng [<c109fbb0>] ? SyS_delete_module+0x130/0x1f0 42*b1b381e2SWu XiangCheng [<c1055654>] ? task_work_run+0x64/0x80 43*b1b381e2SWu XiangCheng [<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90 44*b1b381e2SWu XiangCheng [<c10013f0>] ? do_fast_syscall_32+0x80/0x130 45*b1b381e2SWu XiangCheng [<c1549f43>] ? sysenter_past_esp+0x40/0x6a 46*b1b381e2SWu XiangCheng ---[ end trace 6ebc60ef3981792f ]--- 47*b1b381e2SWu XiangCheng 48*b1b381e2SWu XiangCheng这样的堆栈跟踪提供了足够的信息来识别内核源代码中发生错误的那一行。根据问题的 49*b1b381e2SWu XiangCheng严重性,它还可能包含 **“Oops”** 一词,比如:: 50*b1b381e2SWu XiangCheng 51*b1b381e2SWu XiangCheng BUG: unable to handle kernel NULL pointer dereference at (null) 52*b1b381e2SWu XiangCheng IP: [<c06969d4>] iret_exc+0x7d0/0xa59 53*b1b381e2SWu XiangCheng *pdpt = 000000002258a001 *pde = 0000000000000000 54*b1b381e2SWu XiangCheng Oops: 0002 [#1] PREEMPT SMP 55*b1b381e2SWu XiangCheng ... 56*b1b381e2SWu XiangCheng 57*b1b381e2SWu XiangCheng尽管有 **Oops** 或其他类型的堆栈跟踪,但通常需要找到出问题的行来识别和处理缺 58*b1b381e2SWu XiangCheng陷。在本章中,我们将参考“Oops”来了解需要分析的各种堆栈跟踪。 59*b1b381e2SWu XiangCheng 60*b1b381e2SWu XiangCheng如果内核是用 ``CONFIG_DEBUG_INFO`` 编译的,那么可以使用文件: 61*b1b381e2SWu XiangCheng`scripts/decode_stacktrace.sh` 。 62*b1b381e2SWu XiangCheng 63*b1b381e2SWu XiangCheng链接的模块 64*b1b381e2SWu XiangCheng----------- 65*b1b381e2SWu XiangCheng 66*b1b381e2SWu XiangCheng受到污染或正在加载/卸载的模块用“(…)”标记,污染标志在 67*b1b381e2SWu XiangCheng`Documentation/admin-guide/tainted-kernels.rst` 文件中进行了描述,“正在被加 68*b1b381e2SWu XiangCheng载”用“+”标注,“正在被卸载”用“-”标注。 69*b1b381e2SWu XiangCheng 70*b1b381e2SWu XiangCheng 71*b1b381e2SWu XiangChengOops消息在哪? 72*b1b381e2SWu XiangCheng--------------- 73*b1b381e2SWu XiangCheng 74*b1b381e2SWu XiangCheng通常,Oops文本由klogd从内核缓冲区读取,然后交给 ``syslogd`` ,后者将其写入 75*b1b381e2SWu XiangChengsyslog文件,通常是 ``/var/log/messages`` (取决于 ``/etc/syslog.conf`` )。 76*b1b381e2SWu XiangCheng在使用systemd的系统上,它也可以由 ``journald`` 守护进程存储,并通过运行 77*b1b381e2SWu XiangCheng``journalctl`` 命令进行访问。 78*b1b381e2SWu XiangCheng 79*b1b381e2SWu XiangCheng有时 ``klogd`` 会挂掉,这种情况下您可以运行 ``dmesg > file`` 从内核缓冲区 80*b1b381e2SWu XiangCheng读取数据并保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必须适时 81*b1b381e2SWu XiangCheng中断以停止传输,因为 ``kmsg`` 是一个“永无止境的文件”。 82*b1b381e2SWu XiangCheng 83*b1b381e2SWu XiangCheng如果机器严重崩溃,无法输入命令或磁盘不可用,那还有三个选项: 84*b1b381e2SWu XiangCheng 85*b1b381e2SWu XiangCheng(1) 手动复制屏幕上的文本,并在机器重新启动后输入。很难受,但这是突然崩溃下 86*b1b381e2SWu XiangCheng 唯一的选择。或者你可以用数码相机拍下屏幕——虽然不那么好,但总比什么都没 87*b1b381e2SWu XiangCheng 有好。如果消息滚动超出控制台顶部,使用更高分辨率(例如 ``vga=791`` ) 88*b1b381e2SWu XiangCheng 引导启动将允许您阅读更多文本。(警告:这需要 ``vesafb`` ,因此对“早期” 89*b1b381e2SWu XiangCheng 的Oppses没有帮助) 90*b1b381e2SWu XiangCheng 91*b1b381e2SWu XiangCheng(2) 从串口终端启动(参见 92*b1b381e2SWu XiangCheng :ref:`Documentation/admin-guide/serial-console.rst <serial_console>` ), 93*b1b381e2SWu XiangCheng 在另一台机器上运行调制解调器然后用你喜欢的通信程序捕获输出。 94*b1b381e2SWu XiangCheng Minicom运行良好。 95*b1b381e2SWu XiangCheng 96*b1b381e2SWu XiangCheng(3) 使用Kdump(参阅 Documentation/admin-guide/kdump/kdump.rst ),使用 97*b1b381e2SWu XiangCheng Documentation/admin-guide/kdump/gdbmacros.txt 中的dmesg gdbmacro从旧内存 98*b1b381e2SWu XiangCheng 中提取内核环形缓冲区。 99*b1b381e2SWu XiangCheng 100*b1b381e2SWu XiangCheng找到缺陷位置 101*b1b381e2SWu XiangCheng------------- 102*b1b381e2SWu XiangCheng 103*b1b381e2SWu XiangCheng如果你能指出缺陷在内核源代码中的位置,则报告缺陷的效果会非常好。这有两种方法。 104*b1b381e2SWu XiangCheng通常来说使用 ``gdb`` 会比较容易,不过内核需要用调试信息来预编译。 105*b1b381e2SWu XiangCheng 106*b1b381e2SWu XiangChenggdb 107*b1b381e2SWu XiangCheng^^^^ 108*b1b381e2SWu XiangCheng 109*b1b381e2SWu XiangChengGNU 调试器(GNU debugger, ``gdb`` )是从 ``vmlinux`` 文件中找出OOPS的确切 110*b1b381e2SWu XiangCheng文件和行号的最佳方法。 111*b1b381e2SWu XiangCheng 112*b1b381e2SWu XiangCheng在使用 ``CONFIG_DEBUG_INFO`` 编译的内核上使用gdb效果最好。可通过运行以下命令 113*b1b381e2SWu XiangCheng进行设置:: 114*b1b381e2SWu XiangCheng 115*b1b381e2SWu XiangCheng $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO 116*b1b381e2SWu XiangCheng 117*b1b381e2SWu XiangCheng在用 ``CONFIG_DEBUG_INFO`` 编译的内核上,你可以直接从OOPS复制EIP值:: 118*b1b381e2SWu XiangCheng 119*b1b381e2SWu XiangCheng EIP: 0060:[<c021e50e>] Not tainted VLI 120*b1b381e2SWu XiangCheng 121*b1b381e2SWu XiangCheng并使用GDB来将其翻译成可读形式:: 122*b1b381e2SWu XiangCheng 123*b1b381e2SWu XiangCheng $ gdb vmlinux 124*b1b381e2SWu XiangCheng (gdb) l *0xc021e50e 125*b1b381e2SWu XiangCheng 126*b1b381e2SWu XiangCheng如果没有启用 ``CONFIG_DEBUG_INFO`` ,则使用OOPS的函数偏移:: 127*b1b381e2SWu XiangCheng 128*b1b381e2SWu XiangCheng EIP is at vt_ioctl+0xda8/0x1482 129*b1b381e2SWu XiangCheng 130*b1b381e2SWu XiangCheng并在启用 ``CONFIG_DEBUG_INFO`` 的情况下重新编译内核:: 131*b1b381e2SWu XiangCheng 132*b1b381e2SWu XiangCheng $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO 133*b1b381e2SWu XiangCheng $ make vmlinux 134*b1b381e2SWu XiangCheng $ gdb vmlinux 135*b1b381e2SWu XiangCheng (gdb) l *vt_ioctl+0xda8 136*b1b381e2SWu XiangCheng 0x1888 is in vt_ioctl (drivers/tty/vt/vt_ioctl.c:293). 137*b1b381e2SWu XiangCheng 288 { 138*b1b381e2SWu XiangCheng 289 struct vc_data *vc = NULL; 139*b1b381e2SWu XiangCheng 290 int ret = 0; 140*b1b381e2SWu XiangCheng 291 141*b1b381e2SWu XiangCheng 292 console_lock(); 142*b1b381e2SWu XiangCheng 293 if (VT_BUSY(vc_num)) 143*b1b381e2SWu XiangCheng 294 ret = -EBUSY; 144*b1b381e2SWu XiangCheng 295 else if (vc_num) 145*b1b381e2SWu XiangCheng 296 vc = vc_deallocate(vc_num); 146*b1b381e2SWu XiangCheng 297 console_unlock(); 147*b1b381e2SWu XiangCheng 148*b1b381e2SWu XiangCheng或者若您想要更详细的显示:: 149*b1b381e2SWu XiangCheng 150*b1b381e2SWu XiangCheng (gdb) p vt_ioctl 151*b1b381e2SWu XiangCheng $1 = {int (struct tty_struct *, unsigned int, unsigned long)} 0xae0 <vt_ioctl> 152*b1b381e2SWu XiangCheng (gdb) l *0xae0+0xda8 153*b1b381e2SWu XiangCheng 154*b1b381e2SWu XiangCheng您也可以使用对象文件作为替代:: 155*b1b381e2SWu XiangCheng 156*b1b381e2SWu XiangCheng $ make drivers/tty/ 157*b1b381e2SWu XiangCheng $ gdb drivers/tty/vt/vt_ioctl.o 158*b1b381e2SWu XiangCheng (gdb) l *vt_ioctl+0xda8 159*b1b381e2SWu XiangCheng 160*b1b381e2SWu XiangCheng如果你有调用跟踪,类似:: 161*b1b381e2SWu XiangCheng 162*b1b381e2SWu XiangCheng Call Trace: 163*b1b381e2SWu XiangCheng [<ffffffff8802c8e9>] :jbd:log_wait_commit+0xa3/0xf5 164*b1b381e2SWu XiangCheng [<ffffffff810482d9>] autoremove_wake_function+0x0/0x2e 165*b1b381e2SWu XiangCheng [<ffffffff8802770b>] :jbd:journal_stop+0x1be/0x1ee 166*b1b381e2SWu XiangCheng ... 167*b1b381e2SWu XiangCheng 168*b1b381e2SWu XiangCheng这表明问题可能在 :jbd: 模块中。您可以在gdb中加载该模块并列出相关代码:: 169*b1b381e2SWu XiangCheng 170*b1b381e2SWu XiangCheng $ gdb fs/jbd/jbd.ko 171*b1b381e2SWu XiangCheng (gdb) l *log_wait_commit+0xa3 172*b1b381e2SWu XiangCheng 173*b1b381e2SWu XiangCheng.. note:: 174*b1b381e2SWu XiangCheng 175*b1b381e2SWu XiangCheng 您还可以对堆栈跟踪处的任何函数调用执行相同的操作,例如:: 176*b1b381e2SWu XiangCheng 177*b1b381e2SWu XiangCheng [<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] 178*b1b381e2SWu XiangCheng 179*b1b381e2SWu XiangCheng 上述调用发生的位置可以通过以下方式看到:: 180*b1b381e2SWu XiangCheng 181*b1b381e2SWu XiangCheng $ gdb drivers/media/usb/dvb-usb/dvb-usb.o 182*b1b381e2SWu XiangCheng (gdb) l *dvb_usb_adapter_frontend_exit+0x3a 183*b1b381e2SWu XiangCheng 184*b1b381e2SWu XiangChengobjdump 185*b1b381e2SWu XiangCheng^^^^^^^^ 186*b1b381e2SWu XiangCheng 187*b1b381e2SWu XiangCheng要调试内核,请使用objdump并从崩溃输出中查找十六进制偏移,以找到有效的代码/汇 188*b1b381e2SWu XiangCheng编行。如果没有调试符号,您将看到所示例程的汇编程序代码,但是如果内核有调试 189*b1b381e2SWu XiangCheng符号,C代码也将可见(调试符号可以在内核配置菜单的hacking项中启用)。例如:: 190*b1b381e2SWu XiangCheng 191*b1b381e2SWu XiangCheng $ objdump -r -S -l --disassemble net/dccp/ipv4.o 192*b1b381e2SWu XiangCheng 193*b1b381e2SWu XiangCheng.. note:: 194*b1b381e2SWu XiangCheng 195*b1b381e2SWu XiangCheng 您需要处于内核树的顶层以便此获得您的C文件。 196*b1b381e2SWu XiangCheng 197*b1b381e2SWu XiangCheng如果您无法访问源代码,仍然可以使用以下方法调试一些崩溃转储(如Dave Miller的 198*b1b381e2SWu XiangCheng示例崩溃转储输出所示):: 199*b1b381e2SWu XiangCheng 200*b1b381e2SWu XiangCheng EIP is at +0x14/0x4c0 201*b1b381e2SWu XiangCheng ... 202*b1b381e2SWu XiangCheng Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00 203*b1b381e2SWu XiangCheng 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08 204*b1b381e2SWu XiangCheng <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85 205*b1b381e2SWu XiangCheng 206*b1b381e2SWu XiangCheng Put the bytes into a "foo.s" file like this: 207*b1b381e2SWu XiangCheng 208*b1b381e2SWu XiangCheng .text 209*b1b381e2SWu XiangCheng .globl foo 210*b1b381e2SWu XiangCheng foo: 211*b1b381e2SWu XiangCheng .byte .... /* bytes from Code: part of OOPS dump */ 212*b1b381e2SWu XiangCheng 213*b1b381e2SWu XiangCheng Compile it with "gcc -c -o foo.o foo.s" then look at the output of 214*b1b381e2SWu XiangCheng "objdump --disassemble foo.o". 215*b1b381e2SWu XiangCheng 216*b1b381e2SWu XiangCheng Output: 217*b1b381e2SWu XiangCheng 218*b1b381e2SWu XiangCheng ip_queue_xmit: 219*b1b381e2SWu XiangCheng push %ebp 220*b1b381e2SWu XiangCheng push %edi 221*b1b381e2SWu XiangCheng push %esi 222*b1b381e2SWu XiangCheng push %ebx 223*b1b381e2SWu XiangCheng sub $0xbc, %esp 224*b1b381e2SWu XiangCheng mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb) 225*b1b381e2SWu XiangCheng mov 0x8(%ebp), %ebx ! %ebx = skb->sk 226*b1b381e2SWu XiangCheng mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt 227*b1b381e2SWu XiangCheng 228*b1b381e2SWu XiangCheng`scripts/decodecode` 文件可以用来自动完成大部分工作,这取决于正在调试的CPU 229*b1b381e2SWu XiangCheng体系结构。 230*b1b381e2SWu XiangCheng 231*b1b381e2SWu XiangCheng报告缺陷 232*b1b381e2SWu XiangCheng--------- 233*b1b381e2SWu XiangCheng 234*b1b381e2SWu XiangCheng一旦你通过定位缺陷找到了其发生的地方,你可以尝试自己修复它或者向上游报告它。 235*b1b381e2SWu XiangCheng 236*b1b381e2SWu XiangCheng为了向上游报告,您应该找出用于开发受影响代码的邮件列表。这可以使用 ``get_maintainer.pl`` 。 237*b1b381e2SWu XiangCheng 238*b1b381e2SWu XiangCheng 239*b1b381e2SWu XiangCheng例如,您在gspca的sonixj.c文件中发现一个缺陷,则可以通过以下方法找到它的维护者:: 240*b1b381e2SWu XiangCheng 241*b1b381e2SWu XiangCheng $ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c 242*b1b381e2SWu XiangCheng Hans Verkuil <hverkuil@xs4all.nl> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%) 243*b1b381e2SWu XiangCheng Mauro Carvalho Chehab <mchehab@kernel.org> (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%) 244*b1b381e2SWu XiangCheng Tejun Heo <tj@kernel.org> (commit_signer:1/1=100%) 245*b1b381e2SWu XiangCheng Bhaktipriya Shridhar <bhaktipriya96@gmail.com> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%) 246*b1b381e2SWu XiangCheng linux-media@vger.kernel.org (open list:GSPCA USB WEBCAM DRIVER) 247*b1b381e2SWu XiangCheng linux-kernel@vger.kernel.org (open list) 248*b1b381e2SWu XiangCheng 249*b1b381e2SWu XiangCheng请注意它将指出: 250*b1b381e2SWu XiangCheng 251*b1b381e2SWu XiangCheng- 最后接触源代码的开发人员(如果这是在git树中完成的)。在上面的例子中是Tejun 252*b1b381e2SWu XiangCheng 和Bhaktipriya(在这个特定的案例中,没有人真正参与这个文件的开发); 253*b1b381e2SWu XiangCheng- 驱动维护人员(Hans Verkuil); 254*b1b381e2SWu XiangCheng- 子系统维护人员(Mauro Carvalho Chehab); 255*b1b381e2SWu XiangCheng- 驱动程序和/或子系统邮件列表(linux-media@vger.kernel.org); 256*b1b381e2SWu XiangCheng- Linux内核邮件列表(linux-kernel@vger.kernel.org)。 257*b1b381e2SWu XiangCheng 258*b1b381e2SWu XiangCheng通常,修复缺陷的最快方法是将它报告给用于开发相关代码的邮件列表(linux-media 259*b1b381e2SWu XiangChengML),抄送驱动程序维护者(Hans)。 260*b1b381e2SWu XiangCheng 261*b1b381e2SWu XiangCheng如果你完全不知道该把报告寄给谁,且 ``get_maintainer.pl`` 也没有提供任何有用 262*b1b381e2SWu XiangCheng的信息,请发送到linux-kernel@vger.kernel.org。 263*b1b381e2SWu XiangCheng 264*b1b381e2SWu XiangCheng感谢您的帮助,这使Linux尽可能稳定:-) 265*b1b381e2SWu XiangCheng 266*b1b381e2SWu XiangCheng修复缺陷 267*b1b381e2SWu XiangCheng--------- 268*b1b381e2SWu XiangCheng 269*b1b381e2SWu XiangCheng如果你懂得编程,你不仅可以通过报告错误来帮助我们,还可以提供一个解决方案。 270*b1b381e2SWu XiangCheng毕竟,开源就是分享你的工作,你不想因为你的天才而被认可吗? 271*b1b381e2SWu XiangCheng 272*b1b381e2SWu XiangCheng如果你决定这样做,请在制定解决方案后将其提交到上游。 273*b1b381e2SWu XiangCheng 274*b1b381e2SWu XiangCheng请务必阅读 275*b1b381e2SWu XiangCheng:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` , 276*b1b381e2SWu XiangCheng以帮助您的代码被接受。 277*b1b381e2SWu XiangCheng 278*b1b381e2SWu XiangCheng 279*b1b381e2SWu XiangCheng--------------------------------------------------------------------------- 280*b1b381e2SWu XiangCheng 281*b1b381e2SWu XiangCheng用 ``klogd`` 进行Oops跟踪的注意事项 282*b1b381e2SWu XiangCheng------------------------------------ 283*b1b381e2SWu XiangCheng 284*b1b381e2SWu XiangCheng为了帮助Linus和其他内核开发人员, ``klogd`` 对保护故障的处理提供了大量支持。 285*b1b381e2SWu XiangCheng为了完整支持地址解析,至少应该使用 ``sysklogd`` 包的1.3-pl3版本。 286*b1b381e2SWu XiangCheng 287*b1b381e2SWu XiangCheng当发生保护故障时, ``klogd`` 守护进程会自动将内核日志消息中的重要地址转换为 288*b1b381e2SWu XiangCheng它们的等效符号。然后通过 ``klogd`` 使用的任何报告机制来转发这个已翻译的内核 289*b1b381e2SWu XiangCheng消息。保护错误消息可以直接从消息文件中剪切出来并转发给内核开发人员。 290*b1b381e2SWu XiangCheng 291*b1b381e2SWu XiangCheng``klogd`` 执行两种类型的地址解析,静态翻译和动态翻译。静态翻译使用System.map 292*b1b381e2SWu XiangCheng文件。为了进行静态转换, ``klogd`` 守护进程必须能够在守护进程初始化时找到系 293*b1b381e2SWu XiangCheng统映射文件。有关 ``klogd`` 如何搜索映射文件的信息,请参见klogd手册页。 294*b1b381e2SWu XiangCheng 295*b1b381e2SWu XiangCheng当使用内核可加载模块时,动态地址转换非常重要。由于内核模块的内存是从内核的 296*b1b381e2SWu XiangCheng动态内存池中分配的,因此无论是模块的开头还是模块中的函数和符号都没有固定的 297*b1b381e2SWu XiangCheng位置。 298*b1b381e2SWu XiangCheng 299*b1b381e2SWu XiangCheng内核支持系统调用,允许程序确定加载哪些模块及其在内存中的位置。klogd守护进程 300*b1b381e2SWu XiangCheng使用这些系统调用构建了一个符号表,可用于调试可加载内核模块中发生的保护错误。 301*b1b381e2SWu XiangCheng 302*b1b381e2SWu XiangChengklogd至少会提供产生保护故障的模块的名称。如果可加载模块的开发人员选择从模块 303*b1b381e2SWu XiangCheng导出符号信息,则可能会有其他可用的符号信息。 304*b1b381e2SWu XiangCheng 305*b1b381e2SWu XiangCheng由于内核模块环境可以是动态的,因此当模块环境发生变化时,必须有一种通知 306*b1b381e2SWu XiangCheng``klogd`` 守护进程的机制。有一些可用的命令行选项允许klogd向当前正在执行的守 307*b1b381e2SWu XiangCheng护进程发出信号示意应该刷新符号信息。有关更多信息,请参阅 ``klogd`` 手册页。 308*b1b381e2SWu XiangCheng 309*b1b381e2SWu XiangChengsysklogd发行版附带了一个补丁,它修改了 ``modules-2.0.0`` 包,以便在加载或 310*b1b381e2SWu XiangCheng卸载模块时自动向klogd发送信号。应用此补丁基本上可无缝支持调试内核可加载模块 311*b1b381e2SWu XiangCheng发生的保护故障。 312*b1b381e2SWu XiangCheng 313*b1b381e2SWu XiangCheng以下是 ``klogd`` 处理的可加载模块中的保护故障示例:: 314*b1b381e2SWu XiangCheng 315*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc 316*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 317*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: *pde = 00000000 318*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: Oops: 0002 319*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: CPU: 0 320*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] 321*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 322*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c 323*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c 324*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 325*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) 326*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 327*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 328*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 329*b1b381e2SWu XiangCheng Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] 330*b1b381e2SWu XiangCheng 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 331*b1b381e2SWu XiangCheng 332*b1b381e2SWu XiangCheng--------------------------------------------------------------------------- 333*b1b381e2SWu XiangCheng 334*b1b381e2SWu XiangCheng:: 335*b1b381e2SWu XiangCheng 336*b1b381e2SWu XiangCheng Dr. G.W. Wettstein Oncology Research Div. Computing Facility 337*b1b381e2SWu XiangCheng Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com 338*b1b381e2SWu XiangCheng 820 4th St. N. 339*b1b381e2SWu XiangCheng Fargo, ND 58122 340*b1b381e2SWu XiangCheng Phone: 701-234-7556 341