I've hit a reproducible crash in pyg_sbtcvm.py on a fresh Linux Mint 22.3 install (also reproducible on bare metal and inside a VirtualBox guest). I've narrowed it down enough that I think it's worth reporting in case other modern-Linux users hit the same thing.
Environment:
OS: Linux Mint 22.3 Cinnamon (kernel 6.14.0-37-generic)
Python: 3.12.3
pygame: 2.5.2
SDL: 2.30.0
Mesa: 25.2.8 (OpenGL 4.5)
Symptom:
Running any pygame-frontend ROM (tested with maze and ternarydreams) opens the SBTCVM window briefly, then crashes with:
Exception in thread Thread-2 (statup):
Traceback (most recent call last):
File "/usr/lib/python3.12/threading.py", line 1073, in _bootstrap_inner
self.run()
File "/usr/lib/python3.12/threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File ".../vmsystem/UIO_PYGAME_G2x_9.py", line 177, in statup
self.render_dumbtty()
File ".../vmsystem/UIO_PYGAME_G2x_9.py", line 500, in render_dumbtty
pygame.display.flip()
pygame.error: Could not make GL context current: BadAccess (attempt to access private resource denied)
Diagnosis:
The traceback shows pygame.display.flip() being called from Thread-2 rather than the main thread. SDL2 requires display operations (including flip()) to happen on the same thread that created the display surface — the GL context is bound to the creating thread, and other threads cannot legally use it.
Older pygame/SDL2 versions were more forgiving of this and would silently work. Newer versions enforce the rule strictly, which is why this is surfacing now on modern distributions.
Confirmation that pygame itself is fine:
A minimal single-threaded test runs cleanly in the same environment:
pythonpython3 -c "
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
screen.fill((255, 0, 0))
pygame.display.flip()
import time; time.sleep(2)
pygame.quit()
"
(Red window appears for 2 seconds, no errors.)
So the issue is specifically that SBTCVM's TTY render path is being called from a worker thread that doesn't own the display.
Suggested fix direction (not a patch):
Display operations in render_dumbtty() (and probably elsewhere) need to be marshalled to the main thread — either by moving the rendering loop entirely to the main thread, or by having worker threads post draw requests to a queue that the main thread services.
I'm happy to test any patches you'd like to try.
I've hit a reproducible crash in pyg_sbtcvm.py on a fresh Linux Mint 22.3 install (also reproducible on bare metal and inside a VirtualBox guest). I've narrowed it down enough that I think it's worth reporting in case other modern-Linux users hit the same thing.
Environment:
OS: Linux Mint 22.3 Cinnamon (kernel 6.14.0-37-generic)
Python: 3.12.3
pygame: 2.5.2
SDL: 2.30.0
Mesa: 25.2.8 (OpenGL 4.5)
Symptom:
Running any pygame-frontend ROM (tested with maze and ternarydreams) opens the SBTCVM window briefly, then crashes with:
Exception in thread Thread-2 (statup):
Traceback (most recent call last):
File "/usr/lib/python3.12/threading.py", line 1073, in _bootstrap_inner
self.run()
File "/usr/lib/python3.12/threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File ".../vmsystem/UIO_PYGAME_G2x_9.py", line 177, in statup
self.render_dumbtty()
File ".../vmsystem/UIO_PYGAME_G2x_9.py", line 500, in render_dumbtty
pygame.display.flip()
pygame.error: Could not make GL context current: BadAccess (attempt to access private resource denied)
Diagnosis:
The traceback shows pygame.display.flip() being called from Thread-2 rather than the main thread. SDL2 requires display operations (including flip()) to happen on the same thread that created the display surface — the GL context is bound to the creating thread, and other threads cannot legally use it.
Older pygame/SDL2 versions were more forgiving of this and would silently work. Newer versions enforce the rule strictly, which is why this is surfacing now on modern distributions.
Confirmation that pygame itself is fine:
A minimal single-threaded test runs cleanly in the same environment:
pythonpython3 -c "
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
screen.fill((255, 0, 0))
pygame.display.flip()
import time; time.sleep(2)
pygame.quit()
"
(Red window appears for 2 seconds, no errors.)
So the issue is specifically that SBTCVM's TTY render path is being called from a worker thread that doesn't own the display.
Suggested fix direction (not a patch):
Display operations in render_dumbtty() (and probably elsewhere) need to be marshalled to the main thread — either by moving the rendering loop entirely to the main thread, or by having worker threads post draw requests to a queue that the main thread services.
I'm happy to test any patches you'd like to try.