tcl7.6的编译问题

Debian sarge 3.1,gcc3.3下编译tcl7.6出错

gcc -c -O -fPIC -I./../generic -I. -DHAVE_UNISTD_H=1 -DHAVE_SYS_TIME_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_TM_ZONE=1 -DHAVE_TM_GMTOFF=1 -DHAVE_TIMEZONE_VAR=1 -DSTDC_HEADERS=1 -DNEED_MATHERR=1 -DHAVE_SYS_IOCTL_H=1 -DTCL_SHLIB_EXT=".so" ./../generic/tclPosixStr.c
./../generic/tclPosixStr.c: In function `Tcl_ErrnoId':
./../generic/tclPosixStr.c:340: error: duplicate case value
./../generic/tclPosixStr.c:328: error: previously used here
./../generic/tclPosixStr.c: In function `Tcl_ErrnoMsg':
./../generic/tclPosixStr.c:787: error: duplicate case value
./../generic/tclPosixStr.c:775: error: previously used here
make: *** [tclPosixStr.o] Error 1

patch file

--- tclPosixStr.c 1996-10-11 04:58:40.000000000 +0800
+++ tclPosixStr.new.c 2006-07-02 17:22:39.000000000 +0800
@@ -336,7 +336,7 @@
#ifdef ENXIO
case ENXIO: return "ENXIO";
#endif
-#ifdef EOPNOTSUPP
+#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
case EOPNOTSUPP: return "EOPNOTSUPP";
#endif
#ifdef EPERM
@@ -783,7 +783,7 @@
#ifdef ENXIO
case ENXIO: return "no such device or address";
#endif
-#ifdef EOPNOTSUPP
+#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
case EOPNOTSUPP: return "operation not supported on socket";
#endif
#ifdef EPERM

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,否则加入相应的调试信息。这对函数是系统推荐的方式

Migration to 8.4: CONSTification

Tcl 8.4相对于8.3引入了更严格的类型声明,在函数中不被改变的都声明了const,因此造成许多8.3的源码在8.4下无法编译通过。

http://wiki.tcl.tk/3669 该文列举了不兼容的几种类型,并给了相应的建议。

定义USE_NON_CONST宏可与8.3源码级兼容。当然也可以选择更改代码并与8.4兼容(与8.3不兼容)

Page 1 of 11