Debian下Tcl8.4下的alloc: invalid block错误

问题描述:

采用tcl库编写的程序在redhat下编译运行正常通过(tcl8.3/tcl8.4),但是在Debian Sarge下运行时出现如下错误alloc: invalid block: 0x85cd938: 69 61 41

网上类似的问题描述
http://aspn.activestate.com/ASPN/Mail/Message/2606536

问题分析:

从google group中得知,Tcl_Alloc/Tcl_Free的指针和free/malloc/strdup不能混用。这是因为Debian上的tcl库使用了-DTCL_USEALLOC=1选项进行编译。该版本的库使用了内建的thread memory allocator,因此Tcl_Alloc并不等同于直接malloc返回的指针
http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/e4300a5fd97b22a7/79f0bd67ca2ad68a?lnk=st&q=alloc%3A+invalid+block&rnum=12#79f0bd67ca2ad68a

http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/2f16d826826185a4/535c21cf18b6b8dc?q=alloc%3A+invalid+block&rnum=2#535c21cf18b6b8dc

查看tcl8.4-8.4.9源码可以看到,Tcl_Alloc最终使用了TclpAlloc分配内存,该函数最终返回的是Block2Ptr(blockPtr, bucket, reqsize),两种指针的区别在于头部的MAGIC number。Thread memory allocator(generic/tclThreadAlloc.c)在操作前会做校验。

static char *
Block2Ptr(Block *blockPtr, int bucket, unsigned int
reqsize)
{
register void *ptr;

blockPtr->b_magic1 =
blockPtr->b_magic2 = MAGIC;
blockPtr->b_bucket = bucket;
blockPtr->b_reqsize = reqsize;
ptr = ((void *) (blockPtr + 1));
#if RCHECK
((unsigned char *)(ptr))[reqsize] = MAGIC;
#endif
return (char *) ptr;
}

另外,tcl.h头文件中定义了ckalloc/ckfree函数,当-DTCL_MEM_DEBUG选项未打开时,实际调用Tcl_Alloc/Tcl_Free,否则加入相应的调试信息。这对函数是系统推荐的方式


相关文章

Speak Your Mind

If you want a pic to show with your comment, go get a gravatar!