debugging 我在使用GDB时遇到问题-“无法插入断点”和“无法访问内存”- ASLR?

a64a0gku  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(171)

我昨天在图书馆开发一个小程序时遇到了一些问题,我想我应该学会如何使用与Code::Blocks一起安装的调试器,我认为它工作正常。我很快意识到调试器返回1而不是成功运行,在启用完整的调试器日志后,我意识到正在显示警告,说明调试器在插入断点和访问一个内存地址。我很快写了一个简单的“Hello World”程序,带有一个条件语句,试图使用调试器在断点处对语句进行求值,并收到了同样的警告。

#include <iostream>

using namespace std;

int main()
{
    if(1)
    {
        cout << "Hello world!" << endl;
    }
    return 0;
}

因此,对于第7行的断点,我收到了调试器无法插入断点1的警告,并且无法访问地址0x140017dd处的内存。经过短暂的研究,我很快发现这可能是涉及PIC/PIEs(独立可执行代码/可执行文件)和ASLR(地址布局随机化)的问题;并且我可以通过命令行的方式禁用gdb内的虚拟地址空间随机化。不幸的是,我很快发现通过gdb禁用虚拟地址空间的随机化是“在[我的]平台上不受支持的”--Windows 11。现在,我已经通过Windows Security中的漏洞利用保护设置禁用了此功能,尽管我在Code::Blocks中没有发现gdb成功的解决方案。我也知道这不是关于gdb版本的问题,因为version 8.1返回与version 12.1相同的关于平台的错误消息。
有没有一个简单的解决方案可以解决这个问题,或者有没有其他的调试器可以使用?我计划在不久的将来深入研究通过命令行进行编译和调试的细节(包括汇编代码的阅读等等)但是我还不希望过渡到Linux。如果任何人有建议或者在正确的方向上有一点,我将不胜感激。
EDIT:向注册表添加MoveImages值也不起作用。EDIT2:以下是调试器日志:

Setting breakpoints

[debug]>>>>>>cb_gdb:
[debug]> show version
[debug]GNU gdb (GDB) 8.1
[debug]Copyright (C) 2018 Free Software Foundation, Inc.
[debug]License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[debug]This is free software: you are free to change and redistribute it.
[debug]There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
[debug]and "show warranty" for details.
[debug]This GDB was configured as "x86_64-w64-mingw32".
[debug]Type "show configuration" for configuration details.
[debug]For bug reporting instructions, please see:
[debug]<http://www.gnu.org/software/gdb/bugs/>.
[debug]Find the GDB manual and other documentation resources online at:
[debug]<http://www.gnu.org/software/gdb/documentation/>.
[debug]For help, type "help".
[debug]Type "apropos word" to search for commands related to "word".
[debug]>>>>>>cb_gdb:
[debug]> set confirm off

Debugger name and version: GNU gdb (GDB) 8.1

[debug]>>>>>>cb_gdb:
[debug]> set width 0
[debug]>>>>>>cb_gdb:
[debug]> set height 0
[debug]>>>>>>cb_gdb:
[debug]> set breakpoint pending on
[debug]>>>>>>cb_gdb:
[debug]> set print asm-demangle on
[debug]>>>>>>cb_gdb:
[debug]> set unwindonsignal on
[debug]>>>>>>cb_gdb:
[debug]> set print elements 200
[debug]>>>>>>cb_gdb:
[debug]> set new-console on
[debug]>>>>>>cb_gdb:
[debug]> set disassembly-flavor att
[debug]>>>>>>cb_gdb:
[debug]> directory ../CODEBL~1/DEBUGT~1/
[debug]Source directories searched: ../CODEBL~1/DEBUGT~1;$cdir;$cwd
[debug]>>>>>>cb_gdb:
[debug]> break "../CodeBlocks Projects/Debug Testing/main.cpp:7"
[debug]Breakpoint 1 at 0x1400017dd: file ..\CodeBlocks Projects\Debug Testing\main.cpp, line 7.
[debug]>>>>>>cb_gdb:
[debug]> run
[debug]Starting program: ..\CODEBL~1\DEBUGT~1\bin\Debug\DEBUGT~1.EXE 

Child process PID: 3916

[debug][New Thread 3916.0x27e8]
[debug][New Thread 3916.0x1f0]
[debug][New Thread 3916.0x1a40]
[debug]Warning:
[debug]Cannot insert breakpoint 1.
[debug]Cannot access memory at address 0x1400017dd
[debug]Command aborted.
[debug]>>>>>>cb_gdb:
[debug]> info frame

Debugger finished with status 1
2w3kk1z5

2w3kk1z51#

我建议这是一个基本的优化问题,它不能被禁用。看看这个Compiler Explorer example。(标志:-g -O0,gcc 12.2和Clang 15.0.0的行为相似)
在我的第一个函数中,if(true)从程序集中完全消失。

void hello1()
{
    if(true)
    {
        cout << "Hello world!" << endl;
    }
}

而在第二个示例中,功能上等效的bool b = true; if(b)产生实际的指令。

void hello2()
{
    bool b = true;
    if(b)
    {
        cout << "Hello world!" << endl;
    }
}

有趣的是,如果我将b设为const,则if不再出现。
hello2中的代码再试一次,因为我认为您的问题是要求gdb在没有指令的行处中断。

相关问题