Tk Source Code

View Ticket
Login
Ticket UUID: ff2ca8b34c922c42dea81e9bd7aaf89d23d09284
Title: Tk holds on to application names of deleted interpreters on macOS + segfault when sending to a "zombie" appname
Type: Bug Version: 8.6.16
Submitter: erikleunissen Created on: 2025-08-17 13:07:27
Subsystem: 58. [send] Assigned To: nobody
Priority: 5 Medium Severity: Severe
Status: Open Last Modified: 2025-08-17 20:13:29
Resolution: None Closed By: nobody
    Closed on:
Description:
Under macOS Tk doesn't remove the name of a child interp when it is deleted.
Therefore, the list of interps returned by "winfo interp" grows steadily while
child interpreters are created and deleted [*].

What's more, I see that tests winfo-5.4 and winfo-5.5 work around this issue. I
wondered why the results for these test are defined in such a complicated manner.
Now I understand. But if I'm right, it is contrary to the purpose of tests to hide
bugs. And it is quite remarkable that these work-arounds are made for tests that
run on all platforms, while the problem exists in just one platform.

Lastly, when sending to a Tk application that exists in [winfo interps], but whose
interp was actually deleted, the process segfaults.

The following script (also attached as file exercise.tcl) demonstrates the
faulty behaviour.

--
package require Tk
interp create child1
child1 eval {
    package require Tk
    tk appname foo1
}
interp create child2
child2 eval {
    package require Tk
    tk appname foo2
}
interp delete child1
interp delete child2
puts "winfo interps: |[winfo interps]|"; flush stdout
send foo1 {set tcl_version}
--

Output from a wish 8.6.16 on macOS:

% wish exercise.tcl
winfo interps: |foo2 foo1 exercise.tcl|
zsh: segmentation fault  wish exercise.tcl
%

--
[*] At some point in test file winfo.test in the Tk test suite the list of
    aplication reaches some 18 entries.
User Comments: chrstphrchvz added on 2025-08-17 20:13:29:

Using AddressSanitizer, I can confirm the example script triggers use-after-free of stale pointers to a deleted interpreter. In Tk_SetAppName() there is an old comment TODO: DeleteProc. Presumably the never-implemented DeleteProc() is where such pointers to deleted interpreters would be cleaned up.


Attachments: