Skip to content

Crash with non-consumed Tk timer handler #138791

@picnixz

Description

@picnixz

Crash report

Bug description:

Previously, the following reproducers leaked:

import tkinter
w = tkinter.Tk()
trace = lambda *_, **__: None
trace.evil = type(w.tk)
w.tk.settrace(trace)
w.mainloop()
import tkinter
w = tkinter.Tk()
func = lambda *_, **__: None
func.evil = type(w.tk.createtimerhandler(1234567, print))
w.tk.createtimerhandler(1234567, func)
w.mainloop()

After #138331 was merged, I observed that the first one doesn't leak anymore but the second one crash:

python: ./Modules/_tkinter.c:2784: int Tktt_Traverse(PyObject *, visitproc, void *): Assertion `TkttObject_Check(op)' failed.

The reason is as follows:

  • whenever a timer handler is created, there are actually two references that are created; one regular and one that is used as client data and sent to Tcl
  • BUT a timer handler may not necessarily be destroyed when we deallocate the app.

More precisely, when the handler is called, this extra reference is cleared and the Tcl handler is destroyed. However, if the object is destroyed before that, this never happens, so we have a (non-visible) leak (on previous branches) or a crash (on main).

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

Metadata

Metadata

Assignees

Labels

extension-modulesC modules in the Modules dirtopic-tkintertype-crashA hard crash of the interpreter, possibly with a core dump

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions