Ticket UUID: | 801467 | |||
Title: | incompatible memory debugging options... | |||
Type: | Bug | Version: | None | |
Submitter: | mistachkin | Created on: | 2003-09-06 01:23:26 | |
Subsystem: | 41. Memory Allocation | Assigned To: | patthoyts | |
Priority: | 9 Immediate | Severity: | ||
Status: | Closed | Last Modified: | 2003-10-14 22:37:27 | |
Resolution: | Accepted | Closed By: | patthoyts | |
Closed on: | 2003-10-14 15:37:27 | |||
Description: |
Copied from Tk bug #800419 at dgp's request. Experiencing many crashes and test failures... Here is an example stack trace: Tcl_PanicVA(const char * 0x100cd344, char * 0x0012a42c) line 97 + 42 bytes Tcl_Panic(const char * 0x100cd344) line 134 + 13 bytes TclDbInitNewObj(Tcl_Obj * 0x00ad51d0) line 540 + 10 bytes Tcl_DbNewStringObj(const char * 0x009a4198, int 62, const char * 0x100b8348, int 4618) line 267 + 45 bytes Tcl_AddObjErrorInfo(Tcl_Interp * 0x0086ade8, const char * 0x0012a468, int -1) line 4618 + 25 bytes Tcl_LogCommandInfo(Tcl_Interp * 0x0086ade8, const char * 0x00af57d8, const char * 0x00af5d14, int 38) line 3325 + 18 bytes TclExecuteByteCode(Tcl_Interp * 0x0086ade8, ByteCode * 0x00aba320) line 4134 + 27 bytes TclCompEvalObj(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00add9a8) line 986 + 13 bytes TclObjInterpProc(void * 0x00af0548, Tcl_Interp * 0x0086ade8, int 1, Tcl_Obj * const * 0x0012b29c) line 1080 + 19 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 1, Tcl_Obj * const * 0x0012b29c, const char * 0x00ab8d57, int 13, int 0) line 3095 + 25 bytes Tcl_EvalEx(Tcl_Interp * 0x0086ade8, const char * 0x00ab5b58, int 12812, int 0) line 3525 + 36 bytes Tcl_FSEvalFile(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a8dbe8) line 1445 + 19 bytes Tcl_SourceObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 2, Tcl_Obj * const * 0x0012b654) line 1012 + 16 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 2, Tcl_Obj * const * 0x0012b654, const char * 0x00aa5070, int 56, int 0) line 3095 + 25 bytes Tcl_EvalEx(Tcl_Interp * 0x0086ade8, const char * 0x00aa5070, int 56, int 0) line 3525 + 36 bytes Tcl_Eval(Tcl_Interp * 0x0086ade8, const char * 0x00aa5070) line 3629 + 17 bytes Tcl_GlobalEval(Tcl_Interp * 0x0086ade8, const char * 0x00aa5070) line 4756 + 13 bytes Tcl_PkgRequireEx(Tcl_Interp * 0x0086ade8, const char * 0x00a67608, const char * 0x00000000, int 0, void * * 0x00000000) line 312 + 16 bytes Tcl_PkgRequire(Tcl_Interp * 0x0086ade8, const char * 0x00a67608, const char * 0x00000000, int 0) line 164 + 23 bytes Tcl_PackageObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 3, Tcl_Obj * const * 0x009800dc) line 718 + 21 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 3, Tcl_Obj * const * 0x009800dc, const char * 0x00000000, int 0, int 0) line 3095 + 25 bytes TclExecuteByteCode(Tcl_Interp * 0x0086ade8, ByteCode * 0x00a35868) line 1407 + 36 bytes TclCompEvalObj(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a29590) line 986 + 13 bytes Tcl_EvalObjEx(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a29590, int 0) line 3759 + 13 bytes NamespaceEvalCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 4, Tcl_Obj * const * 0x009800c8) line 2976 + 18 bytes Tcl_NamespaceObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 4, Tcl_Obj * const * 0x009800c8) line 2529 + 21 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 4, Tcl_Obj * const * 0x009800c8, const char * 0x00000000, int 0, int 0) line 3095 + 25 bytes TclExecuteByteCode(Tcl_Interp * 0x0086ade8, ByteCode * 0x00a1e0b8) line 1407 + 36 bytes TclCompEvalObj(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a81c10) line 986 + 13 bytes Tcl_EvalObjEx(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a81c10, int 0) line 3759 + 13 bytes NamespaceEvalCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 4, Tcl_Obj * const * 0x0012cf30) line 2976 + 18 bytes Tcl_NamespaceObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 4, Tcl_Obj * const * 0x0012cf30) line 2529 + 21 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 4, Tcl_Obj * const * 0x0012cf30, const char * 0x00a90246, int 982, int 0) line 3095 + 25 bytes Tcl_EvalEx(Tcl_Interp * 0x0086ade8, const char * 0x00a8ffb0, int 17577, int 0) line 3525 + 36 bytes Tcl_FSEvalFile(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a81190) line 1445 + 19 bytes Tcl_SourceObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 2, Tcl_Obj * const * 0x00a67708) line 1012 + 16 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 2, Tcl_Obj * const * 0x00a67708, const char * 0x100da7da, int 0, int 262144) line 3095 + 25 bytes Tcl_EvalObjv(Tcl_Interp * 0x0086ade8, int 2, Tcl_Obj * const * 0x00a67708, int 262144) line 3206 + 32 bytes Tcl_EvalObjEx(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a81f90, int 262144) line 3744 + 27 bytes Tcl_UplevelObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 1, Tcl_Obj * const * 0x009800c4) line 674 + 20 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 3, Tcl_Obj * const * 0x009800bc, const char * 0x00000000, int 0, int 0) line 3095 + 25 bytes TclExecuteByteCode(Tcl_Interp * 0x0086ade8, ByteCode * 0x00a80090) line 1407 + 36 bytes TclCompEvalObj(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x00a6c610) line 986 + 13 bytes TclObjInterpProc(void * 0x00a62c00, Tcl_Interp * 0x0086ade8, int 7, Tcl_Obj * const * 0x00a22d00) line 1080 + 19 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 7, Tcl_Obj * const * 0x00a22d00, const char * 0x100da7da, int 0, int 262144) line 3095 + 25 bytes Tcl_EvalObjv(Tcl_Interp * 0x0086ade8, int 7, Tcl_Obj * const * 0x00a22d00, int 262144) line 3206 + 32 bytes Tcl_EvalObjEx(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x009c7588, int 262144) line 3744 + 27 bytes Tcl_UplevelObjCmd(void * 0x00000000, Tcl_Interp * 0x0086ade8, int 1, Tcl_Obj * const * 0x009800b8) line 674 + 20 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 3, Tcl_Obj * const * 0x009800b0, const char * 0x00000000, int 0, int 0) line 3095 + 25 bytes TclExecuteByteCode(Tcl_Interp * 0x0086ade8, ByteCode * 0x00a3b430) line 1407 + 36 bytes TclCompEvalObj(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x009c7f88) line 986 + 13 bytes TclObjInterpProc(void * 0x009c7f08, Tcl_Interp * 0x0086ade8, int 8, Tcl_Obj * const * 0x00a29790) line 1080 + 19 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 8, Tcl_Obj * const * 0x00a29790, const char * 0x00000000, int 0, int 0) line 3095 + 25 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 7, Tcl_Obj * const * 0x00980094, const char * 0x00000000, int 0, int 0) line 3047 + 30 bytes TclExecuteByteCode(Tcl_Interp * 0x0086ade8, ByteCode * 0x00a17c28) line 1407 + 36 bytes TclCompEvalObj(Tcl_Interp * 0x0086ade8, Tcl_Obj * 0x009991c0) line 986 + 13 bytes TclObjInterpProc(void * 0x0099e308, Tcl_Interp * 0x0086ade8, int 1, Tcl_Obj * const * 0x0012f9e4) line 1080 + 19 bytes TclEvalObjvInternal(Tcl_Interp * 0x0086ade8, int 1, Tcl_Obj * const * 0x0012f9e4, const char * 0x002f333c, int 6, int 0) line 3095 + 25 bytes Tcl_EvalEx(Tcl_Interp * 0x0086ade8, const char * 0x002f3270 initScript, int 210, int 0) line 3525 + 36 bytes Tcl_Eval(Tcl_Interp * 0x0086ade8, const char * 0x002f3270 initScript) line 3629 + 17 bytes TkpInit(Tcl_Interp * 0x0086ade8) line 51 + 21 bytes Initialize(Tcl_Interp * 0x0086ade8) line 3164 + 9 bytes Tk_Init(Tcl_Interp * 0x0086ade8) line 2804 + 9 bytes Tcl_AppInit(Tcl_Interp * 0x0086ade8) line 161 + 10 bytes Tk_MainEx(int 1, char * * 0x00866e20, int (Tcl_Interp *) * 0x004010b9 Tcl_AppInit(Tcl_Interp *), Tcl_Interp * 0x0086ade8) line 222 + 7 bytes WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x0013374d, int 1) line 130 + 26 bytes WinMainCRTStartup() line 330 + 54 bytes ---- More analysis reveals the following additional diagnostics (tailored for this particular bug): ADD, obj = 0x00ADB540, hPtr = 0x009B3730, file = ..\generic\tclResult.c, line = 828 MARK DELETE, obj = 0x00ADB540, hPtr = 0x009B3730, file = ..\generic\tclExecute.c, line = 1182 DELETE, obj = 0x00ADB540, file = ..\generic\tclExecute.c, line = 1182 ADD, obj = 0x00ADB540, hPtr = 0x009B3730, file = ..\generic\tclExecute.c, line = 1287 MARK DELETE, obj = 0x00ADB540, hPtr = 0x009B3730, file = ..\generic\tclExecute.c, line = 1153 DELETE, obj = 0x00ADB540, file = ..\generic\tclExecute.c, line = 1153 ADD, obj = 0x00ADB540, hPtr = 0x00ADB040, file = unknown, line = 0 ADD (PANIC), obj = 0x00ADB540, hPtr = 0x00ADB040, file = ..\generic\tclBasic.c, line = 4618 As we can see from the above, something (apparently) outside the normal channels (the 'file == "unknown"' line) is responsible for adding this objPtr handle and never removing it from the hash table. However, Tcl_DbCkalloc (really the threaded memory allocator) thinks (probably rightly) that the actual BLOCK of memory is free. ---- After a bit of research, I found the offending code (where the objPtr is allocated first): rootObj = Tcl_NewStringObj(rootName, -1); tclWinReg.c, line 1086 Either this object is being allocated using the wrong function (?) or this object is being freed using the wrong function (TclFreeObj versus Tcl_DbDecrRefCount), because the hash entry remains after the block is freed. Additionally, the object never has it's refcount incremented after it is allocated. I *think* I have come to the conclusion that "tcl/win/makefile.vc" is at fault for this problem. tclWinReg.c (and possibly other files) are NOT being compiled with TCL_CFLAGS (including TCL_MEM_DEBUG). Unless I'm wrong, this could indicate a much bigger problem with the way extensions interact with Tcl's memory allocation and debugging facilities. If an extension compiled without TCL_MEM_DEBUG calls Tcl_NewStringObj in a TCL_MEM_DEBUG enabled tcl.dll (which apparently ALWAYS adds the new objptr to the hash table) and then uses the non-debug Tcl_DecrRefCount __macro__ from tcl.h, major breakage like this bug could occur. Attaching a patch to correct the problem. | |||
User Comments: |
patthoyts added on 2003-10-14 22:37:27:
Logged In: YES user_id=202636 Committed both patches to Tk as well. hobbs added on 2003-10-13 06:26:21: Logged In: YES user_id=72656 assigning to pat since he's halfway done already patthoyts added on 2003-10-09 07:28:30: Logged In: YES user_id=202636 I have tested the tcl patches here against the HEAD. With OPTS=symbols,threads and STATS=memdbg the unpatched tcl will crash horribly on the registry.test and when patched it runs fine. Applied to tcl 8.5 HEAD Tk next. mistachkin added on 2003-10-04 06:18:07: Logged In: YES user_id=113501 Please note that I believe this bug (perhaps not the actual panic) is also present in the core-8-4-branch. The root of the problem is incompatible debug flags between tclsh/wish and the registry/dde packages (which never get the debug flags without the attached fix). dkf added on 2003-09-29 17:23:15: Logged In: YES user_id=79902 New fields *MUST NOT* be introduced into the middle of the Tcl_Obj structure under any circumstances without a major version number change because it runs utterly roughshod over stubs compatability. We also do not wish to have the size of Tcl_Obj (or any other public structure) change between debug and non-debug builds as that makes memory debugging much more difficult. Also remember that on many platforms, a debugging extension may be successfully loaded into a non-debugging core (or the other way round.) mistachkin added on 2003-09-25 21:25:30: Logged In: YES user_id=113501 I'm pretty sure that the fields MUST be before the internal rep, as it is variable size (?). dkf added on 2003-09-11 22:47:40: Logged In: YES user_id=79902 Erk! *After* at the very lease! Don't change the positions of fields between non-debug and debug builds... mistachkin added on 2003-09-06 12:23:54: File Added - 60787: tk_bugfix_801467.diff.zip mistachkin added on 2003-09-06 12:21:07: File Added - 60786: tcl_bugfix_801467.diff.zip mistachkin added on 2003-09-06 12:01:37: File Added - 60785: tk_appinit.diff.zip mistachkin added on 2003-09-06 10:50:56: Logged In: YES user_id=113501 Another very useful thing to have would be the following fields right before the internal rep in the Tcl_Obj struct (only when TCL_MEM_DEBUG is enabled): #ifdef TCL_MEM_DEBUG CONST char *file; /* Source file where originally allocated. */ int line; /* Source line where originally allocated. */ #endif These can be set from inside TclDbInitNewObj, if TclDbInitNewObj is changed according to Tcl feature request #800925. mistachkin added on 2003-09-06 09:31:42: File Deleted - 60761: Logged In: YES user_id=113501 after more testing, still seeing some problems here, removing the patch. mistachkin added on 2003-09-06 08:28:29: File Added - 60762: tcl_appinit.diff.zip Logged In: YES user_id=113501 All the attached patches are related and should be applied. mistachkin added on 2003-09-06 08:23:26: File Added - 60761: makefile.diff.zip |
Attachments:
- tk_bugfix_801467.diff.zip [download] added by mistachkin on 2003-09-06 12:23:54. [details]
- tcl_bugfix_801467.diff.zip [download] added by mistachkin on 2003-09-06 12:21:07. [details]
- tk_appinit.diff.zip [download] added by mistachkin on 2003-09-06 12:01:37. [details]
- tcl_appinit.diff.zip [download] added by mistachkin on 2003-09-06 08:28:29. [details]