解释 strace 输出

Posted

技术标签:

【中文标题】解释 strace 输出【英文标题】:Interpreting strace output 【发布时间】:2012-06-23 12:23:23 【问题描述】:

使用 strace 可以查看特定文件描述符和特定命令的 ioctl 调用。第三个参数是一个结构,但 strace 将其显示为指向内存的原始指针。 strace 输出示例:

open("/dev/node", O_RDWR) = 3
ioctl(3, 0x108, 0x8f0eb18) = 0
close(3)  

有没有办法(strace 选项或其他工具)来查看结构是什么,或者至少是原始指针后面的值?

【问题讨论】:

有没有给你指令的地址?如果是这样,在 GDB 中添加断点然后查看内存真的很简单......你如何确定我不太确定的实际结构。 我的意思是,如果我将它写在我的程序中,它看起来像这样:ioctl( dev_node, IOCTL_CODE, &ioctl_struct ),其中第三个参数是 Ioctl_Buf_Struct 类型的结构。当我们在上面的示例中看到 strace 用于二进制程序时,我很想知道 0x8f0eb18 地址后面是什么:在那里发送的结构是什么,或者至少它的值是什么。 gdb 可以帮忙吗? 好吧...如果您运行程序,如果在该命令之前停止,那么您可以通过取消引用指针来找到值。使用 strace 查找所有 malloc 调用,直到找到返回该指针的调用。这将告诉你结构的大小。然后,您可以查看具有已知大小的内存,并以二进制形式重现该结构。你可能永远不知道结构是什么,但你可以找到它的值。 【参考方案1】:

在 gdb 中,如果在调用 ioctl 之前将其停止,则可以输入:

(gdb) p *(ioctl_struct *) 0x8f0eb18

这将向您展示该内存位置的内容如何映射到 ioctl_struct。

【讨论】:

【参考方案2】:

我遇到了类似的问题:想检查由vde_switch(创建 TUN/TAP 虚拟网络接口)对ioctl 的系统调用,以便了解我在代码中做错了什么(它必须与vde_switch 做同样的事情,但以编程方式。)

通过运行:

sudo strace vde_switch -tap tap0

作为 Terry Greentail,我能够知道正在进行的系统调用是 ioctl(5, TUNSETIFF, 0x7fffa99404e0),并且指针将是对 struct ifreq 类型结构的引用。在我的代码中,我有类似 ioctl(tapfd, TUNSETIFF, &ifr_dev) 的内容。

最初我试图让 gdb 在系统调用上停止,设置为:catch syscall ioctl(我曾以 gdb --args vde_switch -tap tap0 运行 gdb),但每当遇到问题时,gdb 都不会显示有关 ioctl 参数的信息。在为此苦苦挣扎了一段时间后,我决定在 gdb 中运行 strace,如下所示:

gdb --args strace vde_witch -tap -tap0

虽然没有断点以这种方式工作,但输出显示了正在使用的文件描述符:

open("/dev/net/tun", O_RDWR)            = 9
ioctl(9, TUNSETIFF, 0x7fffffffe350)     = 0

所以我又试了一次:gdb --args strace vde_witch -tap -tap0 并设置了条件断点:

b ioctl if $rdi==9

调用约定(我在 AMD64 上)使用RDI 作为第一个参数,RSI 作为第二个参数,RDX 作为第三个参数(参见System V AMD64 ABI。)最后,当断点被命中时,我能够检查ifreq 结构:

Breakpoint 6, ioctl () at ../sysdeps/unix/syscall-template.S:81
81      ../sysdeps/unix/syscall-template.S: File or directory not found.

(gdb) p (struct ifreq) *$rdx
$5 = ifr_ifrn = ifrn_name = "tap0", '\000' <repete 11 vezes>, ifr_ifru = ifru_addr = sa_family = 4098, sa_data = '\000' <repete 13 vezes>, ifru_dstaddr = sa_family = 4098, sa_data = '\000' <repete 13 vezes>, ifru_broadaddr = sa_family = 4098, sa_data = '\000' <repete 13 vezes>, ifru_netmask = sa_family = 4098, sa_data = '\000' <repete 13 vezes>, ifru_hwaddr = sa_family = 4098, sa_data = '\000' <repete 13 vezes>, ifru_flags = 4098, ifru_ivalue = 4098, ifru_mtu = 4098, ifru_map = mem_start = 4098, mem_end = 0, base_addr = 0, irq = 0 '\000', dma = 0 '\000', port = 0 '\000', ifru_slave = "\002\020", '\000' <repete 13 vezes>, ifru_newname = "\002\020", '\000' <repete 13 vezes>, ifru_data = 0x1002 <Address 0x1002 out of bounds>

【讨论】:

以上是关于解释 strace 输出的主要内容,如果未能解决你的问题,请参考以下文章

strace

strace 小结

strace

strace命令用法

如何使用strace+pstack利器分析程序性能

strace命令