gdb地址和"真实"地址之间的区别?

Nos*_*tap 9 c c++ hex gdb memory-address

如果我在gdb运行C/C++程序(带-g标志编译后),我审查某些变量,参数...等的地址,然后我运行它GDB之外(使用./)将这些地址是和我在gdb中看到的相同?如果它们不同,它们通常是相似的,还是会有很大差异?

我问这个是因为我有一个缓冲区溢出程序在gdb中有效(有和没有断点),但是当我尝试在gdb之外运行它时它不起作用.

Emp*_*ian 10

我检查某些变量,参数等的地址,然后我在gdb之外运行它(使用./)这些地址是否与我在gdb中看到的相同

这取决于.

  1. 主可执行文件中定义的全局变量将保留在同一地址(除非可执行文件-fpie使用-pie标志构建并与之链接.
  2. 由于ASLR,在其他共享库中定义的全局变量可能具有截然不同的地址.
  3. 由于ASLR,局部变量和参数可能会移动几个K字节.
  4. 由于ASLR,或者如果您的程序是多线程的,堆分配的变量也可能会大幅移动.

请注意,默认情况下,Linux上的GDB禁用ASLR,以便更轻松地进行调试.您可以使用GDB重新启用ASLR set disable-randomization off.这可能允许您在GDB下重现问题.

我有一个缓冲区溢出

另请注意,ValgrindAddress Sanitizer等工具通常比在GDB下运行更有效地查找缓冲区溢出.地址消毒剂尤其是伟大的,因为它发现在全局和堆栈缓冲区溢出(Valgrind的没有).