Ticket UUID: | 804681 | |||
Title: | traces on errorInfo/errorCode corrupt the evaluation stack | |||
Type: | Bug | Version: | obsolete: 8.4b1 | |
Submitter: | hume | Created on: | 2003-09-11 20:00:06 | |
Subsystem: | 47. Bytecode Compiler | Assigned To: | msofer | |
Priority: | 8 | Severity: | ||
Status: | Closed | Last Modified: | 2003-09-20 01:06:31 | |
Resolution: | Fixed | Closed By: | msofer | |
Closed on: | 2003-09-19 18:06:31 | |||
Description: |
If a variable trace is placed on errorInfo, certain errors cause a core dump in FreeListInternalRep() on both NT and Linux platforms. The crash does not happen with version 8.3 To show the error enter the following at the Tcl prompt: proc show args {puts $args} trace variable errorInfo wu show expr 9/0 Here is the NT stack: FreeListInternalRep(Tcl_Obj * 0x002eb348) line 1386 + 6 bytes TclExecuteByteCode(Tcl_Interp * 0x0029d380, ByteCode * 0x002a5390) line 4198 + 55 bytes TclCompEvalObj(Tcl_Interp * 0x0029d380, Tcl_Obj * 0x00294ba0) line 1008 + 13 bytes Tcl_EvalObjEx(Tcl_Interp * 0x0029d380, Tcl_Obj * 0x00294ba0, int 131072) line 3952 + 13 bytes Tcl_RecordAndEvalObj(Tcl_Interp * 0x0029d380, Tcl_Obj * 0x00294ba0, int 131072) line 142 + 23 bytes Tcl_Main(int 1, char * * 0x00274b30, int (Tcl_Interp *)* 0x00401005 _Tcl_AppInit) line 390 + 24 bytes main() line 110 + 19 bytes mainCRTStartup() line 338 + 17 bytes KERNEL32! 7c4e87f5() | |||
User Comments: |
msofer added on 2003-09-20 01:06:31:
Logged In: YES user_id=148712 Fixed in HEAD and 8.4-branch; patch attached as reference for evetnual backporters msofer added on 2003-09-15 15:21:54: Logged In: YES user_id=148712 The function calls that require protection are: Tcl_ResetResult, Tcl_AddObjErrorInfo, Tcl_AddErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_PosixError, Tcl_LogCommandInfo msofer added on 2003-09-15 15:18:45: Logged In: YES user_id=148712 Pre-modif TEBC had the bug too, but it was more difficult to trigger. Witness mig@cx:/CVS/tcl8.3.4/unix$ ./tclsh % info patch 8.3.4 % proc show args {puts $args} % trace variable errorInfo wu show % expr {1+9/0} errorInfo {} w errorInfo {} w divide by zero % exit Segmentation fault Before those modifs, an instruction that caused an error removed its arguments from the stack before "goto checkForCatch", so that the corruption only happened when there were objects in the stack deeper than them - in the example, the "1" is in the stack when the division error occurs, so that removing the "9" and "0" is not quite enough. Now the stack is not cleared before "goto checkForCatch", so that the stack is always corrupted if error logging causes TEBC to be called. msofer added on 2003-09-14 21:04:22: Logged In: YES user_id=148712 Explicit bug description, for the record: (a) every call from TEBC to an outside function that may evaluate a bcc'ed script has to be protected by a (DE)CACHE_STACK_INFO() macro pair to insure the stack's integrity - namely, so that the nested TEBC knows where the not-in-use part of the stack starts. Failure to do so corrupts the evaluation stack. (b) due to the trace mechanism, every variable modification may end up evaluating bcc'ed code. Therefore, every call that touches a variable should be protected as above. (c) the error mechanism modifies ::errorInfo. But error reports are not protected in TEBC. Thus, a trace on ::errorInfo that calls a proc corrupts the evaluation stack. One possible fix is to identify every instance at risk and protect it. I have not yet been able to understand why TEBC was immune to this problem before, ie, what (subtle?) pre-existing protection I destroyed. TEBC will be fixed shortly with either a restoration of the previous mechanism, or else a bunch of new macro pairs. msofer added on 2003-09-13 04:14:11: Logged In: YES user_id=148712 Good catch Don! There's more of the same, the following still crashes after your patch: proc show args {puts $args} trace variable errorInfo wu show incr a ;# assuming no variable a is defined I'll hunt down all similar things in TEBC, now that you discovered what was happening. I'd also try to understand how those modifs introduced the bug dgp added on 2003-09-13 04:00:40: File Added - 61387: 804681.patch Logged In: YES user_id=80530 Here's a patch against the tip of the core-8-4-branch that fixes the segfault in the reported script. Leaving the report open for further review from msofer. dgp added on 2003-09-13 00:02:29: Logged In: YES user_id=80530 The segfault happens as the bytecode execution engine tries to clear away items on the stack. It decrements and tries to free a list value that has already been freed. This list value is the $args value that was a local variable in the [show] proc. It has been freed already because it was freed when [show] returned, as one would expect. It's a mystery why there's a reference to $args on the bytecode execution stack, and another mystery why that reference, if it must indeed exist, never accounted for itself with a refCount. dgp added on 2003-09-12 09:24:31: Logged In: YES user_id=80530 This bug was introduced by msofer's commits on 2002-06-18. dgp added on 2003-09-12 05:43:03: Logged In: YES user_id=80530 Between 8.4a4 and 8.4b1 even. dgp added on 2003-09-12 05:27:51: Logged In: YES user_id=80530 Thanks for the report. Further investigation reveals this bug entered sometime between releases Tcl 8.4a4 and Tcl 8.4.0. |
Attachments:
- 804681.patch [download] added by dgp on 2003-09-13 04:00:40. [details]