Tcl Source Code

View Ticket
Login
Ticket UUID: 3161787
Title: Unhandled exception with threaded itcl objects
Type: Bug Version: obsolete: 8.5.11
Submitter: tombert Created on: 2011-01-19 15:34:54
Subsystem: 49. Threading Assigned To: aku
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2018-01-10 21:01:18
Resolution: Out of Date Closed By: sebres
    Closed on: 2018-01-10 21:01:18
Description:
I run into this from a "bigger" application where I did call an unknown method from an itcl object - doing this several times the application crashes with an unhandled exception. The small example I posted below brings up an "unable to realloc xxxxx bytes" before but then crashes in the same manner. So I assume it's something with the error propagation between the threads ...

How to reproduce: source the two procedures and call dotest from the console several times - sometimes it crashes on first call, sometimes I need to call it three times.
Environment used: Windows XP, TCL 8.5.9, Thread 2.6.7, Itcl 3.4

proc thread_procCrash {args} {
    thread::send -async $::tid [concat testObj unkowncommand]
}
proc dotest {} {
    package re Thread

    set ::tid [thread::create {thread::wait}]
    ## create initial shared variables
    puts $::tid

    foreach package {Itcl} {thread::send $::tid [list package require $package]}
    foreach import {itcl::*} {thread::send $::tid [list namespace import $import]}

    thread::send $::tid {class TestClass {
        public method z {} {expr 1+1}
        public method a {} {expr 1+1}
        public method b {} {expr 1+1}
        public method c {} {expr 1+1}
        public method d {} {expr 1+1}
        public method e {} {expr 1+1}
        public method f {} {expr 1+1}
        public method g {} {expr 1+1}
        public method h {} {expr 1+1}
        public method i {} {expr 1+1}
        public method j {} {expr 1+1}
        public method k {} {expr 1+1}
        public method l {} {expr 1+1}
        public method m {} {expr 1+1}
        public method n {} {expr 1+1}
        public method o {} {expr 1+1}
        public method p {} {expr 1+1}
        public method q {} {expr 1+1}
        public method r {} {expr 1+1}
        public method s {} {expr 1+1}
        public method t {} {expr 1+1}
        public method u {} {expr 1+1}
        public method v {} {expr 1+1}
        public method w {} {expr 1+1}
        public method x {} {expr 1+1}
        public method y {} {expr 1+1}
        public variable hello {}}
    }
    thread::send $::tid {TestClass testObj}

    for {set index 0} {$index < 100000} {incr index} {thread_procCrash}
}

thx for your support
User Comments: sebres added on 2018-01-10 21:01:18:
Seems to be itcl-issue (possible solved with suggested patch), so I close it here.

tombert added on 2012-04-11 20:05:49:
Added new tracker: https://sourceforge.net/tracker/?func=detail&aid=3516841&group_id=13244&atid=113244

sebres added on 2012-04-11 17:20:23:
this should be moved to [incr Tcl] bug tracker...

sebres added on 2012-04-11 17:16:40:

File Added - 440866: sebres-3.4-patch3.patch

sebres added on 2012-04-11 17:15:41:
I can not find quickly the fix for this only (have too much changes relative main stream). I made the patch included 70% of my fork code (attached). I had not yet tested this patch.

In addition you have new function "itcl::struct <class> <objname>" that allow you to create an object without call of class constructors - I use this for unserialize purposes.

But caution - my completelly fork does not pass some Itcl tests (I don't know about this 70%-patch).

tombert added on 2012-04-11 16:16:51:
Tried ~50 times with no crash.

sebres added on 2012-04-11 13:47:32:
I had uploaded my itcl34.dll (32 bit), could you reproduce it within?

sebres added on 2012-04-11 13:46:04:

File Added - 440847: itcl34.dll

tombert added on 2012-04-11 02:53:05:
updated TCL and TK head - still crash.
Note: I'am using "wish" to run the test.

tombert added on 2012-04-11 02:40:58:
same effect with itcl-3-branch (HEAD) and itcl-3-4-1 - only a single line in a single file changed.

tombert added on 2012-04-11 02:20:29:
retested in W7 still crash

sebres added on 2012-04-10 22:36:03:
I could not more reproduce esception with current itcl-3-branch from fossil (3.4.1) - but currently i have my own customized fork only.

Already fixed? 
Could you please test it with 3.4.1 in your environment?

If not yet - I will check my fork and public a patch for this.

sebres added on 2012-04-10 21:44:02:
reproduced with WinXP, thread2.7, thread2.6.7, Itcl3.4
seems to be Itcl bug (cause the same with namespace does not produce exception) :

>>> SUCCESS >>>
package re Thread
## init ------
set ::tid [thread::create {
  #proc _out_err {args} {puts $args}; 
  #thread::errorproc _out_err;
  thread::wait
}]
## crash ------
proc thread_procCrash {args} {
  thread::send -async $::tid {testnamespace::unkowncommand}
}
## do test ------
proc dotest {} {
  thread::send -async $::tid {namespace eval testnamespace {}}
  for {set index 0} {$index < 100000} {incr index} {thread_procCrash}
}
## do test ------
dotest
<<< <<<

>>> BOOM >>>
package re Thread
## init ------
set ::tid [thread::create {
  #proc _out_err {args} {puts $args}; 
  #thread::errorproc _out_err;
  thread::wait
}]
## crash ------
proc thread_procCrash {args} {
  thread::send -async $::tid {testObj unkowncommand}
}
## do test ------
proc dotest {} {
  thread::send -async $::tid {
    package require Itcl
    itcl::class TestClass {}
    TestClass testObj
  }
  for {set index 0} {$index < 100000} {incr index} {thread_procCrash}
}
## do test ------
dotest
<<< <<<

tombert added on 2012-04-10 16:06:05:
retested - still valid in 8.5.11

tombert added on 2011-05-13 22:22:07:
I would like to bump this up since it is already the second thread related crash I discovered:
https://sourceforge.net/tracker/index.php?func=detail&aid=3301634&group_id=10894&atid=110894

thx

tombert added on 2011-01-20 03:32:24:
Well yes ... it's not so easy to trace ... in the original I don't have this panic - only the unhandled exception pointing to non-existing memory.
Next thing: the crash happens only when having so many public methods - if I do the test with only one method inside the class I can't reproduce.

I only can do assumptions here from my experience:
When I send synchronous commands to the thread I get the exceptions propagated to the calling thread, but what happens if I do it -async? Where is the error gone or how can I check if an error happens? - lacking this method I would assume the error message should be "lost" - thus why the need for so much memory?

thx

msofer added on 2011-01-19 22:49:54:
No that "unable to realloc xxxx bytes" is the panic message in Tcl_Realloc, file tclCkAlloc.c. So this crash is actually a panic due to memory exhaustion.

IOW, it may have little to do with the original, if the original did not have a similar message.

Attachments: