web-dev-qa-db-fra.com

gdb ne peut pas accéder à l'erreur d'adresse mémoire

voici mon code disas:

   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 <puts@plt>
   0x08048462 <+21>:    lea    0x1c(%esp),%eax
   0x08048466 <+25>:    mov    %eax,0x4(%esp)
   0x0804846a <+29>:    movl   $0x8048555,(%esp)
   0x08048471 <+36>:    call   0x8048320 <scanf@plt>
   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 <puts@plt>
   0x0804848d <+64>:    jmp    0x804849b <main+78>
=> 0x0804848f <+66>:    movl   $0x8048569,(%esp)
   0x08048496 <+73>:    call   0x8048310 <puts@plt>
   0x0804849b <+78>:    mov    $0x0,%eax
   0x080484a0 <+83>:    leave  
   0x080484a1 <+84>:    ret 

ce que j’essaie d’examiner, c’est $ 0x208c. Lorsque je tape x/xw 0x208c, cela me renvoie une erreur qui dit Impossible d'accéder à la mémoire à l'adresse 0x208c. Quand je tape Info enregistre et regarde eax, il dit la valeur que j’ai fournie. Donc, fondamentalement, ce programme compare deux valeurs et en fonction de l’impression, le problème est qu’il s’agit d’un devoir de l’université et que je n’ai pas de code. J'espère que vous pourrez aider. Je vous remercie.

11
Ojs

Quand je tape x/xw 0x208c, cela me renvoie une erreur qui dit Cannot access memory at address 0x208c

Le désassemblage de votre programme indique qu'il fait quelque chose comme ceci:

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 { ... }

En d'autres termes, le 0x208c est une valeur (8332) que votre programme a codée en dur, et est pas un pointeur. Par conséquent, GDB a tout à fait raison de vous dire que si vous interprétez 0x208c comme un pointeur, ce pointeur ne pointe pas vers la mémoire lisible.

j'ai finalement compris d'utiliser print statement au lieu de x/xw

Vous semblez ne pas comprendre la différence entre les commandes print et examine. Considérons cet exemple:

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

Avec ce qui précède, print pfoo vous donnera le adresse de foo et x pfoo vous donnera la valeur stockée à cette adresse (c'est-à-dire la valeur de foo). 

14

J'ai découvert qu'il est impossible d'examiner la mémoire mmaped qui n'a pas l'indicateur PROT_READ. Ce n'est pas le problème des PO, mais c'était le mien et le message d'erreur est le même.

Au lieu de

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

faire

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

et voila, la mémoire peut être examinée.

3
user7610

Dans mon cas, le problème a été causé en appelant munmap avec une longueur supérieure à mmap: 

#include <errno.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
int main(){
    size_t length_alloc = 10354688;
    size_t length_unmap = 5917171456;
    void *v = mmap(0, 10354688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 
    if (v == MAP_FAILED) {
            printf("mmap of %lu bytes failed with error: %s", 10354688, strerror(errno));
    }else{
            printf("mmaped %p\n", v); 
            munmap(v, length_unmap);
    }   

}

Ainsi, le mappage unmap non mappé correspond également aux piles de quelques threads. Assez méchant, car il rendait le core dump impossible à utiliser avec mon niveau actuel. Surtout que dans le problème original, la taille transmise à munmap était quelque peu aléatoire. Et cela ne s'est produit que parfois et à la fin d'un très long processus. 

0
Jacek Tomaka

Pointeurs non initialisés

C'est assez évident en rétrospective, mais c’est ce qui a amené GDB à afficher ce message d’erreur. Le long de:

#include <stdio.h>

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

Et alors:

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

Mais dans un programme complexe, bien sûr, et où l'adresse était quelque chose de différent du zéro, au hasard.