Itcl - the [incr Tcl] extension

View Ticket
Login
Ticket Hash: d07590ce7dd0138ce43bdf4b22df558948030186
Title: segfault with tailcall and coroutines and Itcl method calls
Status: Open Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: Resolution: Open
Last Modified: 2015-05-22 15:39:41
Version Found In: trunk
User Comments:
dgp added on 2015-05-22 15:36:11:
The other ticket was getting too many variants, and this
one is a clean segfault:

package require Itcl 4
itcl::class juggler {
    variable name
    variable target
    constructor {_n _t} {
        set name $_n
        set target $_t

        ::proc toss args {
            tailcall my {*}[info level 0]
        }
    }
    method toss {{value ""}} {
        if {[llength [info level 0]] == 2} {
            set value [yield [info coroutine]]
        }
        if {$value ne ""} {
puts "$name toss $value -- [namespace current]-[namespace which toss]"
            toss $value
        }
    }
}

coroutine j1 [juggler #auto Larry [
coroutine j3 [juggler #auto Moe {}] toss ]] toss X


Result:
Larry toss X -- ::juggler-::juggler::
make: *** [shell] Segmentation fault


#0  0x000000000054f21b in TclPushProcCallFrame (clientData=0x8b3d00, 
    interp=0x81f6e0, objc=2, objv=0x96ed90, isLambda=0)
    at /home/dgp/fossil/tcl/generic/tclProc.c:1598
#1  0x000000000054f40d in TclNRInterpProc (clientData=0x8b3d00, 
    interp=0x81f6e0, objc=2, objv=0x96ed90)
    at /home/dgp/fossil/tcl/generic/tclProc.c:1707
#2  0x0000000000414c40 in Dispatch (data=0x869ee8, interp=0x81f6e0, result=0)
    at /home/dgp/fossil/tcl/generic/tclBasic.c:4360
#3  0x0000000000414cce in TclNRRunCallbacks (interp=0x81f6e0, result=0, 
    rootPtr=0x0) at /home/dgp/fossil/tcl/generic/tclBasic.c:4393
#4  0x000000000041442e in Tcl_EvalObjv (interp=0x81f6e0, objc=5, 
    objv=0x82cfe0, flags=2097168)
    at /home/dgp/fossil/tcl/generic/tclBasic.c:4123
#5  0x0000000000416be8 in TclEvalEx (interp=0x81f6e0, 
    script=0x87e780 "package require Itcl 4\n

....
(gdb) print *procPtr->cmdPtr
Cannot access memory at address 0x100000080

dgp added on 2015-05-22 15:39:41:
Next, take coroutines out by replacing final command with:

[juggler #auto dgp {}] toss X

Produces output:

dgp toss X -- ::juggler-::juggler::toss
command "toss" already exists in namespace "::juggler"
    while executing
"error "command \"$m\" already exists in namespace \"$ns\"""
    (class "::itcl::clazz" method "unknown" line 5)
    invoked from within
"my toss X"
    invoked from within
"toss $value"
    (object "::juggler0" method "::juggler::toss" body line 7)
    invoked from within
"[juggler #auto dgp {}] toss X"


Note that in this case the [namespace which] properly resolves.

Then the weirdness is why unknown is getting in the picture when
the "toss" method should already be known.