In process_query_str on line 4 I call splitline and get back a string array of 3 elements, the last of which is a NULL. The array is malloced and so are the individual strings. Then I try to free each of the elements and then the array itself (towards the end of the first function). The first two strings are freed but when it goes to free the third element, which is NULL, I get the error at the bottom regarding invalid pointer. Apparently it’s not getting set to NULL and should be. I tried placing breakpoints but the program won’t stop.
char * process_query_str(char *rq, char *cmd) {
logg("In process_query_str.\n");
int has_query = 0;
char **tokenized_args = splitline(rq, &has_query); //Tokenize the string based on '?'
char * query_str = rq;
logg("has_query:");
fprintf(stderr, "%d", has_query);
if (has_query == 1) //Check for Query String
if (query_str != NULL) {
query_str = retrieve_query_str(tokenized_args);
logg("Query String: ");
logg(query_str);
logg("\n");
char* key = "REQUEST_METHOD"; //Process REQUEST_METHOD envir variable
if (VLstore(key, cmd) == 0)
if (VLexport(key) == 0) {
logg("Successfully exported ");
logg(cmd);
logg(": ");
logg(key);
logg("\n");
key = "QUERY_STRING"; //Process QUERY_STRING envir variable
if (VLstore(key, query_str) != 1) //1 signals a problem
if (VLexport(key) != 0) //0 signals a problem
{
logg("Successfully exported ");
logg(cmd);
logg(": ");
logg(key);
logg("\n");
}
}
}
#ifdef LOGGING //Print out environment variables
VLlist();
#endif
char *resource_str = newstr(tokenized_args[0], strlen(tokenized_args[0]));
freelist(tokenized_args);
logg("resource_str=");
logg(resource_str);
logg("\n");
return resource_str;
}
char ** splitline(char *line, int*has_query)
/*
* purpose: split a line into array of white-space separated tokens
* returns: a NULL-terminated array of pointers to copies of the tokens
* or NULL if line if no tokens on the line
* action: traverse the array, locate strings, make copies
* note: strtok() could work, but we may want to add quotes later
*/
{
//char *newstr();
logg("In splitline\n");
char **args;
int spots = 0; /* spots in table */
int bufspace = 0; /* bytes in table */
int argnum = 0; /* slots used */
char *cp = line; /* pos in string */
char *start;
int len;
if (line == NULL) /* handle special case */
return NULL;
args = emalloc(BUFSIZ); /* initialize array */
bufspace = BUFSIZ;
spots = BUFSIZ / sizeof(char *);
while (*cp != '\0') {
logg("*cp=");
fprintf(stderr, "%c", *cp);
while (*cp == ' ') /* skip leading spaces */
cp++;
if (*cp == '\0') /* quit at end-o-string */
break;
/* make sure the array has room (+1 for NULL) */
if (argnum + 1 >= spots) {
args = erealloc(args, bufspace + BUFSIZ);
bufspace += BUFSIZ;
spots += (BUFSIZ / sizeof(char *));
}
/* mark start, then find end of word */
start = cp;
len = 1;
if (*cp == '?') {
logg("query reached.\n");
*has_query = 1;
}
while (*++cp != '\0' && !(is_delim(*cp,*has_query)))
len++;
args[argnum++] = newstr(start, len);
}
logg("arg[0] =");
logg(args[0]);
logg("\n");
if (argnum == 2) {
logg("arg[1] =");
logg(args[1]);
logg("\n");
}
args[argnum] = NULL;
fprintf(stderr, "last element is NULL. argnum=%d", argnum);
return args;
}
void freelist(char **list)
/*
* purpose: free the list returned by splitline
* returns: nothing
* action: free all strings in list and then free the list
*/
{
char **cp = list;
while (*cp && (*cp)) {
logg("free: ");logg(*cp);logg("\n");
free(*cp++);
}
logg("Now Free the list:");logg("\n");
free(list);
logg("Done Freeing List\n");
}
The stack backtrace information I get from the glibc is:
free: /index.cgifree: key=value*** glibc detected *** ./ws: free(): invalid pointer: 0x0804efa9 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb76d3d05]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb76d7770]
./ws[0x804b36f]
./ws[0x804a1fb]
./ws[0x8049de1]
./ws[0x8049757]
./ws[0x8049660]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb767e460]
./ws[0x8049031]
======= Memory map: ========
08048000-0804d000 r-xp 00000000 00:24 8084895 /nfs/home/j/c/jcalderon/unixlin ux/wsng/ws
0804d000-0804e000 rw-p 00004000 00:24 8084895 /nfs/home/j/c/jcalderon/unixlin ux/wsng/ws
0804e000-0806f000 rw-p 0804e000 00:00 0 [heap]
b7500000-b7521000 rw-p b7500000 00:00 0
b7521000-b7600000 ---p b7521000 00:00 0
b7644000-b764e000 r-xp 00000000 68:07 1122448 /lib/libgcc_s.so.1
b764e000-b764f000 rw-p 0000a000 68:07 1122448 /lib/libgcc_s.so.1
b765c000-b7665000 r-xp 00000000 68:07 1122335 /lib/tls/i686/cmov/libnss_files -2.7.so
b7665000-b7667000 rw-p 00008000 68:07 1122335 /lib/tls/i686/cmov/libnss_files -2.7.so
b7667000-b7668000 rw-p b7667000 00:00 0
b7668000-b77b2000 r-xp 00000000 68:07 1122611 /lib/tls/i686/cmov/libc-2.7.so
b77b2000-b77b3000 r--p 0014a000 68:07 1122611 /lib/tls/i686/cmov/libc-2.7.so
b77b3000-b77b5000 rw-p 0014b000 68:07 1122611 /lib/tls/i686/cmov/libc-2.7.so
b77b5000-b77b8000 rw-p b77b5000 00:00 0
b77c2000-b77c7000 rw-p b77c2000 00:00 0
b77c7000-b77c8000 r-xp b77c7000 00:00 0 [vdso]
b77c8000-b77e2000 r-xp 00000000 68:07 1124008 /lib/ld-2.7.so
b77e2000-b77e4000 rw-p 00019000 68:07 1124008 /lib/ld-2.7.so
bfd9f000-bfdb4000 rw-p bffea000 00:00 0 [stack]
It turned out to be a malloc problem where I didn’t allocate enough space in newstr(). The last array element caused the error when I tried to free it.