您将获得在运行时崩溃的应用程序的源代码。在调试器中运行10次后,您发现它永远不会在同一个地方崩溃。该应用程序是单线程的,仅使用C标准库。哪些编程错误可能导致此崩溃?你会如何测试每一个?
答案 0 :(得分:15)
您的代码可以调用C标准中未定义行为的任何内容,包括(但不限于):
列表很长,但C规范中的附件J.2提供了未定义行为的简明列表。
答案 1 :(得分:9)
一般情况下,可能存在其他过程的情况。请注意,您说只有您的程序是单线程的,其他程序可以并行运行。
答案 2 :(得分:3)
简单:无限循环。只有在调用堆栈溢出时才会崩溃,这可能发生在任何地方,具体取决于调用堆栈可用的内存量。
答案 3 :(得分:2)
如果您认为存在单个错误且应用程序在不同位置崩溃,则可能是悬空指针。访问已经释放的内存将为您提供垃圾值(在大多数情况下可能是段错误),它们将在应用程序创建和破坏变量并执行内存操作时看似随机覆盖。这可能就像缺少malloc
或free
一样容易。
但是,如果第一次尝试没有揭示问题的根源,我根本不打扰调试应用程序。如果一个应用程序在十个不同的地方崩溃,当应用程序使用看似无关的数据时,作者肯定已经编写了大量的代码而没有在此过程中编译和测试它,现在很无奈,因为一个错误导致另一个错误。我会礼貌地要求应用程序的程序员与自己进行交往,并在完成后,从头开始重写错误的代码,编译和测试每几行。
答案 4 :(得分:1)
他们正在寻找的答案是使用未初始化的变量,并取决于它是否为默认值。 E.g:
int a; // default value 0
int b[10];
int main() {
for (;a++;a<10) {
b[a] = 0;
}
}
调试时不会崩溃,因为您调试了未经优化的代码,因此将应用默认值。起始为0. Gcc -O3或-Os没有出错,但是不会初始化该值,使其成为随机值,非常不可能为0,并且b [a]将增加地址(在“平均值”中)案例“,警告适用”,直到数据段之外,导致SIGSEGV。
虽然会有关于此的编译器警告。
依靠链接属性,您可以更加难以理解这个问题。 (查看“static int c”在全局范围内的作用)。