Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segment fault when packed with pyinstaller on linux #1049

Closed
zhengxyz123 opened this issue Feb 15, 2024 · 9 comments
Closed

Segment fault when packed with pyinstaller on linux #1049

zhengxyz123 opened this issue Feb 15, 2024 · 9 comments

Comments

@zhengxyz123
Copy link
Contributor

Take this simple program as an example:

# test.py
from pyglet import app, clock, window

win = window.Window(400, 300, "test")

@win.event
def on_activate():
    print("event: on_activate")

@win.event
def on_deactivate():
    print("event: on_deactivate")

@win.event
def on_expose():
    print("event: on_expose")

@win.event
def on_draw():
    win.clear()

if __name__ == "__main__":
    clock.schedule_interval(win.draw, 1 / 60)
    app.run()

Then run:

pyinstaller -F test.py

Then I run python test.py and test(generated by pyinstaller) and apply following action twice:

  1. Open the window
  2. Minimize the window
  3. Show the window

They have different behaviors:

$ python test.py 
event: on_expose
event: on_expose
event: on_activate
event: on_expose
event: on_deactivate
event: on_expose
event: on_activate
$ ./dist/test 
event: on_expose
event: on_expose
event: on_activate
event: on_expose
event: on_deactivate
[segment fault occurred after deactivate the window]

The following information may be useful:

           PID: 40211 (test)
           UID: 1000 (jason)
           GID: 1000 (jason)
        Signal: 11 (SEGV)
     Timestamp: Thu 2024-02-15 20:22:25 CST (1min 23s ago)
  Command Line: ./dist/test
    Executable: /home/jason/Desktop/mystery/dist/test
 Control Group: /user.slice/user-1000.slice/user@1000.service/app.slice/app-codium-f871a7386bc04ed0912f3571bb3c89d4.scope
          Unit: user@1000.service
     User Unit: app-codium-f871a7386bc04ed0912f3571bb3c89d4.scope
         Slice: user-1000.slice
     Owner UID: 1000 (jason)
       Boot ID: c5b33364fbd648119cd60c079d88ed29
    Machine ID: 52078f282d23400cb95de4b0fdd5f887
      Hostname: mydebian
       Storage: /var/lib/systemd/coredump/core.test.1000.c5b33364fbd648119cd60c079d88ed29.40211.1707999745000000.zst (present)
  Size on Disk: 50.6K
       Message: Process 40211 (test) of user 1000 dumped core.
                
                Stack trace of thread 40211:
                #0  0x00007f43e5fd1e2c __pthread_kill_implementation (libc.so.6 + 0x8ae2c)
                #1  0x00007f43e5f82fb2 __GI_raise (libc.so.6 + 0x3bfb2)
                #2  0x0000000000404204 n/a (/home/jason/Desktop/mystery/dist/test + 0x4204)
                ELF object binary architecture: AMD x86-64

and output from dmesg:

[353795.150103] test[40212]: segfault at 8 ip 00007f27a5840620 sp 00007ffcd6e79968 error 4 in libX11.so.6.4.0[7f27a580b000+8b000] likely on CPU 3 (core 3, socket 0)
[353795.150158] Code: 16 b5 fc ff 66 0f 1f 44 00 00 48 85 ff 74 13 48 83 7f 08 00 74 0c 48 8b 07 ff 60 08 66 0f 1f 44 00 00 c3 0f 1f 80 00 00 00 00 <48> 83 7f 08 00 74 09 48 8b 07 ff 60 10 0f 1f 00 c3 66 66 2e 0f 1f

and from pyglet.info.

This issue was found both on KDE(Wayland) and KED(X11).

@benmoran56
Copy link
Member

I saw this as well on the latest PyInstaller. It might be a bug introduced in some recent version.

@zhengxyz123
Copy link
Contributor Author

I did a rough skim of pyinstaller's issues and didn't find a similar problem.

The error seems to occur in the underlying shared libraries, does that mean there is no solution with python?

@benmoran56
Copy link
Member

Nuitka does not crash. Pyinstaller also did not crash in the past. Unfortunately, older PyInstaller does not support the latest Python versions, but it's worth to test previous versions.

@zhengxyz123
Copy link
Contributor Author

I found that pyinstaller==5.13.0 won't crash.

@benmoran56
Copy link
Member

That's good information.
I see in the v5.13 release notes, there is a message about "breaking changes in v6". https://github.com/pyinstaller/pyinstaller/releases/tag/v5.13.0
However, none of these changes should cause any pyglet issues. It's probably a new bug that was introduced since then.

Unfortunately v5.13 doesn't support Python 3.12, but it's good for a temporary solution.

@zhengxyz123
Copy link
Contributor Author

So, you think this is a bug in the new version of pyinstaller. Then creating a new issue is a good option.

@rokm
Copy link

rokm commented Feb 17, 2024

This looks like combination of regression in PyInstaller 6.x, and a bug in pyglet.

The PyInstaller-side of the problem is that with PyInstaller 6.x, locale.getlocale() in frozen application incorrectly returns (None, None), in contrast to unfrozen python and PyInstaller 5.x.

On pyglet side, this means that _have_utf8 is False:

_have_utf8 = locale.getlocale()[1] == 'UTF-8'

which results in self._x_ic initialization being skipped here:

if _have_utf8 and not self._x_ic:
if not self.display._x_im:
xlib.XSetLocaleModifiers(asbytes('@im=none'))
self.display._x_im = xlib.XOpenIM(self._x_display, None, None, None)
xlib.XFlush(self._x_display)
# Need to set argtypes on this function because its vararg,
# and ctypes guesses wrong.
xlib.XCreateIC.argtypes = [xlib.XIM,
c_char_p, c_int,
c_char_p, xlib.Window,
c_char_p, xlib.Window,
c_void_p]
self._x_ic = xlib.XCreateIC(self.display._x_im,
asbytes('inputStyle'),
xlib.XIMPreeditNothing | xlib.XIMStatusNothing,
asbytes('clientWindow'), self._window,
asbytes('focusWindow'), self._window,
None)

and consequently XUnsetICFocus being called with NULL pointer here

xlib.XUnsetICFocus(self._x_ic)

causing the segfault.

So this can be triggered with unfrozen python as well, for example trying to run the sample program from original report with non-UTF8 locale set, e.g., LANG=sl_SI.ISO8859-2.

@benmoran56
Copy link
Member

Thanks for taking the time to look into this. The non-utf fallback should be easy enough to fix on the pyglet side.

@zhengxyz123
Copy link
Contributor Author

By using pyinstaller==6.5.0, this issue was solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants