-1

Function which worked previously, suddenly refuses cooperation. More precisely this snippet:

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

Program fails one line after "line 82" (no longer line 82, but it's only a debugging stop) with Segmentation Fault (core dumped). If I change

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

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

I get Bus Error: Code dumped instead. I'm working on this program for quite a long time, and I have a feeling it's something obvious, that I'm constantly overlooking because of exhaustion, but no programmer friends to ask for help at this time.

Whole function for context:

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);
}
}
Xyzk
  • 1,332
  • 2
  • 21
  • 36

1 Answers1

3

There are several issues I see on further review...

In a nutshell, the error you are getting does not appear to be the result of the line you're executing, rather, a side effect of a previous corruption of memory.

  1. Where do you initialize myUIDs? It looks like you could be accessing it when it has not been defined based on the code provided

  2. You are assigning fname from pData which is a pointer to the dynamically allocated buffer... which you subsequently free on the next line of execution, which means that fname is now pointing to deallocated memory. Yet you attempt to read from it later in the code... which may well be leading you off on a random walk through memory.

  3. There are multiple instances in the code where you are dynamically allocating memory, and then attempting to use it without ever validating that you actually got the allocation you requested.

  4. You are calling malloc() based on the return value from snprintf() without ever validating that snprintf() returned you a non-negative value. Though, I doubt this is an issue, it's unwise.

To be sure, the symptoms you are describing are the result of the corruption of the heap. The question is where. I would strongly recommend the use of valgrind.

In addition, if it is available, have a look at asprintf() instead of the malloc( snprintf() ) work you are doing.

K Scott Piel
  • 4,320
  • 14
  • 19
  • It worked before, even in this program, you can see a few lines above very similiar code http://stackoverflow.com/questions/1383649/concatenating-strings-in-c-which-method-is-more-efficient – Xyzk Apr 09 '13 at 15:25
  • `snprintf()` may be called with a `NULL` buffer and zero size according to both C99 and SUSv2. In the former, it returns the number of characters that would have been written. In the latter, a value lesser than 1. – Hasturkun Apr 09 '13 at 15:26
  • Edited again to provide a more concise analysis of the errors I see in the code provided... especially given the edits to the original question. – K Scott Piel Apr 09 '13 at 16:01
  • Unfortunately, it appears this was not the problem (EDIT: i added this comment before yours analysis, reading it now). EDIT2: Your comments seem wise. I will apply them, after I get some sleep. Thank you for in depth analysis of my code. – Xyzk Apr 09 '13 at 16:06