malloc sysmalloc 断言错误每隔一段时间

问题描述 投票:0回答:1

我正在 Linux 中使用消息队列和信号编写多处理 C 程序。有时终端会弹出以下错误。

错误:

scheduler.out:malloc.c:2617:sysmalloc:断言`(old_top == initial_top(av)&& old_size == 0)|| ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' 失败。

代码:

Process* stringtoProcess(char* str) {
    Process* p = malloc(sizeof(Process));
    sscanf(str, "%d %d %d %d %d %d %d %s", &p->id, &p->arrival, &p->startTime, &p->runtime, &p->priority, &p->WaitingTime, &p->remainingTime, p->state);
    return p;
}

void receiveProcess() {
    key_t key_up, key_down;
    int msgid_up, msgid_down;
    struct msgbuf buffer_up, buffer_down;
    key_up = ftok("keyfile", 'A');
    key_down = ftok("keyfile", 'Z');
    if (key_up == -1 || key_down == -1) {
        perror("ftok");
        exit(EXIT_FAILURE);
    }

    msgid_up = msgget(key_up, 0666 | IPC_CREAT);
    msgid_down = msgget(key_down, 0666 | IPC_CREAT);
    if (msgid_up == -1 || msgid_down == -1) {
        perror("msgget");
        exit(EXIT_FAILURE);
    }
    memset(&buffer_up, 0, sizeof(buffer_up));
    memset(&buffer_down, 0, sizeof(buffer_down));
    if (msgrcv(msgid_up, &buffer_up, sizeof(buffer_up.mtext), 5, !IPC_NOWAIT) == -1) {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }
    Process *p = stringtoProcess(buffer_up.mtext);
    TotalRunTime += p->runtime;
    if(FirstArrival == -1)
    FirstArrival = p->arrival;
    if(algo == 1)
        enqueue(ready_queue, p);
    else push(ready_queue, p, prio_flag);
    buffer_down.mtype = 5;
    if(msgsnd(msgid_down, &buffer_down, sizeof(buffer_down.mtext), 5) == -1) {
        perror("msgsend");
        exit(EXIT_FAILURE);
    }
}

这是流程结构

typedef struct Process {
    int id;
    int pid;
    int arrival;
    int startTime;
    int runtime;
    int priority;
    int WaitingTime;
    int remainingTime;
    char state[20];
    int Sent;
} Process;

receiveProcess 函数是一个信号处理程序,会连续调用多次(大约 1 - 5 次)。经过一些调试,我发现这个错误是在第三次或第四次进入该函数时发生的。

请记住,通常它根本不会发生。

c multiprocessing malloc signals message-queue
1个回答
0
投票

您的代码存在多个问题。

  1.  Process* stringtoProcess(char* str) {
         Process* p = malloc(sizeof(Process));
         sscanf(str, "%d %d %d %d %d %d %d %s", &p->id, &p->arrival, &p->startTime, &p->runtime, &p->priority, &p->WaitingTime, &p->remainingTime, p->state);
         return p;
     }
    

    这里有两个问题。您没有检查

    malloc()
    是否成功,而是将未初始化的内存写入
    str

  2. 如果我们将自己局限于 ISO C 标准,那么在信号处理程序中可以做的事情就很少了。但是,您的代码假定 POSIX 支持,因此我不会详细介绍。与 C 标准不同,POSIX 标准指定了很多函数为 async-signal-safe,但是

    ftok()
    perror()
    exit()
    msgget()
    msgrcv()
    malloc()
    sscanf()
    、 和
    msgsnd()
    不在其中。

    函数

    enqueue()
    push()
    也可能是异步信号不安全的。请注意,信号处理程序本身调用的函数不应调用异步信号不安全函数,这与
    stringtoProcess()
    不同,它调用
    malloc()
    sscanf()

  3. 信号处理程序的签名是:

    typedef void (*sighandler_t)(int);
    

    你的

    receiveProcess()
    功能不符合它。

  4. 您忽略了

    sscanf()
    的返回值,并且使
    Process
    结构体的两个成员未初始化。

© www.soinside.com 2019 - 2024. All rights reserved.