首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

* glibc detected * ./parse: malloc(): smallbin double linked list corrupted:该如何处

2012-11-17 
*** glibc detected *** ./parse: malloc(): smallbin double linked list corrupted:ubuntu下写了一段文

*** glibc detected *** ./parse: malloc(): smallbin double linked list corrupted:
ubuntu下写了一段文本分析的代码,比如长,如下:

C/C++ code
#include "../unp.h"#include <sys/mman.h>#define GET        "GET "#define HOST    "Host: "#define REFERER    "Referer: "#define HTTP    "http://"#define    DATA_BLOCK_SIZE    10000char     * file_map_ptr;struct data_block {    char            * ptr;    ssize_t            size;}data_block[DATA_BLOCK_SIZE], * data_block_ptr;struct url_referer {    char            * url;    char            * referer;}url_referer[DATA_BLOCK_SIZE];void init_data_block(const void * file_ptr, ssize_t file_size, struct data_block * block, ssize_t block_size);char * memstr(const char * haystack, const char * needle, size_t len);void get_url_refer(struct data_block * block, ssize_t len);intmain(int argc, char ** argv) {    int                fd, i;    struct stat        file_stat;    if (argc != 2) {        err_quit("Usage: %s <filename>", argv[0]);    }        fd = open(argv[1], O_RDONLY);    if (fd < 0) {        err_sys("Open file %s error", argv[1]);    }    if (fstat(fd, &file_stat) < 0) {        err_sys("fstat error");    }    printf("file size: %d K\n", (int)(file_stat.st_size / 1024));    file_map_ptr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_SHARED, fd, 0);    if (file_map_ptr == MAP_FAILED) {        err_sys("map failed");    }    printf("file mapped success\n");    data_block_ptr = NULL;    memset(data_block, 0, sizeof(data_block));    init_data_block(file_map_ptr, file_stat.st_size, data_block, DATA_BLOCK_SIZE);    for (i = 0; i < DATA_BLOCK_SIZE; ++i) {        if (data_block[i].ptr == NULL)            break;        else {            printf("%s\n", data_block[i].ptr);            printf("strlen() = %d\n", strlen(data_block[i].ptr));            printf("calculated size: %d\n", data_block[i].size);        }    }    printf("block size: %d\n", i);    get_url_refer(data_block, DATA_BLOCK_SIZE);        return 0;}char *memstr(const char * haystack, const char * needle, size_t len) {    char                    * p;    size_t                  needle_len;    needle_len = strlen(needle);    if (haystack == NULL || needle == NULL)        return NULL;    for (p = (char *)haystack; p <= haystack + len - needle_len; p++) {        if (memcmp(p, needle, needle_len) == 0) {            return p;        }    }    return NULL;}voidinit_data_block(const void * file_ptr, ssize_t file_size, struct data_block * block, ssize_t n) {    char            * p, * q, * t, * file_end;    ssize_t            i, s;    file_end = (char *)file_ptr + file_size;    for (i = 0, t = (char *)file_ptr; t < (char *)file_end && i < n; ++i) {        p = memstr(t, GET, file_end - t);        if (p) {            q = memstr(p + strlen(GET), GET, file_end - p - strlen(GET));            if (q) {                s = q - p;            }            else {                s = file_end - p;            }            data_block[i].ptr = p;            data_block[i].size = s;            t = p + strlen(GET);        }        else            break;    }    return ;}voidget_url_refer(struct data_block * block, ssize_t len) {    int                 i;    char                * p, * q, * get, * referer, * host, * url;    ssize_t                get_size, host_size, referer_size, url_size;    memset(url_referer, 0, sizeof(url_referer));    p = q = get = referer = host = url = NULL;    for (i = 0; i < len && block[i].ptr != NULL; ++i) {        p = block[i].ptr;        q = p + strlen(GET);        while(* q != ' ' && * q != '\r') q++;        get_size = q - p - strlen(GET);        get = (char *)malloc(get_size + 1);        memset(get, 0, get_size + 1);        memcpy(get, p + strlen(GET), get_size);                p = memstr(block[i].ptr, HOST, block[i].size);        if (p) {            q = p + strlen(HOST);            while(* q != '\r' && *q != ' ') q++;            host_size = q - p - strlen(HOST);            host = (char *)calloc(host_size + 1, sizeof(char));            memcpy(host, p + strlen(HOST), host_size);        }        p = memstr(block[i].ptr, REFERER, block[i].size);        if (p) {            q = p + strlen(REFERER);            while(*q != '\r' && *q != ' ') q++;            referer_size = q - p - strlen(REFERER);            referer = (char *)calloc(referer_size + 1, sizeof(char));            memcpy(referer, p + strlen(REFERER), referer_size);        }        url_size = host_size + get_size + strlen(HTTP);        url = (char *)calloc(url_size + 1, sizeof(char));        memcpy(url, HTTP, strlen(HTTP));        memcpy(url + strlen(HTTP), host, host_size);        memcpy(url + strlen(HTTP) + host_size, get, get_size);[color=#FF0000]        free(host);        printf("free(host) ok\n");        free(get);        printf("free(get) ok\n");[/color]        url_referer[i].url = url;        url_referer[i].referer = referer;                printf("url = %s\n", url);        if (referer)            printf("referer = %s\n", referer);        else            printf("referer is NULL\n");    }    return ;} 



运行之后出现如下错误:

double@ubuntu:~/unp/cap$ ./parse cap3
file size: 49333 K
file mapped success
block size: 2601
*** glibc detected *** ./parse: malloc(): smallbin double linked list corrupted: 0x08c83900 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x50c961]
/lib/i386-linux-gnu/libc.so.6(+0x6e4ba)[0x50f4ba]
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0x63)[0x510f53]
./parse[0x80490b7]
./parse[0x8048eb6]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x4b7e37]
./parse[0x8048c81]
======= Memory map: ========
0031b000-0031c000 r-xp 00000000 00:00 0 [vdso]
004a1000-005fb000 r-xp 00000000 08:01 789692 /lib/i386-linux-gnu/libc-2.13.so
005fb000-005fc000 ---p 0015a000 08:01 789692 /lib/i386-linux-gnu/libc-2.13.so
005fc000-005fe000 r--p 0015a000 08:01 789692 /lib/i386-linux-gnu/libc-2.13.so
005fe000-005ff000 rw-p 0015c000 08:01 789692 /lib/i386-linux-gnu/libc-2.13.so
005ff000-00602000 rw-p 00000000 00:00 0 
0062d000-00647000 r-xp 00000000 08:01 789720 /lib/i386-linux-gnu/libgcc_s.so.1
00647000-00648000 r--p 00019000 08:01 789720 /lib/i386-linux-gnu/libgcc_s.so.1
00648000-00649000 rw-p 0001a000 08:01 789720 /lib/i386-linux-gnu/libgcc_s.so.1
0074a000-00766000 r-xp 00000000 08:01 789679 /lib/i386-linux-gnu/ld-2.13.so
00766000-00767000 r--p 0001b000 08:01 789679 /lib/i386-linux-gnu/ld-2.13.so
00767000-00768000 rw-p 0001c000 08:01 789679 /lib/i386-linux-gnu/ld-2.13.so
08048000-0804b000 r-xp 00000000 08:01 132311 /home/double/unp/cap/parse
0804b000-0804c000 r--p 00002000 08:01 132311 /home/double/unp/cap/parse
0804c000-0804d000 rw-p 00003000 08:01 132311 /home/double/unp/cap/parse
0804d000-08074000 rw-p 00000000 00:00 0 
08c62000-08cc5000 rw-p 00000000 00:00 0 [heap]
b4700000-b4721000 rw-p 00000000 00:00 0 
b4721000-b4800000 ---p 00000000 00:00 0 
b48b5000-b78e3000 r--s 00000000 08:01 132322 /home/double/unp/cap/cap3
b78e3000-b78e4000 rw-p 00000000 00:00 0 
b78f4000-b78f7000 rw-p 00000000 00:00 0 
bf987000-bf9a8000 rw-p 00000000 00:00 0 [stack]
已放弃
double@ubuntu:~/unp/cap$ 

在网上找了半天也没有找到理想的答案,各位高手请指教。我发现,将

free(host);
printf("free(host) ok\n");
free(get);
printf("free(get) ok\n");

注释掉之后就运行正常。


[解决办法]
smallbin double linked list corrupted 可能原因是频繁操作堆栈,导致栈结构损坏

但是LZ的代码不像是这样的;

gcc4.2,测试文件大小为3714K:

file size: 3714 K
file mapped success
block size: 12

执行正常;
也许是文件没LZ的大导致没发现错误

LZ参考:
http://mqzhuang.iteye.com/blog/1064939
http://zhanyonhu.blog.163.com/blog/static/161860442010916112321895/

[解决办法]
很可能是double delete了。用valgrind看看。
[解决办法]
个人建议:
使用malloc函数时,应该这样:
C/C++ code
指针 = (类型*)malloc(sizeof(类型) * 数量);
[解决办法]
探讨

没有更好的意见了吗?

[解决办法]
感觉堆溢出了,破坏了堆结构,不一定是double free

仔细检查你的get和host的内存操作

热点排行