C ++堆损坏和valgrind

时间:2016-08-04 09:18:51

标签: c++ linux solaris core

我在Solaris / Linux平台上都有一个核心,我没有看到问题。 在Linux平台上,我有以下核心:

$ pstack core.ultimo
core 'core.ultimo' of 9220:     my_project_sun
-----------------  lwp# 1 / thread# 1  --------------------
 0006fa28 __1cDstdGvector4CpnMDistribuidor_n0AJallocator4C2___Dend6kM_pk2_ (1010144, 1ce84, ffbd0df8, ffb7a18c, fffffff8, ffbedc7c) + 30
 0005d580 __1cDstdGvector4CpnMDistribuidor_n0AJallocator4C2___Esize6kM_I_ (1010144, 219, 1ce84, ffffffff, fffffff8, ffbedc7c) + 30
 0005ab14 __1cTReceptorHreceive6MrnKMensaje__v_ (33e630, ffbede70, ffffffff, 33e634, 33e68c, 0) + 1d4
 0015df78 __1cREventProcessorDrun6M_v_ (ffbede18, 33e630, dcc, 1, 33e730, 6e) + 350
 00159a50 __1cWSEventProcessorDrun6M_v_ (da08000, 2302f7, 111de0c, 159980, ff1fa07c, cc) + 48
 000b6acc main     (1, ffbeef74, ffbeef7c, 250000, 0, 0) + 16c
 00045e10 _start   (0, 0, 0, 0, 0, 0) + 108
-----------------  lwp# 2 / thread# 2  --------------------

在Solaris平台上,我有另一个核心:

...
msj2.tipo(UPDATE);
for(i = 0; i < distr.size(); ++i)
{
    distr[i]->insert(new Mensaje(msj2)); **--> Receptor.cc:477**

}
...

...

这段代码是:

==19002== Syscall param semctl(arg) points to uninitialised byte(s)

这个核心是随机发生的,有时这个过程会运行数周。 核心的大小是4291407872 B.

我正在运行valgrind以查看堆是否已损坏但是现在我没有遇到“无效读取”,“无效写入”等问题... 此外,当我运行valgrind时,我发现了以下消息的两倍:

{{1}}

我已经检测到了代码行,但这些错误是否可以导致核心?我认为我之前已经看过valgrind的这些错误,并且它们并不那么重要,而且说“读/写无效”。

如果你有任何想法如何解决这个问题,我们将非常感激。

2 个答案:

答案 0 :(得分:3)

核心大小是线索。最大的32位无符号数是4,294,967,295。你的核心非常接近,表明进程内存不足。最可能的原因是内存泄漏。

请参阅我最近的文章Memory Leaks in C/C++

Valgrind将在Linux上找到适合您的问题。您必须使用--leak-check选项启动它。当进程正常退出时,它将检查泄漏,因此您需要一种方法来关闭进程。

在Solaris上使用dbx的Dtrace也可能有效。

答案 1 :(得分:1)

  

另外,当我运行valgrind时,我发现了以下两次   消息:

==19002== Syscall param semctl(arg) points to uninitialised byte(s)
     

我已经检测到代码行,但这些错误可能导致   核心?

是的,这可能会导致SIGSEGV,因为它很可能是未定义的行为。 (在没有看到实际代码的情况下,我不会说它肯定是未定义的行为 - 但它可能是。)它不是可能这样做会导致SIGSEGV,但是你所看到的间歇性失败并不会经常发生。所以你确实需要解决这个问题。

除了valgrind之外,在Solaris上还可以使用libumemwatchmalloc来检查管理堆内存的问题。请参阅umem_debugwatchmalloc的手册页以开始使用。

要在Solaris上使用dbx,您需要安装Solaris Studio(它是免费的)。 Solaris Studio还提供了一种使用dbx的运行时内存检查的方法,而无需直接调用dbx调试器。请参阅bcheck的手册页。 bcheck手册页将位于man目录中的Solaris Studio安装目录树中。

如果是内存泄漏,您应该能够看到进程地址空间随着时间的推移而增长。