| Ticket UUID: | 4a25f316f7bb5d3bd50d1608b66f6acb5ca445fd | |||
| Title: | Embedded application exits with BadDrawable when its container is destroyed | |||
| Type: | Bug | Version: | 8.6.18, 9.0.5, 9.1b1 | |
| Submitter: | serhiy.storchaka | Created on: | 2026-09-26 20:12:03 | |
| Subsystem: | 74. Application Embedding | Assigned To: | jan.nijtmans | |
| Priority: | 5 Medium | Severity: | Important | |
| Status: | Pending | Last Modified: | 2026-10-09 15:56:29 | |
| Resolution: | Fixed | Closed By: | nobody | |
| Closed on: | 2026-10-07 16:33:13 | |||
| Description: |
An embedded Tk application can exit when its container is destroyed while it still has pending drawing: X Error of failed request: BadDrawable (invalid Pixmap or Window parameter) Major opcode of failed request: 55 (X_CreateGC) Destroying the container window also destroys the embedded window in the X server. If the embedded application redraws its toplevel before it has processed that, the drawing request fails with BadDrawable. ErrorProc() in tkError.c ignores such errors for windows deleted externally, but only BadWindow errors, so this one goes to the default Xlib handler, which exits the process. The error can also arrive after Tk has already deleted the window. Tk 8.4 and 8.5 ignored errors for recently deleted windows (TkpWindowWasRecentlyDeleted()), but this was removed together with the XID management in [8356aa0eec], so this case is not handled since 8.6.0 either. Reproducer (parent.tcl runs child.tcl embedded in a container frame):
# child.tcl
. configure -bg green -highlightthickness 2 -bd 2 -relief sunken
update
puts ready; flush stdout
gets stdin ;# no X events are processed meanwhile
. configure -bg blue
update idletasks
winfo pointerxy .
puts alive; flush stdout
# parent.tcl
frame .f -container 1 -width 200 -height 100
pack .f; update
set fd [open "|[list [info nameofexecutable] child.tcl -use [winfo id .f]] 2>@1" r+]
fconfigure $fd -buffering line
while {[gets $fd line] >= 0 && $line ne "ready"} {}
destroy .f
update
puts $fd go
puts [read $fd]
exit
The child prints the X error and exits instead of printing "alive" (every time with core-8-6-branch, core-9-0-branch and main). This also makes test unixEmbed-9.2 fail in about 1 of 6 runs with error flushing "file9": broken pipe: the child process used by the tests has exited after the container of its embedded toplevel was destroyed in an earlier test. The X error message is not visible, because the child's stderr is only read when its channel is closed. [3610628fff] may be a similar issue. | |||
| User Comments: |
serhiy.storchaka added on 2026-10-09 15:56:29:
The growth is fixed in branch embed-container-destroyed, see [5f7ba8c5a3]: deleted windows are now recorded only after a toplevel of the application has been embedded. The new check-in is on top of main and restores the backed out fix, so a plain merge brings it back. The fix was also backed out in core-9-0-branch and core-8-6-branch, where the backout needs to be reverted too. jan.nijtmans added on 2026-10-09 13:58:01: It looks like this fix is causing a memory leakage. See [this] ticket. So, what shall we do? jan.nijtmans added on 2026-10-07 16:33:13: Fixed in [dd18288b38855f19|trunk]. Backported to core-9-0-branch and core-8-6-branch. Many thanks! Closing serhiy.storchaka added on 2026-09-26 20:15:26: Proposed fix in branch embed-container-destroyed: ErrorProc() ignores BadDrawable errors like BadWindow errors, also for windows deleted after the failed request. Recently deleted windows are recorded in a new field at the end of TkDisplay. unixEmbed-9.2 no longer sporadically fails. The new test unixEmbed-9.3 adds a more reliable reproducer. | |||
Home
Timeline
Branches
Tags
Forum
Tickets
Download
Wiki