2012-06-21 18 views
11

W strace można zobaczyć wywołanie ioctl dla określonego deskryptora pliku i za pomocą określonego polecenia. Trzeci argument jest strukturą, ale strace pokazuje go jako surowy wskaźnik do pamięci. Przykładem wyjście strace:Interpretowanie wyjścia strace

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

Czy istnieje sposób (opcje strace lub innych narzędzi), aby zobaczyć jaka jest struktura lub przynajmniej wartość za surowego wskaźnik?

+0

Czy to daje adres instrukcja? Jeśli tak, to w GDB jest naprawdę proste dodawanie punktu przerwania, a następnie spójrz na pamięć ... Jak określić rzeczywistą strukturę, której nie jestem pewien. – Matt

+0

Mam na myśli to, że gdybym napisał to w moim programie, wyglądałoby to tak: 'ioctl (dev_node, IOCTL_CODE i &octl_struct)', gdzie trzeci argument jest strukturą typu Ioctl_Buf_Struct. Kiedy strace jest używane do programu binarnego, jak widzimy w powyższym przykładzie, chciałbym wiedzieć, co kryje się pod adresem 0x8f0eb18: jaka jest struktura, która jest tam wysyłana, lub przynajmniej jaka jest jego wartość. Czy gdb może tutaj pomóc? –

+0

well ... Jeśli uruchomisz program, zatrzymaj się tuż przed tym poleceniem, wtedy możesz znaleźć wartości przez dereferencję wskaźnika. Użyj strace, aby znaleźć wszystkie wywołania malloc, dopóki nie znajdziesz tego, który zwróci ten wskaźnik. To powie ci rozmiar struktury.Następnie możesz spojrzeć na pamięć o znanym rozmiarze i odtworzyć strukturę w jej binarnej postaci. Możesz nigdy nie wiedzieć * czym * jest struktura, ale możesz znaleźć wartość. – Matt

Odpowiedz

2

W gdb, jeśli przestaniesz go tuż przed wywołaniem ioctl można następnie wpisać:

(gdb) p *(ioctl_struct *) 0x8f0eb18 

To pokaże, jak zawartość tej mapy z lokalizacją pamięci do ioctl_struct.

1

Mam podobny problem: chciałem sprawdzić syscall pod numerem ioctl wykonanym przez vde_switch (który tworzy wirtualny interfejs sieciowy TUN/TAP), aby wiedzieć, co robiłem źle w moim kodzie (który miał zrobić to samo, co vde_switch, ale programowo)

Uruchamiając.

sudo strace vde_switch -tap tap0 

udało mi się dowiedzieć, jak Terry Greentail, że syscall dokonywana była ioctl(5, TUNSETIFF, 0x7fffa99404e0) i wskaźnik będzie odwołanie do struktury typu struct ifreq. W moim kodzie miałem coś w rodzaju ioctl(tapfd, TUNSETIFF, &ifr_dev).

Początkowo starałem się zrobić przystanek gdb na syscall, ustawienie: catch syscall ioctl (miałem uruchomić gdb jako gdb --args vde_switch -tap tap0), ale ilekroć połów został uderzony, gdb wykazało żadnych informacji na temat parametrów ioctl. Po zmaga się z tym przez chwilę, postanowiłem uruchomić strace wewnątrz gdb, jak:

gdb --args strace vde_witch -tap -tap0 

Choć nie przerwania pracował w ten sposób wyjście pokazał których deskryptor był używany:

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

Spróbowałem więc innym razem z: gdb --args strace vde_witch -tap -tap0 i ustawić punkt przerwania warunkowego:

b ioctl if $rdi==9 

konwencja wywołujący (jestem na AMD64) wykorzystuje RDI f lub pierwszy parametr, RSI za drugim i RDX za trzeci (patrz System V AMD64 ABI). Wreszcie, kiedy punkt przerwania został trafiony, udało mi się zbadać strukturę 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>}} 
Powiązane problemy