18c2ecf20Sopenharmony_ci.. highlight:: none 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ciDebugging kernel and modules via gdb 48c2ecf20Sopenharmony_ci==================================== 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ciThe kernel debugger kgdb, hypervisors like QEMU or JTAG-based hardware 78c2ecf20Sopenharmony_ciinterfaces allow to debug the Linux kernel and its modules during runtime 88c2ecf20Sopenharmony_ciusing gdb. Gdb comes with a powerful scripting interface for python. The 98c2ecf20Sopenharmony_cikernel provides a collection of helper scripts that can simplify typical 108c2ecf20Sopenharmony_cikernel debugging steps. This is a short tutorial about how to enable and use 118c2ecf20Sopenharmony_cithem. It focuses on QEMU/KVM virtual machines as target, but the examples can 128c2ecf20Sopenharmony_cibe transferred to the other gdb stubs as well. 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciRequirements 168c2ecf20Sopenharmony_ci------------ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci- gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true 198c2ecf20Sopenharmony_ci for distributions) 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciSetup 238c2ecf20Sopenharmony_ci----- 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci- Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and 268c2ecf20Sopenharmony_ci www.qemu.org for more details). For cross-development, 278c2ecf20Sopenharmony_ci https://landley.net/aboriginal/bin keeps a pool of machine images and 288c2ecf20Sopenharmony_ci toolchains that can be helpful to start from. 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci- Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave 318c2ecf20Sopenharmony_ci CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports 328c2ecf20Sopenharmony_ci CONFIG_FRAME_POINTER, keep it enabled. 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci- Install that kernel on the guest, turn off KASLR if necessary by adding 358c2ecf20Sopenharmony_ci "nokaslr" to the kernel command line. 368c2ecf20Sopenharmony_ci Alternatively, QEMU allows to boot the kernel directly using -kernel, 378c2ecf20Sopenharmony_ci -append, -initrd command line switches. This is generally only useful if 388c2ecf20Sopenharmony_ci you do not depend on modules. See QEMU documentation for more details on 398c2ecf20Sopenharmony_ci this mode. In this case, you should build the kernel with 408c2ecf20Sopenharmony_ci CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR. 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci- Build the gdb scripts (required on kernels v5.1 and above):: 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci make scripts_gdb 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci- Enable the gdb stub of QEMU/KVM, either 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci - at VM startup time by appending "-s" to the QEMU command line 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci or 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci - during runtime by issuing "gdbserver" from the QEMU monitor 538c2ecf20Sopenharmony_ci console 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci- cd /path/to/linux-build 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci- Start gdb: gdb vmlinux 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci Note: Some distros may restrict auto-loading of gdb scripts to known safe 608c2ecf20Sopenharmony_ci directories. In case gdb reports to refuse loading vmlinux-gdb.py, add:: 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci add-auto-load-safe-path /path/to/linux-build 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci to ~/.gdbinit. See gdb help for more details. 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci- Attach to the booted guest:: 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci (gdb) target remote :1234 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciExamples of using the Linux-provided gdb helpers 728c2ecf20Sopenharmony_ci------------------------------------------------ 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci- Load module (and main kernel) symbols:: 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci (gdb) lx-symbols 778c2ecf20Sopenharmony_ci loading vmlinux 788c2ecf20Sopenharmony_ci scanning for modules in /home/user/linux/build 798c2ecf20Sopenharmony_ci loading @0xffffffffa0020000: /home/user/linux/build/net/netfilter/xt_tcpudp.ko 808c2ecf20Sopenharmony_ci loading @0xffffffffa0016000: /home/user/linux/build/net/netfilter/xt_pkttype.ko 818c2ecf20Sopenharmony_ci loading @0xffffffffa0002000: /home/user/linux/build/net/netfilter/xt_limit.ko 828c2ecf20Sopenharmony_ci loading @0xffffffffa00ca000: /home/user/linux/build/net/packet/af_packet.ko 838c2ecf20Sopenharmony_ci loading @0xffffffffa003c000: /home/user/linux/build/fs/fuse/fuse.ko 848c2ecf20Sopenharmony_ci ... 858c2ecf20Sopenharmony_ci loading @0xffffffffa0000000: /home/user/linux/build/drivers/ata/ata_generic.ko 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci- Set a breakpoint on some not yet loaded module function, e.g.:: 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci (gdb) b btrfs_init_sysfs 908c2ecf20Sopenharmony_ci Function "btrfs_init_sysfs" not defined. 918c2ecf20Sopenharmony_ci Make breakpoint pending on future shared library load? (y or [n]) y 928c2ecf20Sopenharmony_ci Breakpoint 1 (btrfs_init_sysfs) pending. 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci- Continue the target:: 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci (gdb) c 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci- Load the module on the target and watch the symbols being loaded as well as 998c2ecf20Sopenharmony_ci the breakpoint hit:: 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci loading @0xffffffffa0034000: /home/user/linux/build/lib/libcrc32c.ko 1028c2ecf20Sopenharmony_ci loading @0xffffffffa0050000: /home/user/linux/build/lib/lzo/lzo_compress.ko 1038c2ecf20Sopenharmony_ci loading @0xffffffffa006e000: /home/user/linux/build/lib/zlib_deflate/zlib_deflate.ko 1048c2ecf20Sopenharmony_ci loading @0xffffffffa01b1000: /home/user/linux/build/fs/btrfs/btrfs.ko 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci Breakpoint 1, btrfs_init_sysfs () at /home/user/linux/fs/btrfs/sysfs.c:36 1078c2ecf20Sopenharmony_ci 36 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci- Dump the log buffer of the target kernel:: 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci (gdb) lx-dmesg 1128c2ecf20Sopenharmony_ci [ 0.000000] Initializing cgroup subsys cpuset 1138c2ecf20Sopenharmony_ci [ 0.000000] Initializing cgroup subsys cpu 1148c2ecf20Sopenharmony_ci [ 0.000000] Linux version 3.8.0-rc4-dbg+ (... 1158c2ecf20Sopenharmony_ci [ 0.000000] Command line: root=/dev/sda2 resume=/dev/sda1 vga=0x314 1168c2ecf20Sopenharmony_ci [ 0.000000] e820: BIOS-provided physical RAM map: 1178c2ecf20Sopenharmony_ci [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable 1188c2ecf20Sopenharmony_ci [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved 1198c2ecf20Sopenharmony_ci .... 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci- Examine fields of the current task struct:: 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci (gdb) p $lx_current().pid 1248c2ecf20Sopenharmony_ci $1 = 4998 1258c2ecf20Sopenharmony_ci (gdb) p $lx_current().comm 1268c2ecf20Sopenharmony_ci $2 = "modprobe\000\000\000\000\000\000\000" 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci- Make use of the per-cpu function for the current or a specified CPU:: 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci (gdb) p $lx_per_cpu("runqueues").nr_running 1318c2ecf20Sopenharmony_ci $3 = 1 1328c2ecf20Sopenharmony_ci (gdb) p $lx_per_cpu("runqueues", 2).nr_running 1338c2ecf20Sopenharmony_ci $4 = 0 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci- Dig into hrtimers using the container_of helper:: 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci (gdb) set $next = $lx_per_cpu("hrtimer_bases").clock_base[0].active.next 1388c2ecf20Sopenharmony_ci (gdb) p *$container_of($next, "struct hrtimer", "node") 1398c2ecf20Sopenharmony_ci $5 = { 1408c2ecf20Sopenharmony_ci node = { 1418c2ecf20Sopenharmony_ci node = { 1428c2ecf20Sopenharmony_ci __rb_parent_color = 18446612133355256072, 1438c2ecf20Sopenharmony_ci rb_right = 0x0 <irq_stack_union>, 1448c2ecf20Sopenharmony_ci rb_left = 0x0 <irq_stack_union> 1458c2ecf20Sopenharmony_ci }, 1468c2ecf20Sopenharmony_ci expires = { 1478c2ecf20Sopenharmony_ci tv64 = 1835268000000 1488c2ecf20Sopenharmony_ci } 1498c2ecf20Sopenharmony_ci }, 1508c2ecf20Sopenharmony_ci _softexpires = { 1518c2ecf20Sopenharmony_ci tv64 = 1835268000000 1528c2ecf20Sopenharmony_ci }, 1538c2ecf20Sopenharmony_ci function = 0xffffffff81078232 <tick_sched_timer>, 1548c2ecf20Sopenharmony_ci base = 0xffff88003fd0d6f0, 1558c2ecf20Sopenharmony_ci state = 1, 1568c2ecf20Sopenharmony_ci start_pid = 0, 1578c2ecf20Sopenharmony_ci start_site = 0xffffffff81055c1f <hrtimer_start_range_ns+20>, 1588c2ecf20Sopenharmony_ci start_comm = "swapper/2\000\000\000\000\000\000" 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ciList of commands and functions 1638c2ecf20Sopenharmony_ci------------------------------ 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciThe number of commands and convenience functions may evolve over the time, 1668c2ecf20Sopenharmony_cithis is just a snapshot of the initial version:: 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci (gdb) apropos lx 1698c2ecf20Sopenharmony_ci function lx_current -- Return current task 1708c2ecf20Sopenharmony_ci function lx_module -- Find module by name and return the module variable 1718c2ecf20Sopenharmony_ci function lx_per_cpu -- Return per-cpu variable 1728c2ecf20Sopenharmony_ci function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable 1738c2ecf20Sopenharmony_ci function lx_thread_info -- Calculate Linux thread_info from task variable 1748c2ecf20Sopenharmony_ci lx-dmesg -- Print Linux kernel log buffer 1758c2ecf20Sopenharmony_ci lx-lsmod -- List currently loaded modules 1768c2ecf20Sopenharmony_ci lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ciDetailed help can be obtained via "help <command-name>" for commands and "help 1798c2ecf20Sopenharmony_cifunction <function-name>" for convenience functions. 180