在调试中查找地址信息

Tim*_*Tim 3 memory debugging gdb

我正在学习用gdb解决一些运行时错误.这是我的问题:

  1. 当由于某些内存的某些访问操作发生冲突而发生运行时错误时,我可以在转储核心中找到该内存的地址吗?

  2. 给定一个地址,是否有可能找出哪个变量正在使用它(地址可能位于变量内存的开头,结尾或中间)?

  3. 给定变量使用的内存,是否有可能在其下方及其正上方找到附近的变量?

感谢致敬!

Emp*_*ian 6

  1. 通常是的.假设您的程序由于SIGSEGV 并留下了核心转储而在GDB外部崩溃,您可以:
    A:找出实际导致访问冲突的指令:

        (gdb) x/i $pc
    
    Run Code Online (Sandbox Code Playgroud)

    这通常是存储器访问指令,例如"movl $1,8(%eax)".重要的是那个应该指向有效内存的寄存器有什么价值.
    B.找出该登记册的价值:

       (gdb) p/x $eax
    
    Run Code Online (Sandbox Code Playgroud)

    通常这将是0(您正在通过NULL指针写入)或一些无意义的值,例如 0x32314043(您已损坏指针,或用ASCII字符串覆盖它 ).

  2. GDB "info symbol"命令将告诉您哪个符号(如果有)靠近给定地址.

  3. "info symbol"对于"target"变量的地址略小且略大的地址,请使用相同的命令.

更新:
info symbol不在本地(自动)变量的工作方式,因为这样的变量没有与之关联的(符号表)标志.

要查找有关局部变量的信息,请执行"info locals".然后,您可以打印他们的地址

(gdb) print &a_local_variable
Run Code Online (Sandbox Code Playgroud)

我不知道有什么方法可以做反向(即将局部变量的地址映射回其符号名称).但是,如果您只有少数本地人,那么通过"手动"将地址映射到其中一个地址通常是微不足道的.如果你有太多的本地人,这是一个糟糕的"代码味道" - 你应该重构你的代码,这样你就不会.