메모리 누수현상 찾기..
글쓴이: leolo / 작성시간: 토, 2003/05/31 - 4:27오후
다음은 C로 작성한 CGI파일 입니다..
다음을 연속적으로 여러번 실행하면
메모리 누수 현상이 발생합니다.
도대체 어디에서 발생하는지 좀 알려주세요.
아님.. httpd 데몬에 문제인지 알고 싶습니다.
지금과 같은 경우는 입력폼으로 부터 어떠한 값도 받지 않으므로
결과는 다음과 같이 나옵니다. "Got 0 pairs"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define TEST 1
struct cgi_object {
char *name;
char *value;
struct cgi_object *next;
};
static struct cgi_object *list=NULL;
/* function to remove url encoding */
int url_decode(char *dst, char *src, int len)
{
int a=0, b=0;
int c;
while (b<len)
{
if (src[b]=='+')
{
dst[a++]=' ';
b++;
}
else if (src[b]=='%')
{
if (sscanf(&src[b+1],"%2x",&c)>0)
dst[a++]=c;
b+=3;
}
else dst[a++]=src[b++];
}
dst[a++]=0;
return (a);
}
void cgi_free(struct cgi_object *ptr)
{
struct cgi_object *current = ptr;
struct cgi_object *next;
while(current != NULL){
next = current->next;
if(current->name) free(current->name);
if(current->value) free(current->value);
if(current->next) free(current->next);
free(current);
current = next;
}
ptr = NULL;
}
/* destructive to the query string */
static int cgi_split_pairs(char *query)
{
char *start = NULL, *mid = NULL, *end = NULL;
struct cgi_object *new = NULL;
int count = 0;
start=query;
while (start!=NULL && *start!=0)
{
int len;
if ((end=strchr(start, '&'))==NULL)
end=start+strlen(start);
if ((mid=strchr(start, '='))==NULL)
mid=end;
if (mid > end) mid=end;
if (start == mid)
{
start=end+1;
continue;
}
new=(struct cgi_object *)malloc(sizeof(*new));
if(new==NULL)
exit(1);
len=mid-start;
new->name=(char *)malloc(len+1);
if(new->name==NULL)
exit(1);
url_decode(new->name, start, len);
if (end > mid)
{
mid++;
len=end-mid;
new->value=(char *)malloc(len+1);
url_decode(new->value, mid, len);
new->value[len]=0;
}else
new->value=NULL;
new->next=list;
list=new;
start=end;
if (*start=='&') start++;
count++;
}
return (count);
}
#if 0
char *cgi_find(char *what)
{
struct cgi_object *ptr;
ptr=list;
while (ptr!=NULL)
{
if (!strcasecmp(what, ptr->name))
return(ptr->value);
ptr=ptr->next;
}
return(NULL);
}
char *cgi_nfind(char *what, int which)
{
struct cgi_object *ptr;
int i=1;
ptr=list;
while (ptr!=NULL)
{
if (!strcasecmp(what, ptr->name))
{
if (i==which)
return(ptr->value);
i++;
}
ptr=ptr->next;
}
return(NULL);
}
#endif
/* count the number of arguments,
or number of arguments with a specific name */
int cgi_count(char *what)
{
struct cgi_object *ptr;
int count=0;
ptr=list;
while (ptr!=NULL)
{
if (what==NULL || !strcmp(what, ptr->name))
count++;
ptr=ptr->next;
}
return (count);
}
/* master processing function */
int cgi_process(void)
{
static int done=0;
char *method, *query;
int count=0;
if (done) return ( cgi_count(NULL) );
if ((method=getenv("REQUEST_METHOD"))==NULL)
return(0);
if (!strcasecmp(method, "GET"))
{
if ((query=getenv("QUERY_STRING"))==NULL)
return(0);
query=strdup(query);
count=cgi_split_pairs(query);
free(query);
}else
if (!strcasecmp(method, "POST"))
{
int len;
if ((query=getenv("CONTENT_LENGTH"))==NULL)
return(0);
if ((len=atoi(query))<=0) return(0);
query=(char *)malloc(len+1);
if(query==NULL)
exit(1);
read(fileno(stdin), query, len);
query[len+1]=0;
count=cgi_split_pairs(query);
free(query);
}else
{
fprintf(stderr, "Unknown REQUEST_METHOD of '%s'\n", method);
return(0);
}
done=1;
return ( count );
}
#ifdef TEST
int main()
{
int i;
struct cgi_object *ptr;
i = cgi_process();
printf("Content-type: text/html\n\n");
printf("<html><body>\n");
printf("Got %d pairs<br>\n",i);
if (i>0)
{
printf("<ol>\n");
ptr=list;
while (ptr!=NULL)
{
printf("<li> %s", ptr->name);
if (ptr->value!=NULL)
printf(" = '%s'", ptr->value);
printf("\n");
ptr=ptr->next;
}
printf("</ol>\n");
}
printf("</body></html>\n");
cgi_free(list);
exit(0);
}
#endif
Forums:


[code:1]void cgi_free(struct cgi_obj
void cgi_free(struct cgi_object *ptr) { struct cgi_object *current = ptr; struct cgi_object *next; while(current != NULL){ next = current->next; if(current->name) free(current->name); if(current->value) free(current->value); /* 이 라인이 빠져야 할것 같은데요... */ /* if(current->next) free(current->next); */ free(current); current = next; } ptr = NULL; }우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
지금 저번에 질문하신 글을 봤는데 거기엔 [code:1]if(cu
지금 저번에 질문하신 글을 봤는데 거기엔
if(current->next) free(current->next);이부분이 없더군요.
이 부분이 없을때에도 문제가 있었다는 것으로 생각되어서 다시 좀 봤더니... list에다가 추가하는 부분도 이상합니다.
static int cgi_split_pairs(char *query) { .... while (...) { ... new->next=list; list=new; ... } .... }이 부분에서 보면 input name/value pair가 여러개 오는 경우 list는 항상 마지막 하나의 cgiobject(마지막 new)를 가리키게 되지 않나요?
list에 이미 append되어 있는 마지막 item( cgiobject )을 찾아가서 그 뒤에 append 해주어야 하는것 아닌가요?
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
cgi 프로그램이면, memory leak은 생각할 필요 없습니다. cg
cgi 프로그램이면, memory leak은 생각할 필요 없습니다. cgi는 요청이 들어오면 새 process 가 생성되었다가 죽으므로, 웹서버의 메모리 릭이랑은 무관합니다.
댓글 달기