为什么分段错误在 gdb 中不可重现?
Why is a segmentation fault not reproducible in gdb?
我有这样一种情况,我 运行 进行了一些单元测试,其中一个触发了分段错误。该症状似乎与另一个测试用例 运行 有关,在失败的测试用例之前大约有 30 个测试用例。显然,测试用例之间存在某种依赖关系,我可以通过注释掉较早的测试用例来轻松打开和关闭分段错误。 Google Test/Mock 1.6.0 用作测试框架。测试二进制文件完全用 C++ (gcc 4.6.3) 编写。它是单线程的(除非 Google 测试创建线程)。
然而,当我 运行 gdb 中的所有测试用例都没有分段错误时,这就是让我困惑的地方。
在终端中 运行 运行二进制文件时会出现分段错误,但在通过 gdb 运行 运行完全相同的二进制文件时却不会出现分段错误的现实原因是什么?我想当 gdb 运行s 代码时,一切都会稍微慢一些,但我不明白这会对结果产生什么影响。
我这样做只是为了看不出错:
gdb MyBinary
run
终端打印输出的最后几行:
[ PASSED ] 368 tests.
[Inferior 1 (process 28349) exited normally]
而这个看错了:
MyBinary
终端打印输出的最后一行:
Segmentation fault
What are realistic reasons why there would be a segmentation fault when running a binary in a terminal, but not when running the very same binary through gdb?
最常见的两个是:
- GDB 禁用地址 space 随机化。如果您正在读取一些未初始化的指针,并且该指针在 GDB 下总是恰好是
NULL
,但在 ASLR 中可能不是 NULL
。
- 您有数据竞争,GDB 减慢线程创建速度以隐藏该竞争(GDB 必须做 很多 工作来跟踪所有线程)。
您可以使用 set disable-randomization off
阻止 GDB 禁用 ASLR。
您应该使用 MemorySanitizer and ThreadSanitizer.
检查您的测试
我有这样一种情况,我 运行 进行了一些单元测试,其中一个触发了分段错误。该症状似乎与另一个测试用例 运行 有关,在失败的测试用例之前大约有 30 个测试用例。显然,测试用例之间存在某种依赖关系,我可以通过注释掉较早的测试用例来轻松打开和关闭分段错误。 Google Test/Mock 1.6.0 用作测试框架。测试二进制文件完全用 C++ (gcc 4.6.3) 编写。它是单线程的(除非 Google 测试创建线程)。
然而,当我 运行 gdb 中的所有测试用例都没有分段错误时,这就是让我困惑的地方。
在终端中 运行 运行二进制文件时会出现分段错误,但在通过 gdb 运行 运行完全相同的二进制文件时却不会出现分段错误的现实原因是什么?我想当 gdb 运行s 代码时,一切都会稍微慢一些,但我不明白这会对结果产生什么影响。
我这样做只是为了看不出错:
gdb MyBinary
run
终端打印输出的最后几行:
[ PASSED ] 368 tests.
[Inferior 1 (process 28349) exited normally]
而这个看错了:
MyBinary
终端打印输出的最后一行:
Segmentation fault
What are realistic reasons why there would be a segmentation fault when running a binary in a terminal, but not when running the very same binary through gdb?
最常见的两个是:
- GDB 禁用地址 space 随机化。如果您正在读取一些未初始化的指针,并且该指针在 GDB 下总是恰好是
NULL
,但在 ASLR 中可能不是NULL
。 - 您有数据竞争,GDB 减慢线程创建速度以隐藏该竞争(GDB 必须做 很多 工作来跟踪所有线程)。
您可以使用 set disable-randomization off
阻止 GDB 禁用 ASLR。
您应该使用 MemorySanitizer and ThreadSanitizer.
检查您的测试