다시 한번.. 메모리 누수.. 찾기..

leolo의 이미지

계속해서 CGI를 실행하면 메모리가 누수됩니다..
원인을 모르겠습니다..
일반적으로 들어오는 query는 다음과 같은 형식입니다.
기본 형식 [name=value]
mode=server&name=kiminsik...
이걸 차곡차곡 메모리를 뒤로 늘려가면서 하나씩 할당합니다.
그러니까?
struct cgi_object *list가 처음 들어온 mode=server를 가리키는 것이
아니라. 마지막으로 들어온 name=value를 가리키게됩니다.

혹시, 웹서버의 문제가 아닌지 하는 생각도 듭니다.
웹서버는 thttp를 사용하고 있습니다.
컴파일러는 arm-uclibc-gcc를 사용하였고요..

한가지더.. 부탁드리면..
boa웹서버를 설정하는 방법 좀 알려주세요..
영어로 된 웹사이트 말고, 한글로 설정하는 방법 좀 적혀있는거 없나요..

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

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.