-1

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

    //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);
}
}
4

1 回答 1

3

我在进一步审查时看到了几个问题......

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

  1. 你在哪里初始化myUIDs?如果尚未根据提供的代码定义它,您似乎可以访问它

  2. 您正在分配fnamefrom pDatawhich 是指向动态分配的buffer...的指针,您随后在下一行执行时将其释放,这意味着它fname现在指向已释放的内存。然而,您稍后会尝试在代码中读取它......这很可能会引导您随机浏览内存。

  3. 代码中有多个实例,您在其中动态分配内存,然后尝试使用它而不验证您是否确实获得了您请求的分配。

  4. 您是malloc()根据返回值调用的,snprintf()而无需验证snprintf()返回非负值。虽然,我怀疑这是一个问题,但这是不明智的。

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

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

于 2013-04-09T15:18:17.293 回答