信号11 SIGSEGV在malloc?

时间:2013-12-07 18:59:47

标签: c memory-management segmentation-fault

我通常喜欢很好的解释问题和答案。但在这种情况下,我真的无法提供更多线索。

问题是:为什么malloc()给我SIGSEGV?调试后显示程序没有时间测试返回的指针为NULL并退出。该计划退出INSIDE MALLOC!

我假设我在glibc中的malloc很好。我有一个debian / linux wheezy系统,在旧的奔腾(i386 / i486拱门)中进行了更新。

为了能够跟踪,我生成了一个核心转储。让我们按照它:

iguana$gdb xadreco core-20131207-150611.dump

Core was generated by `./xadreco'.
Program terminated with signal 11, Segmentation fault.
#0  0xb767fef5 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) bt
#0  0xb767fef5 in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0xb76824bc in malloc () from /lib/i386-linux-gnu/libc.so.6
#2  0x080529c3 in enche_pmovi (cabeca=0xbfd40de0, pmovi=0x...) at xadreco.c:4519
#3  0x0804b93a in geramov (tabu=..., nmovi=0xbfd411f8) at xadreco.c:1473
#4  0x0804e7b7 in minimax (atual=..., deep=1, alfa=-105000, bet...) at xadreco.c:2778
#5  0x0804e9fa in minimax (atual=..., deep=0, alfa=-105000, bet...) at xadreco.c:2827
#6  0x0804de62 in compjoga (tabu=0xbfd41924) at xadreco.c:2508
#7  0x080490b5 in main (argc=1, argv=0xbfd41b24) at xadreco.c:604
(gdb) frame 2
#2  0x080529c3 in enche_pmovi (cabeca=0xbfd40de0, pmovi=0x ...) at xadreco.c:4519
4519        movimento *paux = (movimento *) malloc (sizeof (movimento));
(gdb) l
4516 
4517    void enche_pmovi (movimento **cabeca, movimento **pmovi, int c0, int c1, int c2, int c3, int p, int r, int e, int f, int *nmovi)
4518    {
4519        movimento *paux = (movimento *) malloc (sizeof (movimento));
4520        if (paux == NULL)
4521            exit(1);

当然我需要查看第2帧,这是与我的代码相关的最后一个堆栈。但4519行给出了SIGSEGV!如果paux == NULL,它没有时间在第4520行进行测试。

这是" movimento" (缩写):

typedef struct smovimento
{
    int lance[4];  //move in integer notation
    int roque; // etc. ...

    struct smovimento *prox;// pointer to next
} movimento;

该程序可以加载大量内存。我知道记忆力在极限。但我认为当内存不可用时,malloc会处理得更好。

在执行期间执行$free -h,我可以看到内存低至1MB!没关系。旧电脑只有96MB。操作系统使用50MB。

我不知道从哪里开始寻找。也许在malloc调用之前检查可用内存?但这听起来像计算机的力量,因为malloc应该这样做。 sizeof (movimento)约为48 bytes。如果我之前测试过,至少我会对这个bug有一些确认。

任何想法,请分享。感谢。

1 个答案:

答案 0 :(得分:2)

malloc(或free)内的任何崩溃几乎都是堆腐败的迹象,可以有多种形式:

  • 溢出或下溢堆缓冲区
  • 释放一些东西
  • 释放非堆指针
  • 写入释放区块

如果没有工具支持,这些错误很难被捕获,因为崩溃通常会导致数千条指令,以及之后可能需要多次调用mallocfree的代码。程序的不同部分,距离错误的地方很远。

好消息是像ValgrindAddressSanitizer这样的工具通常会直接指出问题。