2012-03-10 9 views
6

natknąłem taki błąd podczas wykonywania polecenia ni podczas gdb debugowania:GDB strace pokazuje próbuje ptrace na nieprawidłowy adres

Ostrzeżenie:
nie można włożyć breakpoint 0.
błąd dostępu do adresu pamięci 0x3ac706a: Błąd wejścia/wyjścia.

0xf6fa4771 w siglongjmp() z /lib/libc.so.6

W celu zbadania tego, co spotyka się z problemem gdb ja strace gdb i uzyskać taki wynik:

rt_sigprocmask (SIG_BLOCK NULL [RT_1] 8) = 0
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fdf60 [0x1cc4fe470]) = 0
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480 [0x3ac706a4506fa1d]) = 0
rt_sigprocmask (SIG_BLOCK NULL [RT_1] 8) = 0
...
...
rt_sigprocmask (SIG_BLOCK NULL [RT_1] 8) = 0
rt_sigprocmask (SIG_BLOCK NULL [ RT_1] 8) = 0
ptrace (PTRACE_GETREGS, 27781, 0 0x7fff8990e8b0) = 0
ptrace (PTRACE_PEEKTEXT, 27781, 0x3ac7068 [0x28b]) = -1 EIO (błąd wejścia/wyjścia)
ptrace (PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (błąd wejścia/wyjścia)

Oznacza to, że gdb pierwszy ptrace na adres pamięci 0xcc4fe480 i pobiera wartości 0x3ac706a4506fa1d (w rzeczywistości wartości 8-bajtowy 0x03ac706a4506fa1d). Później otrzyma adres wyrównany 0x3ac7068 z pierwszych 4 bajtów tej wartości, co jest nieprawidłowym adresem i powoduje, że gdb nie może ptrować.

Zawartość/proc/[pid]/mapy:

cbce2000-cc353000 R xp 00000000 8:03 295479 xxx.so
cc353000-cc3f0000 O - P 00670000 08:03 295479 xxx .so
cc3f0000-cc3f6000 RW-P 0070d000 8:03 295479 xxx.so
cc3f6000-cc3fe000 RW-P cc3f6000 0:00 0
cc3fe000-cc3ff000 --- s cc3fe000 00:00 0
cc3ff000- cc4ff000 rwxp cc3ff000 00:00 0 cc4ff000-cc500000 --- s cc4ff000 00:00 0

cc500000-cc600000 rwxp cc500000 0:00 0
cc62d000-cc673000 R-PD 00000000 8:03 295545 yyy.so
cc673000-cc674000 - -p 00046000 08:03 295545 yyy.so
cc674000-cc675000 r - p 00046000 08:03 295545 rrr.tak
cc675000-cc676000 RW-P 00047000 8:03 295545 yyy.so

wskazuje, że adres 0xcc4fe480 jest z sekcji pogrubioną czcionką powyżej. Ta sekcja nie jest powiązana z żadnym plikiem .so lub bin.

To pytanie jest faktycznie związana z innym pytaniem http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal-breakpoint, który nie został jeszcze rozwiązany. Znalazłem te problemy podczas badania poprzedniego problemu.

Mam 3 pytania tutaj:
1. Spójrz na wyjście strace dla ptrace tutaj:
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480 [0x3ac706a4506fa1d]) = 0
Dlaczego ostatni parametr odnotowany za pomocą nawiasów kwadratowych? Czy to oznacza, że ​​reprezentuje wartość zwrotu? Strona manual mówi, że ptrace powinien zwracać słowo read dla PTRACE_PEEKTEXT, ale wygląda na to, że strace output nie jest zgodne z tym, więc podejrzewam, że pokazuje wartość zwracaną w ostatnim parametrze.
2. Istnieje sekcja (która z pogrubioną czcionką) między dwoma .so, ale nie jest skojarzony z żadnym i-węzłem. Co reprezentuje taka sekcja?
3. Gdb odczytuje jedno słowo z tej sekcji i używa tego słowa jako adresu, ale w rzeczywistości jest to nieprawidłowy adres. Jakie są możliwe przyczyny takiego błędu?

Dzięki!

Odpowiedz

5
  1. Spójrz na wyjście strace na ptrace tutaj: ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480 [0x3ac706a4506fa1d]) = 0 Dlaczego ostatni parametr odnotowany przez nawiasy kwadratowe? Czy to oznacza, że ​​reprezentuje wartość zwrotu?

Prawidłowo.

  1. Istnieje odcinek (który pogrubioną czcionką) pomiędzy dwoma .so ale nie wiąże się z żadnym węzła. Co reprezentuje taka sekcja?

jest obszar pamięci, który został mmap wyd z MAP_ANONYMOUNS flagi (to znaczy, że nie jest zgodny z plikiem na dysku).

Ponieważ rozmiar tego regionu wynosi dokładnie 1MB, a ponieważ jest otoczony prywatnymi regionami zmapowanymi z PROT_NONE, można bezpiecznie założyć, że ten region reprezentuje stos wątków otoczony strefami stosu osłon.

  1. Gdb czyta jedno słowo z tego odcinka i używa tego słowa jako adres, ale w rzeczywistości jest to nieprawidłowy adres. Jakie są możliwe przyczyny takiego błędu?

Z jakiegoś powodu GDB uważa, że ​​nie powinno być kod na adres 0x3ac7068 i chce umieścić tam się wewnętrzny przerwania. GDB używa wewnętrznych punktów przerwania do śledzenia załadowanych bibliotek współdzielonych (między innymi).

Dane wyjściowe z maintenance info break powinny ujawnić kod, który według GDB znajduje się na "złym" adresie.

0

Domyślam się, że kod przepełnił się i zapisano prawidłowy adres, a gdb uzyskuje dostęp do tego obszaru pamięci, oczekując adresu, ale otrzymując niepotrzebne dane. Jaka jest sekcja kodu, który próbujesz debugować? To może nam pomóc.

+0

Jestem debugowania funkcji we wspólnej biblioteki (.so). Ale nie jest to jedna z dwóch wymienionych powyżej bibliotek. To znaczy, że debuguję lib A i gdb odczytuje niepoprawny adres z sekcji między lib B i lib C. To dlatego wprowadza mnie w zakłopotanie. –

Powiązane problemy