11

straceを使用すると、特定のファイル記述子および特定のコマンドに対するioctl呼び出しを確認できます。3番目の引数は構造体ですが、straceはそれをメモリへの生のポインタとして示します。strace出力の例:

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

構造、または少なくとも生のポインターの背後にある値を確認する方法(straceオプションまたは他のツール)はありますか?

4

2 に答える 2

2

gdb では、ioctl を呼び出す直前に停止すると、次のように入力できます。

(gdb) p *(ioctl_struct *) 0x8f0eb18

これにより、そのメモリ位置の内容が ioctl_struct にどのようにマップされるかがわかります。

于 2012-06-21T21:17:22.163 に答える
2

同様の問題に遭遇しました:自分のコードで何が間違っていたかを知るために (TUN/TAP 仮想ネットワーク インターフェイスを作成する) ioctlmade byへの syscall を検査したかったのです (同じことをしなければなりませんでした)。 、しかしプログラム的に。)vde_switchvde_switch

実行することにより:

sudo strace vde_switch -tap tap0

Terry Greentail として、作成されたシステムコールは でioctl(5, TUNSETIFF, 0x7fffa99404e0)あり、ポインターは type の構造体への参照であることを知ることができましたstruct ifreq。私のコードでは、次のようなものがありioctl(tapfd, TUNSETIFF, &ifr_dev)ました。

最初に、syscall で gdb を停止させようとしましたが、次のように設定しましたcatch syscall ioctl(gdb を として実行しましたgdb --args vde_switch -tap tap0) 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、最初のパラメーター、RSI2 番目、3 番目のパラメーターを使用しています ( System V AMD64 ABIRDXを参照してください) 。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>}}
于 2013-07-30T17:44:13.203 に答える