我有一个与SIGSEGV崩溃的应用程序。
--20183-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--20183-- si_code=80; Faulting address: 0x0; sp: 0x409a8de60
valgrind: the 'impossible' happened:
Killed by fatal signal
==20183== at 0x38039981: vgPlain_arena_free (m_mallocfree.c:245)
==20183== by 0x38001E84: die_and_free_mem (mc_malloc_wrappers.c:124)
==20183== by 0x380688C3: vgPlain_scheduler (scheduler.c:1402)
==20183== by 0x380913F4: run_a_thread_NORETURN (syswrap-linux.c:95)
它必然会出现某种内存损坏,这会破坏malloc链,因为崩溃发生在随机位置 - 但总是在释放时。
通常您会看到如下消息:
Invalid write of size 8
表示我损坏内存的地方,但没有任何消息,只是立即崩溃。 AFAIK valgrind涵盖了大多数系统调用,因此它甚至会报告与这些调用相关的问题,所以...
我的理论(*)问题是:我应该寻找什么样的错误? valgrind无法检测到哪种无效写入?
(*):请不要问实际代码,正如我所说,这是一个理论问题。
附带问题:还有其他工具可以解决问题吗?
答案 0 :(得分:3)
仅检查堆上的分配,不检查全局/堆栈变量。
如果最终访问有效内存(另一个已分配的块),则不会捕获缓冲区溢出。对于以下示例,valgrind不报告溢出(当然这完全取决于您使用的内存分配器...):
int main() {
char* a = malloc(1024);
char* b = malloc(1024);
*(a+1600) = '!';
}
在我的案例中,valgrind的ptrcheck工具(--tool=exp-ptrcheck
)发现了问题。
答案 1 :(得分:2)
除非最近发生这种变化,否则Valgrind的Memcheck工具无法检测到覆盖堆栈数组的限制。这可能会导致Valgrind可能无法接受的各种有趣问题。
我做了一些挖掘,发现了一个名为Annelid的用户创建工具,它声称能够检测堆栈变量损坏。这可能有助于发现这些问题。
我对Valgrind内部的大多数经验都围绕着它的内存检查系统,因此其他人可能能够详细说明其他方面以及它能够和无法检测到的内容。