作者
pengdonglin137@163.com
背景
开发过程中,有时需要读取内核中某个变量的值,比如我想获取下面这个变量的内容:
const char linux_banner[] = "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
这个变量其实是/proc/version的内容:
# cat /proc/version Linux version 6.2.0+ (pengdl@ubuntu) (gcc (Ubuntu 8.4.0-3ubuntu2) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #3 SMP PREEMPT_DYNAMIC Sun Aug 6 20:50:53 PDT 2023
下面我们通过几种办法从内存里得到其内容。
方法
使用gdb
# gdb /mnt/linux-6.2/vmlinux /proc/kcore # 获取变量的地址 (gdb) info address linux_banner Symbol "linux_banner" is static storage at address 0xffffffff82961660. # 读取变量的内容 (gdb) x /s 0xffffffff82961660 0xffffffff82961660 <linux_banner>: "Linux version 6.2.0+ (pengdl@ubuntu) (gcc (Ubuntu 8.4.0-3ubuntu2) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #3 SMP PREEMPT_DYNAMIC Sun Aug 6 20:50:53 PDT 2023\n"
使用bpftrace
# export BPFTRACE_STRLEN=200; bpftrace -e 'BEGIN {printf("%s\n", str(kaddr("linux_banner")))}' Attaching 1 probe... Linux version 6.2.0+ (pengdl@ubuntu) (gcc (Ubuntu 8.4.0-3ubuntu2) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #3 SMP PREEMPT_DYNAMIC Sun Aug 6 20:50:53 PDT 2023
crash工具
# crash /mnt/linux-6.2/vmlinux crash> rd -a linux_banner ffffffff82961660: Linux version 6.2.0+ (pengdl@ubuntu) (gcc (Ubuntu 8.4.0-3ubu ffffffff8296169c: ntu2) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #3 SMP P ffffffff829616d8: REEMPT_DYNAMIC Sun Aug 6 20:50:53 PDT 2023 BASH 复制 全屏
完。