Open honggyukim opened 6 years ago
It can be related to #401.
At first, we have to fix incorrect kernel address shown in TUI mode.
For example, handle_mm_fault
is shown 0xffff811c4dd0
but it's actually at 0xffffffff811c4dd0
. It's because uftrace only saves 48-bits for address but it has to show in 64-bit address space.
Thinking again, I found a way to do it without such mkdbg
tool. The source line info can simply be extracted by nm
tool with -l
option.
$ nm -l /usr/lib/debug/boot/vmlinux-4.4.0-116-generic | grep "^[0-9a-f]\+ [tT] .*:[0-9]\+" | head
ffffffff813a55e0 t aa_af_perm.constprop.3 /build/linux-fQ94TU/linux-4.4.0/security/apparmor/net.c:183
ffffffff81393340 T aa_alloc_profile /build/linux-fQ94TU/linux-4.4.0/security/apparmor/policy.c:259
ffffffff8139dad0 T aa_alloc_proxy /build/linux-fQ94TU/linux-4.4.0/security/apparmor/label.c:63
ffffffff81fa2fb6 T aa_alloc_root_ns /build/linux-fQ94TU/linux-4.4.0/security/apparmor/policy_ns.c:333
ffffffff8139b920 T aa_alloc_sid /build/linux-fQ94TU/linux-4.4.0/security/apparmor/sid.c:35
ffffffff8138a3d0 T aa_alloc_task_context /build/linux-fQ94TU/linux-4.4.0/security/apparmor/context.c:38
ffffffff8138bbf0 T aa_apply_modes_to_perms /build/linux-fQ94TU/linux-4.4.0/security/apparmor/lib.c:308
ffffffff81389e70 T aa_audit /build/linux-fQ94TU/linux-4.4.0/security/apparmor/audit.c:132
ffffffff8139bc40 T aa_audit_file /build/linux-fQ94TU/linux-4.4.0/security/apparmor/file.c:103
ffffffff8138ba00 T aa_audit_perm_mask /build/linux-fQ94TU/linux-4.4.0/security/apparmor/lib.c:257
$ nm -l /usr/lib/debug/boot/vmlinux-4.4.0-116-generic | grep "^[0-9a-f]\+ [tT] .*:[0-9]\+" | tail
ffffffff81444910 t zx_direction_output /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:69
ffffffff81444990 t zx_get_value /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:93
ffffffff820c0101 t zx_gpio_driver_exit /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:300
ffffffff81fa8ca6 t zx_gpio_driver_init /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:30i
ffffffff81444ce0 t zx_gpio_probe /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:218
ffffffff81444ba0 t zx_irq_handler /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:160
ffffffff81444ae0 t zx_irq_mask /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:181
ffffffff814449e0 t zx_irq_type /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:110
ffffffff81444b40 t zx_irq_unmask /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:196
ffffffff814449b0 t zx_set_value /build/linux-fQ94TU/linux-4.4.0/drivers/gpio/gpio-zx.c:100
The remaining problem is to change the filepath to the user's source location of prebuilt kernel image. It could be simpler if the user creates the same filepath using softlink to their kernel source location.
I got the above kernel image from the link below: (just leaving this note for later reference) https://launchpad.net/ubuntu/xenial/amd64/linux-image-4.4.0-116-generic-dbgsym/4.4.0-116.140
And ubuntu kernel source is downloaded and set the kernel version as follows:
$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-xenial
$ cd ubuntu-xenial
$ git checkout Ubuntu-4.4.0-116.140 -b Ubuntu-4.4.0-116.140
Hmm.. I thought about it again. What about putting the filepath and line info inside .sym
and kallsyms
?
The layout looks just same as the output from nm
with -l/--line-numbers
option.
$ nm --line-numbers /usr/lib/debug/boot/vmlinux-4.4.0-116-generic | grep "[tT] handle_mm_fault"
ffffffff811c4dd0 T handle_mm_fault /build/linux-fQ94TU/linux-4.4.0/mm/memory.c:3435
Its layout is as follows:
(address) (type) (symbol_name)<tab>(filepath:line_number)
I think it's much easier to parse than using .dbg
separately. We can just skip if <tab>(filepath:line_number)
part doesn't exist.
Instead of just copying from /proc/kallsyms
, we can just run the below command with this change:
$ nm -l <kernel_image_with_debuginfo> | grep "^[0-9a-f]\+ [tT] " > uftrace.data/kallsyms
Then we can ask users to create a soft link properly based on the debug info source location to the kernel source directory.
For example, I made the soft link as follows to make the source location same with its debug info location:
$ readlink /build/linux-fQ94TU/linux-4.4.0
/home/honggyu/work/kernel/ubuntu/ubuntu-xenial
One more small benefit of using nm
tool for getting source location is that we can make uftrace free from libdw-dev
.
I think it's better (and intuitive) to keep debug info (including line numbers) in .dbg
files. Using nm -l
to collect line info with libdw looks useful.
nm
uses libbfd-*-system.so
instead of libdw
so I think we can verify our source location with nm
tool.
It'd be useful to add a tool called
mkdbg
to create.dbg
file from given ELF file. The purposed use case for this is to create.dbg
file forvmlinuz
kernel image with its debug line info.Otherwise, we have to provide an additional option such as
--kernel-image=[vmlinux]
to generate source line information during record time.It can be used to follow source code of
ftrace
recorded function graph data in TUI mode.