By default, Trf dynamically loads "libz.so" at runtime.
However, this file is not always installed on most
Linux distros. (Usually only /usr/lib/libz.so.$VERSION
is included in the zlib runtime package, where $VERSION
is major, major.minor, or major.minor.patchlevel
depending on the distro. /usr/lib/libz.so is
typically part of the zlib development package.)
This makes it difficult to distribute precompiled,
statically linked binaries (tclkits), since not all
users have the zlib development package installed.
I tried: ./configure --enable-static-zlib, but that
doesn't have any effect.
(minor bug in configure.in: this switch sets
STATIC_ZLIB, but the script tests ZLIB_STATIC later
on).
Running 'env ZLIB_STATIC=yes ./configure' does have an
effect:
now [zip] crashes :-(
Logged In: YES
user_id=68433
Stack backtrace:
load {} Trf
zip -mode compress "foo"
#0 0x401df00e in deflateInit2_ () from /usr/lib/libz.so.1
#1 0x401defd3 in deflateInit_ () from /usr/lib/libz.so.1
#2 0x401a40a9 in CreateEncoder (writeClientData=0xbfffecc0,
fun=0x4018f9c8 <PutInterpResult>, optInfo=0x80ece90,
interp=0x80dbbf8,
clientData=0x0) at ./generic/zip.c:256
#3 0x4018eeed in TransformImmediate (interp=0x80dbbf8,
entry=0x80eb960,
source=0x0, destination=0x0, in=0x80e5028,
optInfo=0x80ece90)
at ./generic/registry.c:2488
#4 0x4018dad6 in TrfExecuteObjCmd (clientData=0x80eb960,
interp=0x80dbbf8,
objc=1, objv=0x80dda38) at ./generic/registry.c:1004
#5 0x080667e5 in TclEvalObjvInternal () at eval.c:41
#6 0x080889c4 in TclExecuteByteCode () at eval.c:41
#7 0x08087e66 in TclCompEvalObj () at eval.c:41
#8 0x080676c7 in Tcl_EvalObjEx () at eval.c:41
#9 0x08094436 in Tcl_RecordAndEvalObj () at eval.c:41
#10 0x08054c3e in Tcl_Main () at eval.c:41
#11 0x080546e7 in main () at eval.c:41
#12 0x4006f306 in __libc_start_main (main=0x80546c0 <main>,
argc=1,
ubp_av=0xbffff224, init=0x8053c84 <_init>,
fini=0x80c34c0 <_fini>,
rtld_fini=0x4000d2cc <_dl_fini>, stack_end=0xbffff21c)
at ../sysdeps/generic/libc-start.c:129
Logged In: YES
user_id=68433
Found the problem: the zFunctions mini-stubs table in
generic/zlib.c (lines 43-55) is misinitialised.
From the stacktrace:
#0 0x401df00e in deflateInit2_ () from /usr/lib/libz.so.1
#1 0x401defd3 in deflateInit_ () from /usr/lib/libz.so.1
#2 0x401a40a9 in CreateEncoder [...] ./generic/zip.c:256
generic/zip.c line 256 says:
res = zf.deflateInit2_ (&c->state, o->level, Z_DEFLATED,
So the CreateEncoder() routine *thinks* it's calling
deflateInit2_, but from the stacktrace it's really calling
deflateInit_.
Turns out there's a mismatch in generic/zlib.c between the
'symbols' array (used for dynamic loading) and the
statically initalized 'zf' structure (used for static builds).
Actually, the compiler caught this error:
./generic/zlib.c:47: warning: initialization from
incompatible pointer type
./generic/zlib.c:51: warning: initialization from
incompatible pointer type
but the warning messages were hard to notice in the morass
of make rule outputs. Does the Trf source *really* need
everything -- or anything -- in ${TCL_DEFS} to compile
properly? Could TCL_DEFS be removed from the Makefile?
(I've yet to see a package that actually used any of these,
it seems to be a TEA cargo cult thing.)
Logged In: YES
user_id=68433
Has this been fixed yet? I'm having similar problems with
--enable-static-md5 and --enable-static-bzlib.
Patch to CVS HEAD, fixes --enable-static-zlib
Logged In: YES
user_id=68433
Attached patch fixes the zFunctions table in generic/zlib.c
(deflateInit2/inflateInit2 vs deflateInit/inflateInit --
this was causing a coredump), a couple of the function
signatures in struct Md5functions in generic/loadman.h
('unsigned long' vs. 'size_t', etc.; probably not a problem,
but caused compiler warnings), and patches trf.m4 so that
--enable-static-zlib sets ZLIB_STATIC instead of STATIC_ZLIB
(ditto --enable-static-md5, etc.)
Test suite passes (though I'm not sure how much is actually
being excercised), also did a couple basic sanity checks;
seems OK.
This problem seems to have resurfaced in the latest release (Trf 2.1.4).
More info: looks like this hasn't so much resurfaced as it was never fixed in the first place :-)
generic/zlib.c still has:
#ifdef ZLIB_STATIC_BUILD
zFunctions zf = {
0,
deflate,
deflateEnd,
deflateInit_, <= problem here
...
inflateInit_, <= ... and here
...
}
whereas generic/transformInt.h has:
typedef struct ZFunctions {
...
int (ZEXPORT * zdeflateInit2_) _ANSI_ARGS_ ((...))
...
int (ZEXPORT *zinflateInit2_) _ANSI_ARGS_ ((...))
}
Changing the zf static initializers in generic/zlib.c fixes the problem.
On the plus side, the autogoo appears to be working correctly now -- "./configure --enable-static-{zlib, etc}" works as advertised (modulo this problem).
Refreshed patch against trf 2.1.4