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