背景
我正在开发一个程序,其中一个线程从主线程中分离出来,解析电子邮件日志并按 QID 组织每个条目,QID 是每条消息唯一的 ID。
问题
该程序一直在工作,直到我重新组织它,而不是首先将整个日志文件加载到内存中,而是在读取日志文件时开始解析每一行。该程序将在下面显示的代码片段中进行 SIGABRT(稍微简化但演示了相同的问题)。
调试结果
gdb 将声称它是(取决于运行)realloc/free 无效大小或 realloc/free 损坏内存,而 valgrind 始终声称一个非空终止数组导致运行溢出并损坏堆(我认为这更有可能是案例但找不到问题)。(如果您希望我分享 valgrind 或 gdb 的原始输出,请告诉我)。
void *parseMessageAndMatch(void *params) {
// get params passed in from parent thread
parse_params *rp = (parse_params *)params;
// len0: length of log dump for current QID
// len1: length of log dump after current buffer is appended
int len0, len1;
// tmp char pointer for log dump
char *tmp;
// 1. increase/allocate memory for log dump and append line buffer
// get length of current log dump (0 if NULL)
// dump is of type char* and contains the log lines pertaining to a certain QID
len0 = (!msgs.msgs[rp->index].dump) ? 0 : strlen(msgs.msgs[rp->index].dump);
// get length of log dump after current line buffer is appended
// rp->len contains the strlen of the line buffer
len1 = len0 + rp->len + 1;
// allocate space for tmp log dump
// lock becaus msgs is a global variable and there is more than one thread
pthread_mutex_lock(rp->mutex);
if ((tmp = realloc(msgs.msgs[rp->index].dump, sizeof(*tmp)*len1)) == NULL) {
printf("Cannot allocate memory for log dump.\n");
exit(-1);
}
// update pointer
msgs.msgs[rp->index].dump = tmp;
// set tmp to null
tmp = NULL;
// if original buffer was empty, zero it out for safety
if (len0 == 0)
bzero(msgs.msgs[rp->index].dump, sizeof(char)*len1);
// rp->line is malloc'ed then bzero'ed and strcpy'ed to contain the log line read from file
strcat(msgs.msgs[rp->index].dump, rp->line);
msgs.msgs[rp->index].dump[len1-1] = '\0'; // add null terminator
pthread_mutex_unlock(rp->mutex);
// more parsing code is here but was commented out during my debug process
// so I have omitted it from this code snippet
// free line buffer
free(rp->line);
// set to null to prevent double free
rp->line = NULL;
// free params
free(rp);
// prevent double free
rp = NULL;
}
编辑
在下面的答案中进行了更正。