2011-12-12 105 views
0

这是一个解码base64的函数。 SIGSEGV(有时候是SIGABORT)出现在被调用的malloc的那一行。它几乎让我发疯!提前致谢。base64解码函数:SIGSEGV,,分段错误

static char base64_table[255] = {'\0'}; 

static void base64_tableinit() 
{ 
    int i,j; 
    bzero(base64_table,255); 
    for(j=0,i='A';i<='Z';i++) 
     base64_table[i]=j++; 
    for(i='a';i<='z';i++) 
     base64_table[i]=j++; 
    for(i='0';i<='9';i++) 
     base64_table[i]=j++; 

    base64_table['+']=j++; 
    base64_table['/']=j++; 
    base64_table['=']=j; 
}  
char *decode(const char *cptr,char **rptr) 
{ 
    if(cptr==NULL) 
    { 
     fprintf (stderr, "The input string is NULL!\n"); 
     exit(1); 
    } 

    int len = strlen(cptr); 
    if(len%4 != 0) 
    { 
     fprintf (stderr, "The input string length is not 4X!\n"); 
     exit(1); 
    } 

    base64_tableinit(); 
    int clen=len/4; 

#ifdef DEBUG 
    /// printf ("The length of string len = %d\n",len); 
    /// printf ("The length of string clen = %d\n",clen); 
#endif 
    char* res = NULL; 
    /// Error: below, SIGSEGV 
    if((res=(char *)malloc((len-clen + 1) * sizeof(char)))==NULL) 
    { 
     fprintf (stderr, "Can't malloc enough space in decode!\n"); 
     exit(1); 
    } 

    for(*rptr=res; clen>0; clen--) 
    { 
     *res = base64_table[(int)*cptr++]<<2 ;    /* Use the 1th char(6) */ 
     *res++|= base64_table[(int)*cptr]>>4 ;    /* Use the 2th char(2) */ /// Construct the first char 

     *res = base64_table[(int)*cptr++]<<4 ;    /* Use the 2th char(4) */ 
     *res++ |= base64_table[(int)*cptr]>>2 ;    /* Use the 3th char(4) */ /// Construct the second char 


     *res = base64_table[(int)*cptr++]<<6;    /* Use the 3th char(2) */ 
     *res++ |= base64_table[(int)*cptr++]&0x3f;   /* Use the 4th char(6) */ /// Construct the third char 

    } 
    *(res+len-clen) = '\0'; 

    return *rptr; 
} 

gdb的回溯。

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0xb71a2b70 (LWP 5432)] 
0xb7d450a6 in _int_malloc() from /lib/libc.so.6 
(gdb) bt 
0 0xb7d450a6 in _int_malloc() from /lib/libc.so.6 
1 0xb7d4746c in malloc() from /lib/libc.so.6 
2 0x0804b04c in decode (
cptr=0x806dce8 "PGRpdiBzdHlsZT0ibGluZS1oZWlnaHQ6MS43O2NvbG9yOiMwMDAwMDA7Zm9udC1zaXplOjE0cHg7Zm9udC1mYW1pbHk6YXJpYWwiPuato+W4uCA8YnI+PC9kaXY+PGJyPjxicj48c3BhbiB0aXRsZT0ibmV0ZWFzZWZvb3RlciI+PHNwYW4gaWQ9Im5ldGVhc2VfbWFp"..., rptr=0xb71a1fa8) at base64.c:78 
3 0x0804d5af in email_decode (email_old=0xb71a1ffc, email_new=0xb71a1d50) at email_handle.c:421 
4 0x0804a9c2 in PacketAnalyze() at packet_analyze.c:800 
5 0xb7fa1cf2 in start_thread() from /lib/libpthread.so.0 
6 0xb7da584e in clone() from /lib/libc.so.6 
+0

而且......现在的问题是......? – sidyll

+0

@sidyll对不起,刚刚编辑 – louxiu

+0

这是能够重现问题的最小样本吗?如果不是,你可以提供一个吗? – INS

回答

0

此:

*(res+len-clen) = '\0'; 

似乎是错误的,因为你已经增加res全部通过循环,应该可能只是

*res = '\0'; 
+0

非常感谢! :-) – louxiu

1

分割故障在malloc是一个相当明确的信号,无论是一些野生的内存损坏或发生有人free是个指针非动态分配的内存。这两个错误不一定发生在您展示的代码或触发SIGSEGV的代码中。 但是,这两个错误通常由valgrind检测到。

+0

这是否意味着错误可能发生在其他地方,但gcc会在内存分配的位置报告错误? – louxiu

+0

@LouXiou:'gcc'在这里报告没有错误。编译完成后''gcc'完成了它的工作,它与运行程序无关。程序崩溃了,它破坏了内存分配,破坏的分配可能在代码中完全不同的地方。 – thiton

+0

对不起,我的意思是由gdb报告的回溯信息。 – louxiu