Menu

#212 shared init code causes trouble

3.4
closed-fixed
5
2011-07-07
2011-07-07
Don Porter
No

This script fails in a Tcl 8.6 interp:

if 1 {
itcl::class Foo {
constructor {args} {concat} {}
}
itcl::class Bar {
constructor {args} {concat} {global G}
}
}
Bar bar
Foo foo
Bar baz

variable "G" has traces: can't use for upvar
while executing
"global G"
while constructing object "::baz" in ::Bar::constructor (body line 1)
invoked from within
"Bar baz"

The problem is that the value {concat}
serves as the init code for two classes
(which means in two namespace contexts)
and that value is shared. So, as the two
constructors interleave, that code body gets
repeatedly recompiled to reset back to the
proper compile environment. Then the
additional problem arises that the initcode
and the constructor body share a callframe
and the recompile of one without recompiling
the other leads to an internal inconsistency
that manifests as a mangled state of the local
variables.

The underlying problem is that Tcl's internal
routine TclProcCompileProc() expects the "body"
argument passed to it to be unshared. Itcl takes
care of that constraint with its method bodies,
but has not done so with initCode. The fix is very
easy, just the addition of a Tcl_DuplicateObj() at
the right place.

The same issue is what causes tests chain-2.*
to fail when running the Itcl test suite.

Discussion

  • Don Porter

    Don Porter - 2011-07-07

    Fix committed for Itcl 3.4.1

     
  • Don Porter

    Don Porter - 2011-07-07
    • status: open --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB