2015-05-09 8 views
9

tutaj jest mój kod disas:gdb nie może uzyskać dostępu Błąd adresu pamięci

0x0804844d <+0>:  push %ebp 
    0x0804844e <+1>:  mov %esp,%ebp 
    0x08048450 <+3>:  and $0xfffffff0,%esp 
    0x08048453 <+6>:  sub $0x20,%esp 
    0x08048456 <+9>:  movl $0x8048540,(%esp) 
    0x0804845d <+16>: call 0x8048310 <[email protected]> 
    0x08048462 <+21>: lea 0x1c(%esp),%eax 
    0x08048466 <+25>: mov %eax,0x4(%esp) 
    0x0804846a <+29>: movl $0x8048555,(%esp) 
    0x08048471 <+36>: call 0x8048320 <[email protected]> 
    0x08048476 <+41>: mov 0x1c(%esp),%eax 
    0x0804847a <+45>: cmp $0x208c,%eax 
    0x0804847f <+50>: jne 0x804848f <main+66> 
    0x08048481 <+52>: movl $0x8048558,(%esp) 
    0x08048488 <+59>: call 0x8048310 <[email protected]> 
    0x0804848d <+64>: jmp 0x804849b <main+78> 
=> 0x0804848f <+66>: movl $0x8048569,(%esp) 
    0x08048496 <+73>: call 0x8048310 <[email protected]> 
    0x0804849b <+78>: mov $0x0,%eax 
    0x080484a0 <+83>: leave 
    0x080484a1 <+84>: ret 

co jestem tring aby zbadać to $ 0x208c. Kiedy wpisuję x/xw 0x208c, to daje mi błąd, który mówi: Nie mogę uzyskać dostępu do pamięci pod adresem 0x208c. Kiedy wpisuję rejestry Info i patrzę na eax, mówi ona o wartości, którą podałem. Zasadniczo ten program porównuje dwie wartości iw zależności od tego drukuje coś. Problem polega na tym, że jest to praca domowa z uniwersytetu i nie mam kodu. Mam nadzieję, że możesz pomóc. Dziękuję Ci.

+1

[palec w powietrzu] podajesz nieprawidłowy parametr? Siedzisz tam, przed debuggerem. Czego moglibyśmy się dowiedzieć, czego nie można, zwłaszcza bez kodu źródłowego? To bardzo dziwne zadanie, które prosi cię o naprawienie rzeczy bez źródła ... –

+0

W końcu wymyśliłem, żeby użyć instrukcji print zamiast x/xw, czy możesz wyjaśnić, dlaczego druk działał, a x nie? – Ojs

+0

$ 0x208c jest wartością bezwzględną, a nie adresem pamięci! –

Odpowiedz

12

Po wpisaniu x/xw 0x208c daje mi błąd, który mówi Cannot access memory at address 0x208c

demontaż dla programu mówi, że robi coś takiego:

puts("some string"); 
int i; 
scanf("%d", &i); // I don't know what the actual format string is. 
        // You can find out with x/s 0x8048555 
if (i == 0x208c) { ... } else { ... } 

Innymi słowy, 0x208c jest wartością (8332), która jest w nim zakodowana na stałe i jest , a nie wskaźnikiem. Dlatego GDB jest całkowicie poprawny w informowaniu, że jeśli interpretujesz 0x208c jako wskaźnik, wskaźnik ten nie wskazuje czytelnej pamięci.

w końcu zorientowali się, aby korzystać z instrukcji print zamiast x/xw

Wygląda na nie zrozumieć różnicę między print i examine poleceń. Rozważmy następujący przykład:

int foo = 42; 
int *pfoo = &foo; 

Z powyższego print pfoo daje adres od foo i x pfoo daje wartość zapisany pod tym adresem (czyli wartości foo).

3

Okazało się, że niemożliwe jest zbadanie pamięci mmap, która nie ma flagi PROT_READ. To nie jest problem z OP, ale był mój, a komunikat o błędzie jest taki sam.

Zamiast

mmap(0, size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 

zrobić

mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 

i voila, pamięć może być zbadany.

0

Niezainicjowane wskaźniki

To niby oczywiste w retrospektywne, ale to, co było przyczyną GDB aby pokazać, że komunikat o błędzie do mnie. Wzdłuż:

#include <stdio.h> 

int main(void) { 
    int *p; 
    printf("*p = %d\n", *p); 
} 

, a następnie:

gdb -q -nh -ex run ./tmp.out 
Reading symbols from ./tmp.out...done. 
Starting program: /home/ciro/bak/git/cpp-cheat/gdb/tmp.out 

Program received signal SIGSEGV, Segmentation fault. 
0x0000555555554656 in main() at tmp.c:5 
5   printf("*p = %d\n", *p); 
(gdb) print *p 
Cannot access memory at address 0x0 

Ale w złożonym programem kursu, a gdy adres było coś przypadkowy różny od zera.