我相信你们中很多人都经历过。有时,在调试崩溃时,您添加了一行跟踪信息和中提琴,崩溃消失了。这通常表示内存损坏,并且您在代码周围寻找缓冲区溢出等。更具体地说,即使是单线程应用程序也是如此。
一条跟踪线如何防止崩溃发生?
跟踪线是一段代码,所以应该转到代码段,因为它是只读的?
它应该对本地执行堆栈没有影响吗?它如何影响指针偏移量以使其他一些内存被覆盖而无法自我体现(仍然很糟糕)。
最佳答案
几个人已经提到了时间变化。即使您的代码是单线程的,您也可能正在调用API来代表您启动线程,或实现某种其他形式的异步通信。
就此声明而言:
这取决于您的跟踪代码实际执行的操作。甚至很简单:
write(0, "Hello, World!\n", 14);
至少将为常量字符串添加额外的数据存储,这将转移其他常量数据的位置,并可能更改其他内存段的开始,从而也影响代码和/或堆的位置。如果这是对该函数的第一个引用,它将在对象文件中添加一个重定位记录,这可能导致内存布局发生其他变化。
例如,调用fwrite或printf的更复杂的跟踪调用几乎肯定会最终为临时缓冲区等分配一些内存。
如果您可以在调试器中运行时重现该错误(很明显带有原始代码),那么您至少应该能够确定触发该段错误的代码。如果调试器也导致错误不会发生,则可以考虑启用核心转储,并根据转储进行调试。
失败的话,您可以尝试使用调试的malloc包(有几种可用的包)运行代码。即使“错误”没有重现,您也可能会以这种方式发现一些不正确的指针操作。
最后建议:在编译器上启用所有警告的情况下重新编译代码,并认真考虑如此生成的所有警告。请注意,对于gcc,-Wall不会打开所有警告。
关于debugging - 调试段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1929780/