2

我有一个与 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 无法检测到什么样的无效写入?

(*):请不要询问实际代码,正如我所说,这是一个理论问题。

附带问题:还有其他工具可以解决问题吗?

4

2 回答 2

3

只检查堆上的分配,不检查全局/堆栈变量。

如果最终访问有效内存(另一个分配的块),则不会捕获缓冲区溢出。对于以下示例 valgrind 不会报告溢出(当然这完全取决于您使用的内存分配器......):

int main() {
    char* a = malloc(1024);
    char* b = malloc(1024);
    *(a+1600) = '!';
}

就我而言,valgrind 的 ptrcheck 工具 ( --tool=exp-ptrcheck) 发现了问题。

于 2012-11-23T16:34:23.897 回答
2

除非最近发生了变化,否则 Valgrind 的 Memcheck 工具无法检测覆盖堆栈数组边界。这可能会导致 Valgrind 可能无法解决的各种有趣的问题。

我做了一些挖掘,发现了一个名为Annelid的用户创建的工具,它声称能够检测堆栈变量损坏。这可能有助于发现此类问题。

我对 Valgrind 内部结构的大部分经验都围绕它的内存检查系统展开,因此其他人可能能够详细说明它的其他方面以及它可以检测到和不能检测到的内容。

于 2012-11-14T14:15:12.433 回答