gdb无法访问内存地址错误

时间:2015-05-09 11:28:16

标签: c gdb

这是我的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 

我要检查的是$ 0x208c。当我输入x / xw 0x208c时,它会给我一个错误,表示无法访问地址0x208c的内存。当我输入Info寄存器并查看eax时,它会显示我提供的值。所以基本上这个程序比较两个值,并根据打印出来的东西。问题是这是大学的家庭作业,我没有代码。希望你能帮忙。谢谢。

6 个答案:

答案 0 :(得分:14)

  

当我输入x/xw 0x208c时,它会返回错误,其中显示Cannot access memory at address 0x208c

你的程序的反汇编说它做了这样的事情:

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

换句话说,0x208c是您的程序在其中硬编码的值(8332),并且不是指针。因此,GDB完全正确地告诉您如果将0x208c解释为指针,则该指针不指向可读内存。

  

我终于想通了使用print语句而不是x / xw

您似乎不理解printexamine命令之间的区别。考虑这个例子:

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

如上所述,print pfoo将为您提供foo地址x pfoo将为您提供该地址(即foo的值)。

答案 1 :(得分:3)

我发现无法检查没有mmap标志的PROT_READ内存。这不是OP的问题,但它是我的,并且错误信息是相同的。

而不是

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

DO

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

瞧,可以检查记忆。

答案 2 :(得分:0)

未初始化的指针

回顾展中有一点显而易见,但这是导致GDB向我显示错误信息的原因。沿着:

#include <stdio.h>

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

然后:

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

但是在一个复杂的程序中,当然地址是零随机的。

答案 3 :(得分:0)

在我的情况下,此问题是由调用长度大于mmap的munmap引起的:

basicid alertType   alertTypeId alertDescription    macId     timeStamp   companyId     alertName            alertCondition  unitType   channelType  alertValue expectedValue
1295     409            127         testalert       13448   1547722123000   1234     test alert name            testalert   Centimeters   length        50.2        60.3
1238     408            123         testalert       13446   1548148705000   1234     test alert name            testalert   Centimeters   length        50.2        60.3
1256     409            128         testalert       13448   1548135899000   1234     test alert name            testalert   Centimeters   length        50.2        60.3

因此,unmap也取消映射一些线程堆栈的映射。这很讨厌,因为它使核心转储无法以我当前的技能水平使用。特别是在最初的问题中,传递给munmap的大小有些随机。它仅在某些时候崩溃,并且是一个非常漫长的过程的结束。

答案 4 :(得分:0)

如果GDB表示未找到内存地址,则表示该符号在gdb打开的可执行文件或通过exefilename文件中不可用。或者您尚未使用-g选项编译exefile。当您是gdb的新手时,可能会给命令文件argfile而不是运行argfile。请检查。

答案 5 :(得分:0)

我遇到了同样的错误。我通过使用Gparted软件增加交换空间解决了我的问题。 1-首先使用“ sudo apt-get install gparted”安装Gparted 2-打开Gparted,右键单击交换,然后选择“调整大小/移动” (注意:只有在交换内存之前或之后有未分配的内存,您才能增加交换大小)