使用strace可以看到对特定文件描述符和特定命令的ioctl调用。第三个参数是一个结构,但strace将其显示为指向内存的原始指针。strace输出示例:
open("/dev/node", O_RDWR) = 3 ioctl(3, 0x108, 0x8f0eb18) = 0 close(3)
是否有办法(strace选项或其他工具)查看结构,或至少查看原始指针后面的值?
2j4z5cfb1#
在gdb中,如果在调用ioctl之前停止它,则可以输入:
(gdb) p *(ioctl_struct *) 0x8f0eb18
这将显示该内存位置的内容如何Map到ioctl_struct。
whitzsjs2#
我也遇到过类似的问题:我想检查vde_switch(它创建了一个TUN/TAP虚拟网络接口)对ioctl的系统调用,以便了解我的代码(它必须执行与vde_switch相同的操作,但以编程方式执行)中的错误。通过运行:
vde_switch
ioctl
sudo strace vde_switch -tap tap0
作为Terry Greentail,我能够知道正在进行的系统调用是ioctl(5, TUNSETIFF, 0x7fffa99404e0),指针将是对struct ifreq类型结构的引用,在我的代码中,我有类似ioctl(tapfd, TUNSETIFF, &ifr_dev)的内容。最初,我尝试让gdb在系统调用时停止,设置:catch syscall ioctl(我将gdb作为gdb --args vde_switch -tap tap0运行),但是每当catch被命中时,gdb都不显示有关ioctl的参数的信息,经过一段时间的挣扎之后,我决定在gdb中运行strace,如下所示:
ioctl(5, TUNSETIFF, 0x7fffa99404e0)
struct ifreq
ioctl(tapfd, TUNSETIFF, &ifr_dev)
catch syscall ioctl
gdb --args vde_switch -tap tap0
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
调用约定(我使用的是AMD 64)使用RDI作为第一个参数,RSI作为第二个参数,RDX作为第三个参数(参见System V AMD 64 ABI)。最后,当断点命中时,我能够检查ifreq结构:
RDI
RSI
RDX
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>}}
2条答案
按热度按时间2j4z5cfb1#
在gdb中,如果在调用ioctl之前停止它,则可以输入:
这将显示该内存位置的内容如何Map到ioctl_struct。
whitzsjs2#
我也遇到过类似的问题:我想检查
vde_switch
(它创建了一个TUN/TAP虚拟网络接口)对ioctl
的系统调用,以便了解我的代码(它必须执行与vde_switch
相同的操作,但以编程方式执行)中的错误。通过运行:
作为Terry Greentail,我能够知道正在进行的系统调用是
ioctl(5, TUNSETIFF, 0x7fffa99404e0)
,指针将是对struct ifreq
类型结构的引用,在我的代码中,我有类似ioctl(tapfd, TUNSETIFF, &ifr_dev)
的内容。最初,我尝试让gdb在系统调用时停止,设置:
catch syscall ioctl
(我将gdb作为gdb --args vde_switch -tap tap0
运行),但是每当catch被命中时,gdb都不显示有关ioctl
的参数的信息,经过一段时间的挣扎之后,我决定在gdb中运行strace,如下所示:虽然没有断点以这种方式工作,但输出显示了正在使用的文件描述符:
所以我又试了一次:
gdb --args strace vde_witch -tap -tap0
并设置条件断点:调用约定(我使用的是AMD 64)使用
RDI
作为第一个参数,RSI
作为第二个参数,RDX
作为第三个参数(参见System V AMD 64 ABI)。最后,当断点命中时,我能够检查ifreq
结构: