Bug 226785 - RawHide rebuild request: tcl went 8.4->8.5
RawHide rebuild request: tcl went 8.4->8.5
Product: Fedora
Classification: Fedora
Component: expect (Show other bugs)
All Linux
medium Severity high
: ---
: ---
Assigned To: Miloslav Trmač
Depends On:
  Show dependency treegraph
Reported: 2007-02-01 11:21 EST by Jan Kratochvil
Modified: 2007-11-30 17:11 EST (History)
3 users (show)

See Also:
Fixed In Version: 5.43.0-6
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2007-02-04 15:22:54 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description Jan Kratochvil 2007-02-01 11:21:44 EST
rawhide report: 20070201 changes

Broken deps for i386
        expect - 5.43.0-5.1.i386 requires libtcl8.4.so
        expectk - 5.43.0-5.1.i386 requires libtk8.4.so
        expectk - 5.43.0-5.1.i386 requires libtcl8.4.so

* Thu Jan 25 2007 Marcela Maslanova <mmaslano@redhat.com> - 8.5a5-5
- rebuilt

* Mon Dec 18 2006 Marcela Maslanova <mmaslano@redhat.com> - 8.5a5-4
- change in spec for compatibility with tk, version 8.5a5
- Resolves: rhbz#160441

Error: Missing Dependency: libtcl8.4.so is needed by package expect
Comment 1 Jan Kratochvil 2007-02-01 11:23:48 EST
(sure I do not care now of expectk, a typo)
Comment 2 Jakub Jelinek 2007-02-04 13:24:20 EST
expect doesn't rebuild in rawhide.
The problem is:
1) make apparently doesn't have fully fixed the RLIMIT_STACK bug, so the:
TCL_LIBRARY=/usr/include/tcl-private/library ; \
        export TCL_LIBRARY ; \
LD_LIBRARY_PATH=.:/usr/lib:/var/tmp/expect-5.43.0-6-root/usr/lib:$LD_LIBRARY_PATH ./expect ./fixline1 /usr/bin < ./example/timed-run > timed-run
Tcl_Init failed: too many nested evaluations (infinite loop?)

command is executed with ulimit -s unlimited
2) on x86_64 kernel, 32-bit mock root, pthread_getattr_np returns in the initial
thread how much the stack can actually grow at that point, if I try say:
extern int TclpThreadGetStackSize(void); int main (void) { __builtin_printf
("%x\n", TclpThreadGetStackSize ()); }
linked against -ltcl8.5 it prints aa650000
3) TclpThreadGetStackSize has misdesigned return value, returning stack sizes
in an int is a joke.  It must be size_t instead.
4) TclpCheckStackSpace has:
    if (tsdPtr->initialised == 0) {
         * We appear to have not computed the stack size before. Attempt to
         * retrieve it from either the current thread or, failing that, the
         * process accounting limit. Note that we assume that stack sizes do
         * not change throughout the lifespan of the thread/process; this is
         * almost always true.

        tsdPtr->stackDetermineResult = GetStackSize(&tsdPtr->stackSize);
        tsdPtr->initialised = 1;

But, when GetStackSize was computed using pthread_getattr_np rather than say
getrlimit this assumption is wrong for the initial thread.  There
pthread_getattr_np changes over time, as memory is mmapped/unmapped, with
RLIMIT_STACK being the upper limit for it.

So, IMHO 3) needs to be fixed and, when using pthread_getattr_np on Linux, it
should always just use getrlimit RLIMIT_STACK for the initial thread and only
use pthread_getattr_np for other threads (where it doesn't change over time).

Or, disable the broken stack checking altogether.
Comment 3 Jakub Jelinek 2007-02-04 13:53:13 EST
Actually, pthread_getattr_np even for initial thread shouldn't hurt.
But there is a different bug in TclpCheckStackSpace:
register ptrdiff_t stackUsed;
    if (&localVar > tsdPtr->outerVarPtr) {
        stackUsed = (char *)&localVar - (char *)tsdPtr->outerVarPtr;
    } else {
        stackUsed = (char *)tsdPtr->outerVarPtr - (char *)&localVar;

     * Now we perform the actual check. Are we about to blow our stack frame?

    if (stackUsed < (ptrdiff_t) tsdPtr->stackSize) {
        STACK_DEBUG(("stack OK\tin:%p\tout:%p\tuse:%04X\tmax:%04X\n",
                &localVar, tsdPtr->outerVarPtr, stackUsed, tsdPtr->stackSize));
        return 1;
    } else {
        STACK_DEBUG(("stack OVERFLOW\tin:%p\tout:%p\tuse:%04X\tmax:%04X\n",
                &localVar, tsdPtr->outerVarPtr, stackUsed, tsdPtr->stackSize));
        return 0;

The problem is that ptrdiff_t is a signed type and if tsdPtr->stackSize
is bigger than half of the address space (or stackUsed is bigger than that),
then the comparison doesn't do what the writer meant to do.
For Linux and most other targets ptrdiff_t is the same size as size_t, only
size_t is unsigned, so guess just
-    if (stackUsed < (ptrdiff_t) tsdPtr->stackSize) {
+    if ((size_t) stackUsed < tsdPtr->stackSize) {
and a fix for TclpThreadGetStackSize return value could be enough.
Comment 4 Miloslav Trmač 2007-02-04 15:22:54 EST
expect-5.43.0-6 built.  Jakub, thanks a lot.

Note You need to log in before you can comment on or make changes to this bug.