indygreg / python-build-standalone

Produce redistributable builds of Python
BSD 3-Clause "New" or "Revised" License
1.71k stars 107 forks source link

Not able to run a tkinter program #146

Open yijianli-autra opened 1 year ago

yijianli-autra commented 1 year ago

I am using the bazel/rules_python to compile our python code. according to the configuration, we are using the cpython-3.9.13+20220802-x86_64-unknown-linux-gnu-install_only.tar.gz as our python interpreter. But as we are using the Tkinter, there is a segment fault during the runtime. the code

import faulthandler
faulthandler.enable()

import tkinter
from tkinter.constants import *
tk = tkinter.Tk()
frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
frame.pack(fill=BOTH,expand=1)
label = tkinter.Label(frame, text="Hello, World")
label.pack(fill=X, expand=1)
button = tkinter.Button(frame,text="Exit",command=tk.destroy)
button.pack(side=BOTTOM)
tk.mainloop()

the stack trace

/tmp/python_interpreter_x86_64-unknown-linux-gnu ❯ ./bin/python3.9 tkinter_test.py                                                                                                                                                                                            
Fatal Python error: Segmentation fault

Current thread 0x00007fe29108ef40 (most recent call first):
  File "/tmp/python_interpreter_x86_64-unknown-linux-gnu/lib/python3.9/tkinter/__init__.py", line 2572 in __init__
  File "/tmp/python_interpreter_x86_64-unknown-linux-gnu/lib/python3.9/tkinter/__init__.py", line 3148 in __init__
  File "/tmp/python_interpreter_x86_64-unknown-linux-gnu/tkinter_test.py", line 9 in <module>
[1]    55139 segmentation fault (core dumped)  ./bin/python3.9 tkinter_test.py

according to other tickets, seems the python interpreter is already linked to the Tkinter.

Update

I was trying to use the debug version to know what happened in the core dump. but it is very strange that I am able to run this with python3.9d. it is very weird.

indygreg commented 1 year ago

Thanks for the report.

Can confirm this fails on the latest 20221107 distributions. The x86_64-unknown-linux-gnu distribution fails for me on the >>> label = tkinter.Label(frame, text="Hello, World") line:

>>> label = tkinter.Label(frame, text="Hello, World")
[xcb] Unknown sequence number while appending request
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python3: ../../src/xcb_io.c:157: append_pending_request: Assertion `!xcb_xlib_unknown_seq_number' failed.
Fatal Python error: Aborted

Current thread 0x00007f7f676b5c40 (most recent call first):
  File "/home/gps/src/python-build-standalone/dist/python/lib/python3.9/tkinter/__init__.py", line 2572 in __init__
  File "/home/gps/src/python-build-standalone/dist/python/lib/python3.9/tkinter/__init__.py", line 3148 in __init__
  File "<stdin>", line 1 in <module>
Aborted (core dumped)

This program works with other Python builds on my system. So something is amiss.

The xcb warnings point to a potential interaction with that library. I reckon we're missing a configure flag somewhere in the X11 libraries which results in something using a non-standard config. tk and/or CPython is probably making assumptions about some X library config that aren't true.

There's possibly an upstream bug or two to report in here somewhere. But I don't know what until root cause is understood.

indygreg commented 1 year ago

Here's an excerpt from libxcb's configure:

Package: libxcb 1.13.1

  Configuration
    XDM support.........: no
    sendmsg fd passing..: yes
    Build unit tests....: no
      with html results.: no
    XCB buffer size.....: 16384

  X11 extensions
    Composite...........: yes

  Package: libxcb 1.13.1

  Configuration
    XDM support.........: no
    sendmsg fd passing..: yes
    Build unit tests....: no
      with html results.: no
    XCB buffer size.....: 16384

  X11 extensions
    Composite...........: yes
Damage..............: yes
    Dpms................: yes
    Dri2................: yes
    Damage..............: yes
    Dpms................: yes
    Dri2................: yes
Dri3................: yes
    GenericEvent........: no
    Glx.................: yes
    Randr...............: yes
    Record..............: yes
    Render..............: yes
    Dri3................: yes
    GenericEvent........: no
    Glx.................: yes
    Randr...............: yes
    Record..............: yes
    Render..............: yes
Resource............: yes
    Screensaver.........: yes
    Resource............: yes
    Screensaver.........: yes
selinux.............: no
    Shape...............: yes
    Shm.................: yes
    Sync................: yes
    Xevie...............: no
    Xfixes..............: yes
    Xfree86-dri.........: yes
    selinux.............: no
    Shape...............: yes
    Shm.................: yes
    Sync................: yes
    Xevie...............: no
    Xfixes..............: yes
    Xfree86-dri.........: yes
xinerama............: yes
    xinput..............: yes
    xkb.................: yes
    xprint..............: no
    xtest...............: yes
    xinerama............: yes
    xinput..............: yes
    xkb.................: yes
    xprint..............: no
    xtest...............: yes
xv..................: yes
    xvmc................: yes

  Used CFLAGS:
    CPPFLAGS............: -fvisibility=hidden -fPIC
    CFLAGS..............: -fvisibility=hidden -fPIC

  Installation:
    Prefix..............: /tools/deps
    xv..................: yes
    xvmc................: yes

  Used CFLAGS:
    CPPFLAGS............: -fvisibility=hidden -fPIC
    CFLAGS..............: -fvisibility=hidden -fPIC

  Installation:
    Prefix..............: /tools/deps

I have no clue how to interpret any of it though.

(I wish all configure scripts gave you concise reports of important metadata like this!)

indygreg commented 1 year ago

And from libx11:

11 will be built with the following settings:
 Loadable i18n module support:            no
 Loadable xcursor library support:        yes
 Threading support:                       yes
 Use Threads safe API:                    yes
 Threads stubs in libX11:                 no
 XCMS:                                    yes
 Internationalization support:            yes
 XF86BigFont support:                     yes
 XKB support:                             yes
 XLOCALEDIR environment variable support: yes
 Compose table cache enabled:             yes
 Functional specs building enabled:       yes

X11 will be built with the following settings:
 Loadable i18n module support:            no
 Loadable xcursor library support:        yes
 Threading support:                       yes
 Use Threads safe API:                    yes
 Threads stubs in libX11:                 no
 XCMS:                                    yes
 Internationalization support:            yes
 XF86BigFont support:                     yes
 XKB support:                             yes
 XLOCALEDIR environment variable support: yes
 Compose table cache enabled:             yes
 Functional specs building enabled:       yes

Threads stubs in libX11 seems potentially relevant.

indygreg commented 1 year ago

OK. We compile tk with -DTCL_THREADS=1. And we see some code in tk calling XInitThreads() (it is the only caller of XInitThreads() I found outside libX11 source, so I think this is the only relevant caller).

However, that code in tk (unix/tkUnixEvent.c) is protected behind an #if 0 && defined(XKEYCODETOKEYSYM_IS_DEPRECATED) && defined(TCL_THREADS). That will never be true. So we never call XInitThreads().

I think the problem here is we build tcl/tk with support for threads? Is this somehow different from how the entire world builds tcl/tk?

Note that I enabled threads in commit 169bdadd6ed2de0d2940ba600c73af2709608aa9. But sadly didn't leave any context. (Very uncharacteristic of me!) Commits around it were part of enabling tcl/tk to build on macOS. I wonder if I enabled threads for a reason or just saw they weren't enabled and figured enabling threads was a good idea?

indygreg commented 1 year ago

Hmmm. /usr/lib/x86_64-linux-gnu/tclConfig.sh and /usr/lib/x86_64-linux-gnu/tkConfig.sh on my machine (Ubuntu 22.04) says we built with TCL_THREADS=1. I wonder why my machine's tk is working but this one isn't...

Edward-Knight commented 1 year ago

To add on to the debugging - I cannot reproduce when using xvfb in Docker or otherwise

dae commented 1 year ago

Could it perhaps be related to the change mentioned here? https://github.com/indygreg/python-build-standalone/issues/95#issuecomment-1127021925

jplumail commented 1 month ago

After a git bisect testing against OP code, I found that this commit is the first bad commit. I have no idea about how to fix this though !