After the kernel panic, how to quickly locate?

When the kernel Panic, usually print a callback, and print out the address of the current error, such as:

[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)

[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)

[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)

[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)

Through analysis, to quickly locate the line of code error, in fact, to quickly find the error code that corresponds to the address?

First, when the connection code is compiled, each function has a start address and length, this address is the address of the program running, and internal functions, each instruction with respect to the start address of the function will be offset. Then later with address, can be positioned within the function which the address falls in the interval, then find the function, and further by calculating the offset to locate the line of code.

However, if the log file system version to get where inconsistent with the current version of the code, the compiler will address the differences. So by simply direct address could not find the original location, you may need this information inside the callback function name. Where the first positioning function by the function name, and then navigate through the line offset.

The appropriate tools addr2line, gdb, objdump and so on. However, to note that the actual running code symbol is not required, just the address on the line. So if you want to debug code, you must ensure that the debug symbols have been compiled into the kernel, otherwise, the callback is printed inside a bunch of address, you can not see the sign, then the case for the two mentioned above, will not be able to accurately locate the problem. So, if you want to get enough debugging information, based on the need to open the following options:

CONFIG_DEBUG_KERNEL=y

CONFIG_DEBUG_INFO=y

CONFIG_KALLSYMS=y

CONFIG_KALLSYMS_ALL=y

CONFIG_DEBUG_BUGVERBOSE=y

CONFIG_STACKTRACE=y

1、addr2line

If an error kernel debugging kernel consistent with current needs, but also the compiler and so consistent, you can get to the line of code error by addr2line direct, assuming error address 0019594c:

$ addr2line -e vmlinux 0x0019594c

mm/backing-dev.c:335

If this is the case two, we can first obtain the current position of the real function by vmlinux in bdi_register nm.

$ nm vmlinux | grep bdi_register

0x00195860 T bdi_register

Then, with an offset 0xec, you can calculate the real address:

$ echo "obase=16;ibase=10;$((0x00195860+0xec))" | bc -l

19594C

2、gdb

The use of this relatively common, there is not elaborated.

3、objdump

If this is the case of a direct address with dump out. Let's look back Backtrace information: bdi_register + 0xec / 0x150, 0xec here is shifted, and the function is the size of 0x150. Vmlinux can get the entire code with objdump default, but in fact we only get part, this may be specified by --start-address and --stop-address. Additionally disassembly can -d, -S may be incorporated into the source code.

$ objdump -dS vmlinux_with_debug_info --start-address=0x0019594c --stop-address=$((0x0019594c+0x150))

If this is the case of two, you can be like addr2line first calculate real address, and then exported by the above method.

Reproduced in: https: //www.jianshu.com/p/016988ae3609

Guess you like

Origin blog.csdn.net/weixin_33953249/article/details/91236189