Ste*_*las 2 linux arrays systemtap
在姐妹网站的答案中,我试图从Linux内核数组中转储信息,该数组unix_socket_table@net/unix/af_unix.c定义为:
struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
Run Code Online (Sandbox Code Playgroud)
目前,我在stp脚本中硬编码数组的大小:
for (i = 0; i < 512; i++)
我怎么能避免这种情况?该信息(数组的大小)存储在调试信息中.gdb可以告诉我:
$ gdb --batch --ex 'whatis unix_socket_table' "/usr/lib/debug/boot/vmlinux-$(uname -r)"
type = struct hlist_head [512]
$ gdb --batch --ex 'p sizeof(unix_socket_table)/sizeof(*unix_socket_table)' "/usr/lib/debug/boot/vmlinux-$(uname -r)"
$1 = 512
Run Code Online (Sandbox Code Playgroud)
但是我该怎么办呢systemtap?AFAICT,systemtap没有sizeof()运营商.
如果是类型,则@cast可以使用运算符:
size=&@cast(0,"$TYPENAME")[1]
Run Code Online (Sandbox Code Playgroud)
但是,唉,unix_socket_table不是一种类型.因此,计划B,使用symdata变量(在附近的任何旧核函数的范围内).
probe begin /* kernel.function("*@net/unix/af_unix.c") */ {
println(symdata(& @var("unix_socket_table")))
exit()
}
Run Code Online (Sandbox Code Playgroud)
结果在这里:
unix_socket_table+0x0/0x1000 [kernel]
Run Code Online (Sandbox Code Playgroud)
第二个十六进制数字是符号大小,在脚本处理时从ELF符号表计算,相当于此处的4096数字:
% readelf -s /usr/lib/debug/lib/modules/`uname -r`/vmlinux | grep unix_socket_table
71901: ffffffff82023dc0 4096 OBJECT GLOBAL DEFAULT 28 unix_socket_table
Run Code Online (Sandbox Code Playgroud)
例如,您可以获取该号码:
probe begin {
tokenize(symdata(@var("unix_socket_table@net/unix/af_unix.c")),"/");
printf("%d\n", strtol(tokenize("",""), 16));
exit()
}
Run Code Online (Sandbox Code Playgroud)