对于在RHEL5 32bit下运行的自定义程序,我有一个非常奇怪的问题。
这是一个用C编写的商业程序,因此我没有源代码。无论如何,当我运行这个程序大约50%的时间时,我随机地得到了分段错误(信号11)。例如。当我使用相同的参数和条件运行该程序10次时,5次给出信号11,5次成功完成。
我将ulimit
设置为无限制以收集核心转储。我能够获取核心转储文件并激活gdb以查看回溯。我可以看到程序停止在错误之前调用哪个函数的位置。
我在gdb下启动了这个程序: gdb [程序名],然后输入"运行[parameter1] [parameter2] ..."
然后我得到"程序正常退出。"
我得到了结果(文本文件)没有任何问题。由于此信号11是随机发生的,所以我在gdb下运行该程序100次。 完全没有错误。
我回去正常运行这个程序。核心转储。
所以我的问题很简单: 我正常运行此程序有什么区别,我在gdb下运行它?我真的无法弄清楚为什么它只能在gdb下完美运行,但在正常情况下会随机出错。
$ uname -a
Linux vsapvm01 2.6.18-398.el5PAE #1 SMP Mon Sep 15 23:05:28 PDT 2014 i686 i686 i386 GNU/Linux
答案 0 :(得分:2)
调试器有时会导致程序的行为方式不同。以下是一些可能的方法:
任何这些问题都可能导致程序在GDB下进行测试时表现不同;调查后消失的错误(例如使用调试器)通俗地称为heisenbugs。
所以你想知道什么可能导致程序在正常运行时50%的时间崩溃,但每次都在调试器下工作?请允许我介绍一下这个小宝石,它在x86-64 Linux上运行正常时会以50%的概率崩溃,但每次调试都会成功运行:(至少在我的测试机器上)
#include <stdio.h>
#include <stdlib.h>
int main() {
int *x = malloc(256);
printf("%d\n", *(int *)((unsigned long long)x & ~0x1000));
}
这利用了ASLR和固定内存映射(上面的第二点) - 在随机化下,清除x
的第12位会使程序崩溃一半,但是没有随机化(在GDB下),第12位将始终一直都很清楚。 (这仅用于说明目的;我并未声称您的软件存在如此明显的错误!)