如何使用kgdb查看完整的回溯以调试ARM Linux模块?

时间:2017-04-08 06:47:29

标签: linux-kernel gdb arm remote-debugging kgdb

我完成了Free Electrons创建的所有免费Linux培训材料。在上一个实验中,我们学习使用kgdb远程调试可加载模块中的简单崩溃。崩溃是由memzero函数调用中的空指针取消引用引起的。

我使用Linux内核4.9和BeagleBone Black作为目标,所有这些都是根据实验室的建议,到目前为止我没有遇到任何问题。我的主机是Ubuntu xenial,我正在使用ARM工具链(Ubuntu / Linaro 5.4.0-6ubuntu1~16.04.4)和gdb(7.11.1-0ubuntu1~16.04)调试器的标准软件包。

gdb能够从vmlinux和模块中读取符号表,其中包含错误,名为drvbroken.ko。该模块的init函数有一个错误,所以当我insmod它时会立即崩溃。

gdb输出:

(gdb) backtrace
#0  __memzero () at arch/arm/lib/memzero.S:69
#1  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) list 69
64      ldmeqfd sp!, {pc}       @ 1/2 quick exit
65  /*
66   * No need to correct the count; we're only testing bits from now on
67   */
68      tst r1, #32         @ 1
69      stmneia r0!, {r2, r3, ip, lr}   @ 4
70      stmneia r0!, {r2, r3, ip, lr}   @ 4
71      tst r1, #16         @ 1 16 bytes or more?
72      stmneia r0!, {r2, r3, ip, lr}   @ 4
73      ldr lr, [sp], #4        @ 1

无论是使用CONFIG_ARM_UNWIND(默认值)构建内核还是禁用它,并使用CONFIG_FRAME_POINTER(实验室笔记推荐的旧方法),结果都是一样的。

我在kdb中尝试了相同的过程,在这里我看到一个包含调用函数的很长的回溯。 memzero的调用者是cdev_init。

kdb输出:

Entering kdb (current=0xde616240, pid 106) on processor 0 Oops: (null)
due to oops @ 0xc04c2be0
CPU: 0 PID: 106 Comm: insmod Tainted: G           O    4.9.0-dirty #1
Hardware name: Generic AM33XX (Flattened Device Tree)
task: de616240 task.stack: de676000
PC is at __memzero+0x40/0x7c
LR is at 0x0
pc : [<c04c2be0>]    lr : [<00000000>]    psr: 00000013
sp : de677da4  ip : 00000000  fp : de677dbc
r10: bf000240  r9 : 219a3868  r8 : 00000000
r7 : de65c7c0  r6 : de6420c0  r5 : bf0000b4  r4 : 00000000
r3 : 00000000  r2 : 00000000  r1 : fffffffc  r0 : 00000000
Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 9e69c019  DAC: 00000051
CPU: 0 PID: 106 Comm: insmod Tainted: G           O    4.9.0-dirty #1
Hardware name: Generic AM33XX (Flattened Device Tree)
Backtrace:

... pruned function calls related to kdb itself ...

[<c08326cc>] (do_page_fault) from [<c010138c>] (do_DataAbort+0x3c/0xbc)
 r10:bf000240 r9:de676000 r8:de677d50 r7:00000000 r6:c08326cc r5:00000817
 r4:c0d0bb2c
[<c0101350>] (do_DataAbort) from [<c0831d04>] (__dabt_svc+0x64/0xa0)
Exception stack(0xde677d50 to 0xde677d98)
7d40:                                     00000000 fffffffc 00000000 00000000
7d60: 00000000 bf0000b4 de6420c0 de65c7c0 00000000 219a3868 bf000240 de677dbc
7d80: 00000000 de677da4 00000000 c04c2be0 00000013 ffffffff
 r8:00000000 r7:de677d84 r6:ffffffff r5:00000013 r4:c04c2be0

[<c02bf44c>] (cdev_init) from [<bf002048>] (init_module+0x48/0xb4 [drvbroken])
 r5:bf002000 r4:bf000480
[<bf002000>] (init_module [drvbroken]) from [<c01018d4>] (do_one_initcall+0x44/0x180)
 r5:bf002000 r4:ffffe000
[<c0101890>] (do_one_initcall) from [<c024fa2c>] (do_init_module+0x64/0x1d8)
 r8:00000001 r7:de65c7c0 r6:de6420c0 r5:c0dbfa84 r4:bf000240
[<c024f9c8>] (do_init_module) from [<c01e10e8>] (load_module+0x1d6c/0x23d8)
 r6:c0d0512c r5:c0dbfa84 r4:c0d4c70f
[<c01df37c>] (load_module) from [<c01e18ac>] (SyS_init_module+0x158/0x17c)
 r10:00000051 r9:de676000 r8:e0a95100 r7:00000000 r6:000ac118 r5:00004100

很容易找出使用此信息查找错误的位置,但唉,不可能直接从kdb获取行号或列出源代码。假设我可以获得完整的回溯,这在gdb中要容易得多。

0 个答案:

没有答案