2015-12-09 30 views
1

我有一种情况,我运行了一些单元测试,其中一个触发了分段错误。这个症状似乎与另一个测试用例在失败之前运行大约30个测试用例有关。很明显,测试用例之间存在一定的依赖关系,我可以通过注释掉早期的测试用例来轻松地打开和关闭分段错误。 Google Test/Mock 1.6.0被用作测试框架。测试二进制文件完全用C++编写(gcc 4.6.3)。它是单线程的(除非Google Test创建线程)。为什么分段错误在gdb中不可重现?

但是,当我在gdb中运行所有测试用例时,没有出现分段错误,这让我很困惑。

为什么在终端中运行二进制文件时会出现段错误,但在通过gdb运行相同的二进制文件时不会出现分段错误?我猜gdb运行代码时一切都会稍微慢一点,但我不明白这会如何影响结果。

我只是这样做,看看无故障:

gdb MyBinary 
run 

最后终端打印的行:

[ PASSED ] 368 tests. 
[Inferior 1 (process 28349) exited normally] 

而这款以查看故障:

MyBinary 

最后一行终端打印输出:

Segmentation fault 
+1

在发现错误之前,您可能不会有任何想法。只要你能以某种方式重现这个错误,你就不应该太在意它发生的情况,直到你有理由认为它是重要的。 –

+0

你可以尝试运行valgrind下的单元测试来查看它设​​法检测到的内存错误。 –

+0

顺便说一句,你可以将核心转储大小限制在一个合理的数值上(例如至少500M字节)并在'core'上运行'gdb'后验概率 –

回答

5

为什么在终端中运行二进制文件时会出现段错误,而不是在通过gdb运行相同的二进制文件时会出现段错误?

两种最常见的有:

  1. GDB禁用地址空间随机化。如果您正在读取一些未初始化的指针,并且该指针始终恰好在GDB下为NULL,但可能不是带有ASLR的NULL
  2. 你有一个数据竞赛,并且GDB减缓线程创建以隐藏该比赛(GDB必须做一个lot工作来跟踪所有线程)。

您可以通过set disable-randomization off阻止GDB禁用ASLR。

您应该使用MemorySanitizerThreadSanitizer检查您的测试。

相关问题