内核模块上的 addr2line [英] addr2line on kernel module

查看:41
本文介绍了内核模块上的 addr2line的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调试内核模块.我怀疑有一些内存泄漏.为了检查它,我已经为内核和模块准备了启用内存泄漏调试的构建.我从中得到了一些警告:

I'm trying to debug kernel module. I suspect to have there some memory leaks. To check it I have prepared build with enabled Memory leak debugging for kernel and modules. And I got some warning from that:

[11839.429168] slab error in verify_redzone_free(): cache `size-64': memory outside object was overwritten
[11839.438659] [<c005575c>] (unwind_backtrace+0x0/0x164) from [<c0116ca0>] (kfree+0x278/0x4d8)
[11839.447357] [<c0116ca0>] (kfree+0x278/0x4d8) from [<bf083f48>] (some_function+0x18/0x1c [my_module])
[11839.457214] [<bf083f48>] (some_function+0x18/0x1c [my_module]) from [<bf08762c>] (some_function+0x174/0x718 [my_module])
[11839.470184] [<bf08762c>] (some_function+0x174/0x718 [my_module]) from [<bf0a56b8>] (some_function+0x12c/0x16c [my_module])
[11839.483917] [<bf0a56b8>] (some_function+0x12c/0x16c [my_module]) from [<bf085790>] (some_function+0x8/0x10 [my_module])
[11839.496368] [<bf085790>] (some_function+0x8/0x10 [my_module]) from [<bf07b74c>] (some_function+0x358/0x6d4 [my_module])
[11839.507476] [<bf07b74c>] (some_function+0x358/0x6d4 [my_module]) from [<c00a60f8>] (worker_thread+0x1e8/0x284)
[11839.517211] [<c00a60f8>] (worker_thread+0x1e8/0x284) from [<c00a9edc>] (kthread+0x78/0x80)
[11839.525543] [<c00a9edc>] (kthread+0x78/0x80) from [<c004f8fc>] (kernel_thread_exit+0x0/0x8)

转换指向内核的地址没有问题:

There is no problem to translate addresses which points to kernel:

$ addr2line -f -e vmlinux.kmeml c0116ca0
verify_redzone_free
/[...]/kernel/mm/slab.c:2922

但如果地址来自 my_module,我就不能这样做:

But I can't do that if addresses are from my_module:

$ addr2line -f -e vmlinux.kmeml bf0a56b8
??
??:0

我也在尝试使用模块文件:

I was also trying with module file:

$ addr2line -f -e my_module.ko bf0a56b8
??
??:0

如何将此地址转换为文件和行号?

How can I translate this addresses to files and line numbers?

推荐答案

我想该模块是在包含调试信息的情况下构建的.如果是这样,您可以使用 gdb 或 objdump 找出每个地址属于哪个源文件和行.像这样:

I suppose the module is built with debug info included. If so, you can use gdb or objdump to find out which source file and line each address belongs to. Something like this:

$ gdb "$(modinfo -n my_module)"
(gdb) list *(some_function+0x12c)

Gdb 现在会告诉源文件的名称和其中的行.

Gdb will now tell the name of the source file and the line in it.

你也可以用 objdump 做类似的事情,但它有点困难.首先,拆解模块:

You can also do a similar thing with objdump but it is a bit more difficult. First, disassemble the module:

objdump -dSlr my_module.ko > my_module.disasm

当使用 -S 选项调用时,objdump 将在结果列表中适当地包含源代码行.

When called with -S option, objdump will include the source lines in the resulting listing where appropriate.

您现在可以将列表向下滚动到 some_function 的代码,找到距函数开头偏移 0x12c 处的指令.源行将在其上方指示.

You can now scroll the listing down to the code of some_function, find the instruction at offset 0x12c from the beginning of the function. The source line will be indicated above it.

经过多次实验,我发现虽然addr2line确实可以用于内核模块,但eu-addr2line(elfutils的类似工具)似乎更可靠.也就是说,有时 addr2line 输出不正确的源代码行,但 eu-add2line 做得对.

After many experiments, I found that although addr2line can indeed be used for kernel modules, eu-addr2line (a similar tool from elfutils) seems to be more reliable. That is, sometimes addr2line output incorrect source lines but eu-add2line did things right.

要使用 eu-addr2line,如果尚未与 elfutils 一起安装 libdw 和 libebl 库,则可能需要安装它们.

To use eu-addr2line, one may need to install libdw and libebl libraries if they are not already installed along with elfutils.

用法与addr2line类似:

eu-addr2line -f -e <path_to_the_module> -j <section_name> <offset_in_section>

如果内核模块的调试信息存储在单独的文件中(这对于主要 Linux 发行版提供的内核来说通常是这种情况),则该文件的路径应用作 .

If the debug information for a kernel module is stored in separate file (this is often the case for the kernels provided by the major Linux distros), the path to that file should be used as <path_to_the_module>.

这篇关于内核模块上的 addr2line的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆