malloc和snprintf总线核心转储

时间:2013-04-09 15:15:27

标签: c++ c unix malloc solaris

以前工作的功能,突然拒绝合作。更准确地说,这个片段:

    //If not, add to UIDS
    printf("line 78\n");
    free(s2);
    printf("line 82\n");
    char * ss = malloc(snprintf(NULL, 0, "%s:%d", myUIDs, userId) + 1);
    printf("line 84\n");
    sprintf(ss, "%s:%d", myUIDs, userId);
    free(myUIDs);
    myUIDs=ss;
    free(buffer);

程序在“第82行”(不再是第82行,但只是一个调试停止)之后使用Segmentation Fault (core dumped)失败了一行。 如果我改变

char * ss = malloc(snprintf(NULL, 0, "%s:%d", myUIDs, userId) + 1);

char * ss = malloc(snprintf(NULL, 0, "%s:%d", "", 1) + 1);

我得到了Bus Error: Code dumped。我正在研究这个程序很长一段时间,我觉得这很明显,我因为精疲力竭而不断忽视,但此时没有程序员朋友请求帮助。

上下文的整个功能:

char* myUIDs; //string containing all UID-s, separated by colon

void printProcessInformation(char pid[],int isSetP, int isSetN, int isSetU){
//find full path name to your "stat" file
//DIR *dir;
//struct dirent *ent;
//Creating string with /proc/PID
char * s = malloc(snprintf(NULL, 0, "%s%s", "/proc/", pid) + 1);
sprintf(s, "%s%s", "/proc/", pid);
//Creating string with /proc/PID/psinfo (full path)
char * fullPath = malloc(snprintf(NULL, 0, "%s%s", s, "/psinfo") + 1);
sprintf(fullPath, "%s%s", s, "/psinfo");
free(s);
//printf("%s\n",fullPath);

//Reading data from file
FILE* file = fopen(fullPath, "r");
printf("line 37\n");
char* buffer;
buffer = (char*) malloc(sizeof(psinfo_t));
printf("line 40\n");
if(file == NULL)
{
    //perror("Error: Couldn't open file");
    return;
}
fread((void *)buffer, sizeof(psinfo_t), 1, file);
psinfo_t* pData = (psinfo_t*) buffer;
time_t sTime=pData->pr_start.tv_sec; 
int pr_pid=pData->pr_pid;
char* fname=pData->pr_fname;
free(buffer);
buffer = (char*) malloc(sizeof(stat));
stat(fullPath,buffer);
struct stat* fileStat=(struct stat*) buffer;
fclose(file);
int userId=fileStat->st_uid;
struct passwd* pw=getpwuid(userId);
char* uid=pw->pw_name;
printf("line 58\n");
if(isSetU<0){
    //Print results
    printf("%8s", uid);
    if(isSetP>0)
    printf(" %5d",pr_pid);
    printf(" %16s %.24s\n", fname, ctime(&sTime));
    free(buffer);
}else{
    //Or else, add UID to UIDS if it didn't appear before
    //check if UID is in UIDS
    printf("line 70\n");
    char * s2 = malloc(snprintf(NULL, 0, "%s:%d", "", userId) + 1);
    printf("line 72\n");
    snprintf(s2, "%s:%d", "", userId);
    if(strstr(myUIDs,s2)!=NULL){
        free(s2);
        free(buffer);
        return;
    }
    //If not, add to UIDS
    printf("line 78\n");
    free(s2);
    printf("line 82\n");
    char * ss = malloc(snprintf(NULL, 0, "%s:%d", "", 1) + 1);
    printf("line 84\n");
    sprintf(ss, "%s:%d", myUIDs, userId);
    free(myUIDs);
    myUIDs=ss;
    free(buffer);
}
}

1 个答案:

答案 0 :(得分:3)

我在进一步审核中看到了几个问题...

简而言之,您获得的错误似乎不是您正在执行的行的结果,而是先前内存损坏的副作用。

  1. 您在哪里初始化myUIDs?如果没有根据提供的代码定义

  2. ,您可能会访问它
  3. 您正在从fname分配pData,这是指向动态分配的buffer的指针...您随后会在下一行执行时释放,这意味着fname现在指向已释放的内存。然而,你试图在后面的代码中读取它...这可能会引导你随意浏览内存。

  4. 代码中有多个实例,您动态分配内存,然后尝试使用它而不验证您实际获得了所请求的分配。

  5. 您根据malloc()的返回值调用snprintf(),但未确认snprintf()是否为您返回了非负值。虽然,我怀疑这是一个问题,但这是不明智的。

  6. 可以肯定的是,您描述的症状是堆损坏的结果。问题是在哪里。我强烈建议使用valgrind。

    此外,如果可用,请查看asprintf()而不是您正在进行的malloc( snprintf() )工作。