Menu

#2815 memory leak in interpreter creation/deletion loop

obsolete: 8.5a2
closed-fixed
7
2011-05-08
2004-07-20
No

Running the loop

while 1 {
interp create i
interp delete i
}

results in process memory growing endlessly.

Miguel Sofer and I have been discussing the bug
at length in email and the Tcl'ers Chat and have
reached the conclusion that the problem arises when
a proc's bytecode representation lives until the interp
is deleted (generally, because some shared literal
has an internal representation of tclLocalVarType
that designates a variable in the proc).

I now suspect that the problem is ameliorated if
internal representations of global literals are destroyed
earlier in the process of taking down an interp.
I'm developing a patch to test this hypothesis.

Discussion

  • Kevin B KENNY

    Kevin B KENNY - 2004-07-20

    Logged In: YES
    user_id=99768

    The attached patch appears to correct the problem
    as described.

     
  • Kevin B KENNY

    Kevin B KENNY - 2004-07-20

    Patch to free literal internal reps early.

     
  • miguel sofer

    miguel sofer - 2004-07-21

    Logged In: YES
    user_id=148712

    The patch has been committed, ticket still open until I
    reach a full understanding of the issue and am satisfied of
    its correction and completeness. Issues:

    (0) I still do not see why the leak was only observable in
    windows.

    (1) it frees the internal rep of every shared literal, but
    unshared literals are not covered. This will break any
    reference loop where a shared literal intervenes, but leaves
    the issue untouched for loops of unshared lits

    (2) it panics on a literal with no string rep; this can only
    occur with unshared literals created via TclAddLiteralObj(),
    so it is not really an issue while issue (1) remains untouched

     
  • miguel sofer

    miguel sofer - 2004-07-23
    • status: open --> closed-fixed
     
  • miguel sofer

    miguel sofer - 2004-07-23

    Logged In: YES
    user_id=148712

    Committed a change in tclLocalVarnameType that removes the
    reference to the proc, and hence renders these circular
    references impossible.
    Closing the ticket, the bug is now fixed twice over ;)

     
  • Don Porter

    Don Porter - 2011-04-25

    Miguel, can you comment on what importance
    the call to TclCleanupLiteralTable() still has?

     
  • miguel sofer

    miguel sofer - 2011-04-26

    Chatlogs:

    dgp For when I get back, I'm curious about the purpose of TclCleanupLiteralTable().
    kbk dgp - ISTR that the literal table is one case where it's possible that Tcl_Obj's' int-reps can hold references to each other, and that a bespoke cleanup was needed to break cycles and actually kill them, but I may
    dgp here's my observations
    dgp TCLT() is called in only one place, DeleteInterpProc(.) in tclBasic.c
    dgp About 100 lines later in the same DIP(.) routine, TclDeleteLiteralTable() is called.
    dgp TCLT only removes intreps of literal values.
    dgp TDLT actually frees them, which would destroy intreps if any were still around.
    dgp The value of the TCLT pass is not clear to me.
    dgp Commenting it out has no effect on the success of the test suite.
    dgp hmmm, TCLT is not in Tcl 8.4, so the history of its origin ought to be findable....

     
  • miguel sofer

    miguel sofer - 2011-05-08
    • assigned_to: msofer --> kennykb
     
  • Don Porter

    Don Porter - 2011-05-10

    Yes, kbk did that to fix (work around?) a leak tearing down interps.

    Then you fixed the underlying cause shortly afterward.

    http://core.tcl.tk/tcl/info/63de804c96

    After that, TclCleanupLiteralTable() can be
    removed. I'd like to do so. Why have code
    you don't need? But I want to know what others
    think. Are we keeping it around just as another
    layer of protection in case another similar bug
    pops up?

     
  • miguel sofer

    miguel sofer - 2011-05-10

    Agreed: remove

     
  • Kevin B KENNY

    Kevin B KENNY - 2011-05-11

    Agreed. It was a hack to deal with circular Tcl_Obj references. Miguel fixed the circular references. It can go.