*** 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的内存操作