5 题: gdb无法访问内存地址错误

在...创建的问题 Sat, May 9, 2015 12:00 AM

这是我的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时,它会显示我提供的值。所以基本上这个程序比较两个值,并根据打印出来的东西。问题是这是大学的家庭作业,我没有代码。希望你能帮忙。谢谢。

    
12
  1. [手指在空中]你传递的是非法参数?你坐在那里,在调试器前面。我们能做些什么,你不能,特别是没有源代码?这是一个非常奇怪的任务,要求你修复没有源代码的东西...
    2015-05-09 12:30:44Z
  2. 我终于想通了使用print语句代替x /xw你能解释为什么打印工作而x没有?
    2015-05-09 12:32:16Z
  3. $0x208c是绝对值,而不是内存地址!
    2015-05-09 12:57:03Z
  4. 醇>
    5答案                              5 跨度>                         
      

    当我输入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)。

        
    14
    2015-05-09 21:39:09Z

    我发现不可能检查没有mmap标志的PROT_READ ed内存。这不是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);
    

    瞧,可以检查记忆。

        
    3
    2016-01-08 18:28:15Z

    未初始化的指针

    回顾展中有一点显而易见,但这是导致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
    

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

        
    0
    2017-12-16 13:02:34Z

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

     
    #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);
        }   
    
    }
    

    因此unmap的映射也映射了几个线程的堆栈。非常令人讨厌,因为它使核心转储无法与我目前的技能水平一起使用。特别是在原始问题中,传递给munmap的大小有点随机。它有时只会崩溃,而且会在一个非常漫长的过程中结束。

        
    0
    2019-01-27 07:26:31Z

    如果GDB说未找到内存地址,则意味着该符号在gdb或文件exefilename打开的可执行文件中不可用。或者您还没有使用-g选项编译exefile。当您是gdb的新手时,您可能已经给出了命令文件argfile而不是运行argfile会发生什么。请检查。

        
    0
    2019-05-19 11:08:32Z
来源放置 这里