*** glibc detected *** ./parse: malloc(): smallbin double linked list corrupted:

desdouble 2012-02-16 08:42:57
ubuntu下写了一段文本分析的代码,比如长,如下:


#include "../unp.h"
#include <sys/mman.h>

#define GET "GET "
#define HOST "Host: "
#define REFERER "Referer: "
#define HTTP "http://"
#define DATA_BLOCK_SIZE 10000

char * 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);

int
main(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;
}

void
init_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 ;
}

void
get_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);

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

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

注释掉之后就运行正常。
...全文
1250 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
localxiao 2012-02-20
  • 打赏
  • 举报
回复
感觉堆溢出了,破坏了堆结构,不一定是double free

仔细检查你的get和host的内存操作
Wolf0403 2012-02-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 desdouble 的回复:]

没有更好的意见了吗?
[/Quote]

[Quote=引用 3 楼 jim_king_2000 的回复:]

很可能是double delete了。用valgrind看看。
[/Quote]

没有比挂 valgrind 更好的建议了。
灼眼的超哥 2012-02-19
  • 打赏
  • 举报
回复
个人建议:
使用malloc函数时,应该这样:
指针 = (类型*)malloc(sizeof(类型) * 数量);

为了避免申请的实际内存大小比自己想象大小要小的问题,这样有可能会在写数据时导致数据溢出,段错误。
还有memset和memcpy也要谨慎使用,第三个参数应该形如这样:sizeof(类型) * 数量。
desdouble 2012-02-19
  • 打赏
  • 举报
回复
没有更好的意见了吗?
程序员小迷 2012-02-17
  • 打赏
  • 举报
回复
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/
Jim_King_2000 2012-02-17
  • 打赏
  • 举报
回复
很可能是double delete了。用valgrind看看。
desdouble 2012-02-17
  • 打赏
  • 举报
回复
我的文件是40多兆,wireshark抓的http包。10几兆的小文件没啥总是。难道是大小的原因。
正在看楼上的参考。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧