Tcl Source Code

View Ticket
Login
Ticket UUID: 46442d45efc02ebf03e3054227210fbc54a3da2c
Title: memleak in dict implementation, AllocChainEntry
Type: Bug Version: trunk
Submitter: dgp Created on: 2023-11-27 15:33:26
Subsystem: 15. Dict Object Assigned To: nobody
Priority: 5 Medium Severity: Important
Status: Open Last Modified: 2024-04-19 12:40:50
Resolution: None Closed By: nobody
    Closed on:
Description:
From valgrind output...

==2967== 13,922 (1,456 direct, 12,466 indirect) bytes in 26 blocks are definitely lost in loss record 12,124 of 12,223
==2967==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==2967==    by 0x61E2F4: TclpAlloc (tclAlloc.c:699)
==2967==    by 0x446188: Tcl_Alloc (tclCkalloc.c:1038)
==2967==    by 0x4FE398: AllocChainEntry (tclDictObj.c:245)
==2967==    by 0x540BC2: CreateHashEntry (tclHash.c:322)
==2967==    by 0x4FE532: CreateChainEntry (tclDictObj.c:291)
==2967==    by 0x4FF42B: SetDictFromAny (tclDictObj.c:706)
==2967==    by 0x4FF6DA: GetDictFromObj (tclDictObj.c:751)
==2967==    by 0x50022E: Tcl_DictObjFirst (tclDictObj.c:1159)
==2967==    by 0x59D313: TclMergeReturnOptions (tclResult.c:839)
==2967==    by 0x59DDAF: Tcl_SetReturnOptions (tclResult.c:1111)
==2967==    by 0x52164C: TEBCresume (tclExecute.c:2342)
==2967==    by 0x436F20: TclNRRunCallbacks (tclBasic.c:4612)
==2967==    by 0x439AE4: TclEvalObjEx (tclBasic.c:6072)
==2967==    by 0x439A78: Tcl_EvalObjEx (tclBasic.c:6053)
==2967==    by 0x5B1341: AfterProc (tclTimer.c:1182)
==2967==    by 0x5B019A: TimerHandlerEventProc (tclTimer.c:593)
==2967==    by 0x57EE9A: Tcl_ServiceEvent (tclNotify.c:710)
==2967==    by 0x57F2D6: Tcl_DoOneEvent (tclNotify.c:1007)
==2967==    by 0x51D865: Tcl_VwaitObjCmd (tclEvent.c:1731)
==2967==    by 0x436EBC: Dispatch (tclBasic.c:4596)
==2967==    by 0x436F20: TclNRRunCallbacks (tclBasic.c:4612)
==2967==    by 0x436803: Tcl_EvalObjv (tclBasic.c:4355)
==2967==    by 0x438F13: TclEvalEx (tclBasic.c:5451)
User Comments: sebres added on 2024-04-19 12:40:50:

Is this leaked by AllocChainEntry or by TclMergeReturnOptions or what?

No... This traceback shows the allocation "history". A leak itself is somewhere else (there is no paired free for that alloc), not necessarily in dict implementation, and maybe even simple overwrite or lost of returned options (that dict object), because it was initially set by Tcl_SetReturnOptions.

And since it is TEBCresume, it may be some missed de-cache or whatever causing an oblivion of objects in exec-stack. E. g. I saw some potentially missed DECACHE_STACK_INFO/CACHE_STACK_INFO in merge of TIP#636 and some following check-ins, for instance, IIRC, in INST_LIST_INDEX_IMM, as I was searching for an performance issue by iterate/llength over dict (have no time for deeper analysis at the moment).

Anyway, if you don't see it in 8.7, can you try to revert 91c2f411e7e71552, Don? Is it still there without that check-in?


dgp added on 2024-04-17 17:31:27:
Ignore the April 15 comment.  It seems to be wrong.

dgp added on 2024-04-15 17:09:10:
The hash table revisions made in [167e0635db] also correct this problem.

dgp added on 2023-12-06 19:52:01:
Still trying to isolate.  The test files that create the symptom are
http11.test and http.test

dkf added on 2023-11-27 16:59:08:

Is this leaked by AllocChainEntry or by TclMergeReturnOptions or what?

AllocChainEntry is just making an entry in the hashtable, and is little more than a wrapper around Tcl_Alloc. It (effectively) returns a pointer to the memory it allocates; as such, it cannot leak itself. This instead looks to be a leak further up the stack, probably in TclMergeReturnOptions, Tcl_SetReturnOptions or (hopefully not) TEBCresume.

Or maybe those are all bystanders and these are just the places where things are correctly allocated, and the problem is the absence of a Tcl_DecrRefCount elsewhere? (That's what I really suspect is the problem, FWIW.)

A smaller example that can reproduce this would help...