malloc()如何导致SIGSEGV?

use*_*745 8 c malloc gdb segmentation-fault

我的程序中有一个奇怪的错误,在我看来malloc()正在引起一个SIGSEGV,据我所知,这没有任何意义.我正在使用一个名为simclist的库来创建动态列表.

这是一个稍后引用的结构:

typedef struct {
    int msgid;
    int status;
    void* udata;
    list_t queue;
} msg_t;
Run Code Online (Sandbox Code Playgroud)

以下是代码:

msg_t* msg = (msg_t*) malloc( sizeof( msg_t ) );

msg->msgid = msgid;
msg->status = MSG_STAT_NEW;
msg->udata = udata;
list_init( &msg->queue );
Run Code Online (Sandbox Code Playgroud)

list_init 程序失败的地方,这里是list_init的代码:

/* list initialization */
int list_init(list_t *restrict l) {
    if (l == NULL) return -1;

    srandom((unsigned long)time(NULL));

    l->numels = 0;

    /* head/tail sentinels and mid pointer */
    l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
    l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
    l->head_sentinel->next = l->tail_sentinel;
    l->tail_sentinel->prev = l->head_sentinel;
    l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL;
    l->head_sentinel->data = l->tail_sentinel->data = NULL;

    /* iteration attributes */
    l->iter_active = 0;
    l->iter_pos = 0;
    l->iter_curentry = NULL;

    /* free-list attributes */
    l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *));
    l->spareelsnum = 0;

#ifdef SIMCLIST_WITH_THREADS
    l->threadcount = 0;
#endif

    list_attributes_setdefaults(l);

    assert(list_repOk(l));
    assert(list_attrOk(l));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该行l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS *是根据堆栈跟踪引起SIGSEGV的位置.我正在使用gdb/nemiver进行调试,但我不知所措.第一次调用此函数时,它可以正常工作但第二次总是失败.malloc()如何导致SIGSEGV?

这是堆栈跟踪:

#0  ?? () at :0
#1  malloc () at :0
#2  list_init (l=0x104f290) at src/simclist.c:205
#3  msg_new (msg_switch=0x1050dc0, msgid=8, udata=0x0) at src/msg_switch.c:218
#4  exread (sockfd=8, conn_info=0x104e0e0) at src/zimr-proxy/main.c:504
#5  zfd_select (tv_sec=0) at src/zfildes.c:124
#6  main (argc=3, argv=0x7fffcabe44f8) at src/zimr-proxy/main.c:210
Run Code Online (Sandbox Code Playgroud)

非常感谢任何帮助或见解!

laa*_*lto 26

malloc例如,当堆损坏时,可以进行段错误.检查您是否在编写任何超出先前分配范围的内容.

  • 并使用valgrind!其他海报提到了这个工具,但遗憾的是没有得到很多赞成.这个答案没有错,但任何关于记忆腐败的讨论都是不完整的,没有使用valgrind的警告! (20认同)
  • 在调用free()时我得到了一个sigsegv.我在valgrind下运行代码,它表明我已经写了超出缓冲区并损坏了堆. (2认同)

use*_*818 17

可能在代码的其他部分发生内存冲突.如果你在Linux上,你一定要试试valgrind.我永远不会相信我自己的C程序,除非它通过valgrind.

编辑:另一个有用的工具是电围栏.Glibc还提供MALLOC_CHECK_环境变量来帮助调试内存问题.这两种方法不像valgrind那样影响运行速度.


sth*_*sth 12

您可能在此调用之前通过缓冲区溢出或free使用未分配malloc(或已经释放)的指针调用来损坏您的堆.

如果malloc使用的内部数据结构以这种方式被破坏,则malloc使用无效数据并可能崩溃.