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:
- exercise.tcl [download] added by erikleunissen on 2025-08-17 14:14:32. [details]