From: SourceForge.net <no...@so...> - 2008-07-17 21:57:31
|
Bugs item #2017857, was opened at 2008-07-14 11:33 Message generated for change (Comment added) made by dkf You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=2017857&group_id=10894 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: 45. Parsing and Eval Group: current: 8.6a1 Status: Open Resolution: None Priority: 9 Private: No Submitted By: Neil Madden (tallniel) Assigned to: miguel sofer (msofer) Summary: NRE crash calling tailcall from [dict with] Initial Comment: I'm seeing a crash testing NRE tailcall on Windows XP, using a tclsh86sg built from current CVS head (VS.NET 2003, static, symbols). Currently trying to track down the problem, possibly a funny interaction between [uplevel] and [tailcall]. I'll try and create a minimal example. In the meantime, the code that causes the crash is http://wiki.tcl.tk/16695. Copy that code to an editor, and then add the following interp alias at the top: interp alias {} tailcall {} ::tcl::unsupported::tailcall Then change the term::fold procedure to use [tailcall]: proc term::fold {f z t} { match $t { {Lambda var body} -> { tailcall $f lam $z $var $body } {Apply a b} -> { tailcall $f app $z [fold $f $z $a] [fold $f $z $b] } {Var name} -> { tailcall $f var $z $name } {IntLit i} -> { tailcall $f int $z $i } {Add a b} -> { tailcall $f add $z [fold $f $z $a] [fold $f $z $b] } {Sub a b} -> { tailcall $f sub $z [fold $f $z $a] [fold $f $z $b] } {Mul a b} -> { tailcall $f mul $z [fold $f $z $a] [fold $f $z $b] } {Div a b} -> { tailcall $f div $z [fold $f $z $a] [fold $f $z $b] } } } This is an interesting case, as [match] uses both [uplevel] and [dict with], so plenty of tricksiness going on here. Possibly might not be ok to call [tailcall] here, but should produce an error rather than a crash. Crash seems to be an invalid pointer deref (cannot access location 0x00000014). Stack dump: > tclsh86sg.exe!TclExecuteByteCode(Tcl_Interp * interp=0x00afa8b8, ByteCode * codePtr=0x00b86ae0) Line 2741 + 0xc C tclsh86sg.exe!NRPostProcess(Tcl_Interp * interp=0x00afa8b8, int result=0, int objc=0, Tcl_Obj * const * objv=0x00000000) Line 7419 + 0x10 C tclsh86sg.exe!TclEvalObjEx(Tcl_Interp * interp=0x00afa8b8, Tcl_Obj * objPtr=0x00b5e5e8, int flags=0, const CmdFrame * invoker=0x00afb314, int word=1) Line 5327 + 0x11 C tclsh86sg.exe!Tcl_CatchObjCmd(void * dummy=0x00000000, Tcl_Interp * interp=0x00afa8b8, int objc=3, Tcl_Obj * const * objv=0x00afb33c) Line 253 + 0x1e C tclsh86sg.exe!Tcl_EvalObjv(Tcl_Interp * interp=0x00afa8b8, int objc=3, Tcl_Obj * const * objv=0x00afb33c, int flags=2097152) Line 4079 + 0x15 C tclsh86sg.exe!TclExecuteByteCode(Tcl_Interp * interp=0x00afa8b8, ByteCode * codePtr=0x00b67840) Line 2696 + 0x1c C tclsh86sg.exe!NRPostProcess(Tcl_Interp * interp=0x00afa8b8, int result=0, int objc=0, Tcl_Obj * const * objv=0x00000000) Line 7419 + 0x10 C tclsh86sg.exe!TclEvalObjEx(Tcl_Interp * interp=0x00afa8b8, Tcl_Obj * objPtr=0x00b862d0, int flags=0, const CmdFrame * invoker=0x00afb1c0, int word=2) Line 5327 + 0x11 C tclsh86sg.exe!Tcl_WhileObjCmd(void * dummy=0x00000000, Tcl_Interp * interp=0x00afa8b8, int objc=3, Tcl_Obj * const * objv=0x00afb1f0) Line 4029 + 0x1e C tclsh86sg.exe!Tcl_EvalObjv(Tcl_Interp * interp=0x00afa8b8, int objc=3, Tcl_Obj * const * objv=0x00afb1f0, int flags=2097152) Line 4079 + 0x15 C tclsh86sg.exe!TclEvalEx(Tcl_Interp * interp=0x00afa8b8, const char * script=0x00b81ec8, int numBytes=6872, int flags=0, int line=219) Line 5044 + 0x16 C tclsh86sg.exe!Tcl_EvalEx(Tcl_Interp * interp=0x00afa8b8, const char * script=0x00b81ec8, int numBytes=6872, int flags=0) Line 4751 + 0x17 C tclsh86sg.exe!Tcl_FSEvalFileEx(Tcl_Interp * interp=0x00afa8b8, Tcl_Obj * pathPtr=0x00b69f28, const char * encodingName=0x00000000) Line 1776 + 0x13 C tclsh86sg.exe!Tcl_Main(int argc=-1, char * * argv=0x00af38e8, int (Tcl_Interp *)* appInitProc=0x00401070) Line 443 + 0x11 C tclsh86sg.exe!main(int argc=2, char * * argv=0x00af38e0) Line 102 + 0x12 C tclsh86sg.exe!mainCRTStartup() Line 259 + 0x19 C kernel32.dll!7c816fd7() Offending line in tclExecute.c: iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr; I can't dig into that structure to see what those fields are set to as iPtr is just a #define, and the interp pointer shows nothing interesting. Looks like iPtr->cmdFramePtr is invalid at this point. ---------------------------------------------------------------------- >Comment By: Donal K. Fellows (dkf) Date: 2008-07-17 22:57 Message: Logged In: YES user_id=79902 Originator: NO done, but leaving open as I ran across a problem The problem was that while TclNREvalObjEx works just fine if the thing being evaluated is a general script, it crashes if it is the same command twice (see test dict-21.10 for an example). I've worked around it with TclNR_EvalObj but that breaks TIP#280 promises, so this is a short-term solution only. Two places to fix in tclDictObj.c, one at end of DictUpdateCmd, one at end of DictWithCmd. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2008-07-14 13:17 Message: Logged In: YES user_id=79902 Originator: NO sounds like that means that [dict with] needs NRE-ing ---------------------------------------------------------------------- Comment By: Neil Madden (tallniel) Date: 2008-07-14 11:50 Message: Logged In: YES user_id=102050 Originator: YES Definitely an interaction with [dict with] rather than [uplevel]. Minimal script to reproduce bug: package require Tcl 8.6a1 proc test env { dict with env { tcl::unsupported::tailcall test {} } } test "" (Note: if/when fixed this proc will result in an infinite loop). ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2008-07-14 11:45 Message: Logged In: YES user_id=79902 Originator: NO Fact points to help chasing this down: [dict with] is not bytecoded (I didn't have the time to figure it out) and has a substantial amount of code to execute after the body. Some of said code *must* execute, even in error cases; disrupting that will cause trouble, memory leaks, nasal demons, the end of the world, cats and dogs living together, etc. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=2017857&group_id=10894 |