从上面可以看出,PC的值和ffffff8000ef0058
很接近 。所以,基本可以确定出错的模块是oops_module
。而这个模块正是我自己写的例程 。
接下来,我们就要准备反汇编oops_module.ko
了,根据反汇编可以进一步确认出错的行数 。
aarch64-linux-gnu-objdump-D oops_module.ko> oops_module.dis
oops_module.dis
内容如下
oops_module.ko:file format elf64-littleaarch64Disassembly of section .note.gnu.build-id:0000000000000000 <.note.gnu.build-id>:0:00000004.inst0x00000004 ; undefined4:00000014.inst0x00000014 ; undefined8:00000003.inst0x00000003 ; undefinedc:00554e47.inst0x00554e47 ; undefined10:70d55614adrx20, fffffffffffaaad3 <__UNIQUE_ID_vermagic0+0xfffffffffffaaa9a>14:56a7eb64.inst0x56a7eb64 ; undefined18:a66fbdf8.inst0xa66fbdf8 ; undefined1c:2b31c03fcmnw1, w17, sxtw20:bd9e1ffe.inst0xbd9e1ffe ; undefinedDisassembly of section .text:0000000000000000 <init_module>:0:a9bf7bfdstpx29, x30, [sp, #-16]!4:910003fdmovx29, sp8:aa1e03e0movx0, x30c:94000000bl0 <_mcount>10:58000100ldrx0, 30 <init_module+0x30>14:94000000bl0 <printk>18:d2800000movx0, #0x0// #01c:528102e1movw1, #0x817// #207120:72a32ec1movkw1, #0x1976, lsl #1624:b9000001strw1, [x0]28:a8c17bfdldpx29, x30, [sp], #162c:d65f03c0ret...0000000000000038 <cleanup_module>:38:a9bf7bfdstpx29, x30, [sp, #-16]!3c:910003fdmovx29, sp40:aa1e03e0movx0, x3044:94000000bl0 <_mcount>48:58000080ldrx0, 58 <cleanup_module+0x20>4c:94000000bl0 <printk>50:a8c17bfdldpx29, x30, [sp], #1654:d65f03c0ret...Disassembly of section .modinfo:0000000000000000 <__UNIQUE_ID_license2>:0:6563696cfnmlsz12.h, p2/m, z11.h, z3.h4:3d65736eldrb14, [x27, #2396]8:004c5047.inst0x004c5047 ; undefined
根据反汇编和之前 PC is at init_oopsdemo+0x24/0x38 [oops_module]
,可以确定发生错误的是0x24的位置 。
24:b9000001strw1, [x0] #将w1寄存器的值,传送到地址值为x0的(存储器)内存中
而根据18:d2800000movx0, #0x0// #0
可以确定x0 为0 。
到这里也基本可以确定,是w1的值赋值给0地址时出错了 。
其他方法gdb?oops_module aarch64-linux-gnu-gdb-q ./oops_module.koReading symbols from ./oops_module.ko...done.(gdb) list *init_oopsdemo+0x240x4c is in init_oopsdemo (/home/zhongyi/code/module/oops_module/oops_module.c:10).5MODULE_AUTHOR("ZHONGYI");67staticint init_oopsdemo(void)8{9printk("oops module init! \n");10*((int*)0x00) = 0x19760817;11return 0;12}1314module_init(init_oopsdemo);(gdb)
addr2lineLinux下addr2line命令用于将程序指令地址转换为所对应的函数名、以及函数所在的源文件名和行号 。当含有调试信息(-g)的执行程序出现crash时(core dumped),可使用addr2line命令快速定位出错的位置 。
如果无法确定文件名或函数名,addr2line将在它们的位置打印两个问号;如果无法确定行号,addr2line将打印0或一个问号 。
参数说明:
- -a:在函数名、文件名和行号信息之前,以十六进制形式显示地址 。
- -b:指定目标文件的格式为bfdname 。
- -C:将低级别的符号名解码为用户级别的名字 。
- -e:指定需要转换地址的可执行文件名,默认文件是a.out 。
- -f:在显示文件名、行号信息的同时显示函数名 。
- -s:仅显示每个文件名(the base of each file name)去除目录名 。
- -i:如果需要转换的地址是一个内联函数,则还将打印返回第一个非内联函数的信息 。
- -j:读取指定section的偏移而不是绝对地址 。
- -p:使打印更加人性化:每个地址(location)的信息都打印在一行上 。
- -r:启用或禁用递归量限制 。
- --help:打印帮助信息 。
- --version:打印版本号 。
经验总结扩展阅读
- 青年如何弘扬爱国奋斗精神 成长青春追中国梦的句子简短
- 原神缀叶成章如何完成
- 珐琅锅如何开锅
- 原著知否王老夫人结局如何?
- 蛤蜊当天不吃如何保存
- iphone如何设置自定义铃声(苹果修改自定义手机铃声)
- 如何加微信好友(微信加好友的痕迹查找)
- win7烟雾头怎么调最清楚2021(win7如何调烟雾)
- 大暑如何健脾养胃
- 微信如何添加自己好友(找回添加好友记录)