Debugger/Observer don't start
Describe the bug Starting the debugger/observer with debugger:start()/observer:start() stalls. Interpreter must be quit with ^C.
To Reproduce see above on Archlinux with X11.
Expected behavior Debugger/Observer starts.
Affected versions Erlang 28.1
Additional context erlang-wx/erlang-debugger packages are installed.
We ran into this with Fedora 43. It happens with Erlang 26 as well, and also with Wayland. For us, running anything from the Ctrl-G menu (including continue) unblocks it.
Attaching the debugger, it seems something is blocked in the Glycin pixmap loading:
Thread 11 (Thread 0x7f141ebff6c0 (LWP 356008) "wxwidgets"):
#0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1 0x00007f14d85fabd5 in std::sys::pal::unix::futex::futex_wait (futex=0x7f14141ff0a0, expected=16, timeout=...) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/sys/pal/unix/futex.rs:72
#2 std::sys::sync::condvar::futex::Condvar::wait_optional_timeout (self=0x7f14141ff0a0, mutex=0x7f14141ff098, timeout=...) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/sys/sync/condvar/futex.rs:49
#3 std::sys::sync::condvar::futex::Condvar::wait (self=0x7f14141ff0a0, mutex=0x7f14141ff098) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/sys/sync/condvar/futex.rs:33
#4 std::sync::poison::condvar::Condvar::wait<()> (self=0x7f14141ff0a0, guard=...) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/sync/poison/condvar.rs:191
#5 parking::Inner::park (self=0x7f14141ff090, timeout=...) at src/lib.rs:377
#6 0x00007f14d85339b7 in parking::Parker::park (self=<optimized out>) at /usr/share/cargo/registry/parking-2.2.1/src/lib.rs:132
#7 async_io::driver::block_on::{closure#1}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, async_executor::{impl#11}::run::{async_fn_env#0}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}>> (cache=0x7f1414048fd8) at /usr/share/cargo/registry/async-io-2.6.0/src/driver.rs:290
#8 std::thread::local::LocalKey<core::cell::RefCell<(parking::Parker, core::task::wake::Waker, alloc::sync::Arc<core::sync::atomic::AtomicBool, alloc::alloc::Global>)>>::try_with<core::cell::RefCell<(parking::Parker, core::task::wake::Waker, alloc::sync::Arc<core::sync::atomic::AtomicBool, alloc::alloc::Global>)>, async_io::driver::block_on::{closure_env#1}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, async_executor::{impl#11}::run::{async_fn_env#0}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}>>, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (f=..., self=<optimized out>) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/thread/local.rs:315
#9 std::thread::local::LocalKey<core::cell::RefCell<(parking::Parker, core::task::wake::Waker, alloc::sync::Arc<core::sync::atomic::AtomicBool, alloc::alloc::Global>)>>::with<core::cell::RefCell<(parking::Parker, core::task::wake::Waker, alloc::sync::Arc<core::sync::atomic::AtomicBool, alloc::alloc::Global>)>, async_io::driver::block_on::{closure_env#1}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, async_executor::{impl#11}::run::{async_fn_env#0}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}>>, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (f=..., self=<optimized out>) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/thread/local.rs:279
#10 async_io::driver::block_on<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, async_executor::{impl#11}::run::{async_fn_env#0}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}>> (future=...) at /usr/share/cargo/registry/async-io-2.6.0/src/driver.rs:180
#11 async_global_executor::reactor::block_on::{closure#0}<async_executor::{impl#11}::run::{async_fn_env#0}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}>, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> () at /usr/share/cargo/registry/async-global-executor-3.1.0/src/reactor.rs:3
#12 async_global_executor::reactor::block_on<async_executor::{impl#11}::run::{async_fn_env#0}<core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>, glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}>, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (future=...) at /usr/share/cargo/registry/async-global-executor-3.1.0/src/reactor.rs:8
#13 async_global_executor::executor::block_on::{closure#0}<glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (executor=<optimized out>) at /usr/share/cargo/registry/async-global-executor-3.1.0/src/executor.rs:26
#14 std::thread::local::LocalKey<async_executor::LocalExecutor>::try_with<async_executor::LocalExecutor, async_global_executor::executor::block_on::{closure_env#0}<glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>>, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (f=..., self=<optimized out>) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/thread/local.rs:315
#15 std::thread::local::LocalKey<async_executor::LocalExecutor>::with<async_executor::LocalExecutor, async_global_executor::executor::block_on::{closure_env#0}<glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>>, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (f=..., self=<optimized out>) at /builddir/build/BUILD/rust-1.90.0-build/rustc-1.90.0-src/library/std/src/thread/local.rs:279
#16 async_global_executor::executor::block_on<glycin::gobject::loader::{impl#0}::load::{async_fn_env#0}, core::result::Result<glycin::gobject::image::GlyImage, glycin::error::ErrorCtx>> (future=...) at /usr/share/cargo/registry/async-global-executor-3.1.0/src/executor.rs:26
#17 glycin::loader::gly_loader_load (loader=0x7f1414282700, g_error=g_error@entry=0x7f141ebfe1e8) at libglycin/src/loader.rs:80
#18 0x00007f14dbd4c060 in load_pixbuf_with_glycin (file=file@entry=0x7f141404dd80, size_func=size_func@entry=0x0, user_data=user_data@entry=0x0, animation=animation@entry=0x0, error=error@entry=0x0) at ../gdk-pixbuf/io-glycin-utils.c:433
#19 0x00007f14dbd4c4ac in gdk_pixbuf__glycin_image_load (f=<optimized out>, error=0x0) at ../gdk-pixbuf/io-glycin-utils.c:595
#20 0x00007f14dbd3b781 in gdk_pixbuf_new_from_file (filename=0x7f14141ee9c0 "/usr/lib64/erlang/lib/observer-2.15.1/priv/erlang_observer.png", error=0x0) at ../gdk-pixbuf/gdk-pixbuf-io.c:1235
#21 0x00007f14da6b5838 in wxBitmap::LoadFile (this=this@entry=0x7f1414029a40, name=..., type=wxBITMAP_TYPE_PNG) at ../include/wx/buffer.h:181
#22 0x00007f14da6b5a86 in wxBitmap::wxBitmap (this=0x7f1414029a40, filename=<optimized out>, type=<optimized out>, this=<optimized out>, filename=<optimized out>, type=<optimized out>) at ../src/gtk/bitmap.cpp:418
#23 0x00007f14db0f52ae in wxIcon::wxIcon (this=<optimized out>, filename=<optimized out>, type=<optimized out>) at /usr/include/wx-3.2/wx/generic/icon.h:29
#24 EwxIcon::EwxIcon (this=<optimized out>, name=<optimized out>, type=<optimized out>, desiredWidth=<optimized out>, desiredHeight=<optimized out>) at gen/wxe_derived_dest.h:186
#25 wxIcon_new_2 (app=0x7f1414000c20, memenv=0x7f14c002e260, Ecmd=...) at gen/wxe_wrapper_4.cpp:883
#26 0x00007f14db2b5062 in WxeApp::wxe_dispatch (this=<optimized out>, event=...) at /usr/src/debug/erlang-26.2.5.15-1.fc43.x86_64/lib/wx/c_src/wxe_impl.cpp:535
#27 0x00007f14db2b7035 in WxeApp::dispatch (this=this@entry=0x7f1414000c20, batch=0x7f14141d97a0) at /usr/src/debug/erlang-26.2.5.15-1.fc43.x86_64/lib/wx/c_src/wxe_impl.cpp:409
#28 0x00007f14db2b9979 in WxeApp::dispatch_cmds (this=0x7f1414000c20) at /usr/src/debug/erlang-26.2.5.15-1.fc43.x86_64/lib/wx/c_src/wxe_impl.cpp:338
#29 WxeApp::dispatch_cmds (this=0x7f1414000c20) at /usr/src/debug/erlang-26.2.5.15-1.fc43.x86_64/lib/wx/c_src/wxe_impl.cpp:331
#30 0x00007f14db2b9a51 in WxeApp::idle (this=<optimized out>, event=...) at /usr/src/debug/erlang-26.2.5.15-1.fc43.x86_64/lib/wx/c_src/wxe_impl.cpp:294
#31 0x00007f14da35a981 in wxEvtHandler::ProcessEventIfMatchesId (entry=..., handler=<optimized out>, event=...) at ../src/common/event.cpp:1482
#32 0x00007f14da35ccc8 in wxEvtHandler::SearchDynamicEventTable (this=this@entry=0x7f1414000c20, event=...) at ../src/common/event.cpp:1952
#33 0x00007f14da35d01d in wxEvtHandler::TryHereOnly (this=this@entry=0x7f1414000c20, event=...) at ../src/common/event.cpp:1675
#34 0x00007f14da35d0cf in wxEvtHandler::TryBeforeAndHere (this=0x7f1414000c20, event=...) at ../include/wx/event.h:4013
#35 wxEvtHandler::ProcessEventLocally (this=0x7f1414000c20, event=...) at ../src/common/event.cpp:1612
#36 0x00007f14da35d1f9 in wxEvtHandler::ProcessEvent (this=0x7f1414000c20, event=...) at ../src/common/event.cpp:1585
#37 0x00007f14da35c5b3 in wxEvtHandler::SafelyProcessEvent (this=<optimized out>, event=<optimized out>) at ../src/common/event.cpp:1701
#38 0x00007f14da2371c6 in wxAppConsoleBase::ProcessIdle (this=0x7f1414000c20) at ../src/common/appbase.cpp:452
#39 0x00007f14da799069 in wxAppBase::ProcessIdle (this=<optimized out>) at ../src/common/appcmn.cpp:396
#40 0x00007f14da6b1f03 in wxApp::DoIdle (this=0x7f1414000c20) at ../src/gtk/app.cpp:150
#41 0x00007f14da6b1fe7 in wxapp_idle_callback () at ../src/gtk/app.cpp:101
#42 0x00007f14da4f19cd in g_idle_dispatch (source=0x7f14c01aa2b0, callback=0x7f14da6b1fd0 <wxapp_idle_callback(gpointer)>, user_data=0x0) at ../glib/gmain.c:6466
#43 0x00007f14da4eb263 in g_main_dispatch (context=0x7f1414015b50) at ../glib/gmain.c:3565
#44 g_main_context_dispatch_unlocked (context=0x7f1414015b50) at ../glib/gmain.c:4425
#45 0x00007f14da4f41b8 in g_main_context_iterate_unlocked (context=0x7f1414015b50, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4490
#46 0x00007f14da4f445f in g_main_loop_run (loop=0x7f14141253e0) at ../glib/gmain.c:4695
#47 0x00007f14d9b85da5 in gtk_main () at ../gtk/gtkmain.c:1332
#48 0x00007f14da6c6755 in wxGUIEventLoop::DoRun (this=0x7f14141255a0) at ../src/gtk/evtloop.cpp:61
#49 0x00007f14da2621ea in wxEventLoopBase::Run (this=0x7f14141255a0) at ../src/common/evtloopcmn.cpp:87
#50 0x00007f14da23aff5 in wxAppConsoleBase::MainLoop (this=0x7f1414000c20) at ../src/common/appbase.cpp:395
#51 0x00007f14da2a0980 in wxEntry (argc=@0x7f141ebfeaf4: 1, argv=argv@entry=0x7f141ebfeb20) at ../src/common/init.cpp:497
#52 0x00007f14db2b8738 in wxe_main_loop (_unused=<optimized out>) at /usr/src/debug/erlang-26.2.5.15-1.fc43.x86_64/lib/wx/c_src/wxe_main.cpp:138
#53 0x0000562ae9a6b319 in thr_wrapper (vtwd=0x7f14e13a48f0) at ../lib_src/pthread/ethread.c:116
#54 0x00007f1535e7e464 in start_thread (arg=<optimized out>) at pthread_create.c:448
#55 0x00007f1535f015ac in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Is there anything in Erlang or the wx driver that could lead to the background threads not running?
I'm pretty certain this is a problem with glycin (the new sandboxed image loading of gtk). Running with G_MESSAGES_DEBUG=all as suggested in similar issues on the glycin issue tracker (https://gitlab.gnome.org/GNOME/glycin/-/issues/237) gives this log last before the halting:
DEBUG glycin::sandbox: Testing bwrap availability with: "bwrap" "--unshare-all" "--die-with-parent" "--chdir" "/" "--ro-bind" "/usr" "/usr" "--dev" "/dev" "--ro-bind-try" "/etc/ld.so.cache" "/etc/ld.so.cache" "--ro-bind-try" "/nix/store" "/nix/store" "--tmpfs" "/tmp-home" "--tmpfs" "/tmp-run" "--clearenv" "--setenv" "HOME" "/tmp-home" "--setenv" "XDG_RUNTIME_DIR" "/tmp-run" "--setenv" "XDG_RUNTIME_DIR" "/run/user/694634552" "--symlink" "/usr/lib64" "/lib64" "--symlink" "/usr/lib" "/lib" "--seccomp" "36" "/usr/bin/true"
and then immediately after unblocking it (by going into the Ctrl-C menu and continuing) it logs
2025-11-03T09:56:53.774586Z INFO glycin::sandbox: Can't determine if bwrap syscalls are blocked: IO error: No child processes (os error 10) (StdIoError { err: Os { code: 10, kind: Uncategorized, message: "No child processes" }, info: "" })
before continuing to load.
This is the relevant section: https://gitlab.gnome.org/GNOME/glycin/-/blob/main/glycin/src/sandbox.rs#L705-709
What kind of RLIMIT settings are enforced by the BEAM?
What kind of RLIMIT settings are enforced by the BEAM?
None.
Is there anything in Erlang or the wx driver that could lead to the background threads not running?
No, not that I can think of.
Yes, I can confirm this also in Fedora 43.
Erlang 28.1.1 compiled with kerl asdf plugin with these conifgure options (two separate builds):
- default
-
--enable-debug --enable-dirty-schedulers
Setting environment variable G_MESSAGES_DEBUG=all prints this message:
2025-11-04T19:49:53.454335Z DEBUG glycin::sandbox: Testing bwrap availability with: "bwrap" "--unshare-all" "--die-with-parent" "--chdir" "/" "--ro-bind" "/usr" "/usr" "--dev" "/dev" "--ro-bind-try" "/etc/ld.so.cache" "/etc/ld.so.cache" "--ro-bind-try" "/nix/store" "/nix/store" "--tmpfs" "/tmp-home" "--tmpfs" "/tmp-run" "--clearenv" "--setenv" "HOME" "/tmp-home" "--setenv" "XDG_RUNTIME_DIR" "/tmp-run" "--setenv" "XDG_RUNTIME_DIR" "/run/user/1000" "--symlink" "/usr/lib" "/lib" "--symlink" "/usr/lib64" "/lib64" "--seccomp" "35" "/usr/bin/true"
I tried to execute the command on a normal terminal without the --seccomp 35 part and this worked.
Also I execute prlimit on the erl process and the bwrap process and I get this output:
prlimit -p erl pid:
RESOURCE DESCRIPTION SOFT HARD UNITS
AS address space limit unlimited unlimited bytes
CORE max core file size unlimited unlimited bytes
CPU CPU time unlimited unlimited seconds
DATA max data size unlimited unlimited bytes
FSIZE max file size unlimited unlimited bytes
LOCKS max number of file locks held unlimited unlimited locks
MEMLOCK max locked-in-memory address space 8388608 8388608 bytes
MSGQUEUE max bytes in POSIX mqueues 819200 819200 bytes
NICE max nice prio allowed to raise 0 0
NOFILE max number of open files 1024 524288 files
NPROC max number of processes 60421 60421 processes
RSS max resident set size unlimited unlimited bytes
RTPRIO max real-time priority 0 0
RTTIME timeout for real-time tasks unlimited unlimited microsecs
SIGPENDING max number of pending signals 60421 60421 signals
STACK max stack size 8388608 unlimited bytes
prlimit -p bwrap pid
ESOURCE DESCRIPTION SOFT HARD UNITS
AS address space limit 14451946291 14451946291 bytes
CORE max core file size unlimited unlimited bytes
CPU CPU time unlimited unlimited seconds
DATA max data size unlimited unlimited bytes
FSIZE max file size unlimited unlimited bytes
LOCKS max number of file locks held unlimited unlimited locks
MEMLOCK max locked-in-memory address space 8388608 8388608 bytes
MSGQUEUE max bytes in POSIX mqueues 819200 819200 bytes
NICE max nice prio allowed to raise 0 0
NOFILE max number of open files 1024 524288 files
NPROC max number of processes 60421 60421 processes
RSS max resident set size unlimited unlimited bytes
RTPRIO max real-time priority 0 0
RTTIME timeout for real-time tasks unlimited unlimited microsecs
SIGPENDING max number of pending signals 60421 60421 signals
STACK max stack size 8388608 unlimited bytes
For reference, prlimit from normal shell:
ESOURCE DESCRIPTION SOFT HARD UNITS
AS address space limit unlimited unlimited bytes
CORE max core file size unlimited unlimited bytes
CPU CPU time unlimited unlimited seconds
DATA max data size unlimited unlimited bytes
FSIZE max file size unlimited unlimited bytes
LOCKS max number of file locks held unlimited unlimited locks
MEMLOCK max locked-in-memory address space 8388608 8388608 bytes
MSGQUEUE max bytes in POSIX mqueues 819200 819200 bytes
NICE max nice prio allowed to raise 0 0
NOFILE max number of open files 1024 524288 files
NPROC max number of processes 60421 60421 processes
RSS max resident set size unlimited unlimited bytes
RTPRIO max real-time priority 0 0
RTTIME timeout for real-time tasks unlimited unlimited microsecs
SIGPENDING max number of pending signals 60421 60421 signals
STACK max stack size 8388608 unlimited bytes
Workaround
If the bwrap /usr/bin/true process is killed, the observer:start(). completes and shows the window.
Note
wx:demo(). works fine without any modifications.
Errata
wx:demo(). works well until open the menu, it triggers icons loading and freezes the process.
Also this is printing some issues with bwrap on glycin-svg
2025-11-04T20:41:56.395487Z DEBUG glycin::dbus: Spawning loader/editor:
"bwrap" "--unshare-all" "--die-with-parent" "--chdir" "/" "--ro-bind" "/usr" "/usr" "--dev" "/dev" "--ro-bind-try" "/etc/ld.so.cache" "/etc/ld.so.cache" "--ro-bind-try" "/nix/store" "/nix/store" "--tmpfs" "/tmp-home" "--tmpfs" "/tmp-run" "--clearenv" "--setenv" "HOME" "/tmp-home" "--setenv" "XDG_RUNTIME_DIR" "/tmp-run" "--setenv" "XDG_RUNTIME_DIR" "/run/user/1000" "--symlink" "/usr/lib" "/lib" "--symlink" "/usr/lib64" "/lib64" "--ro-bind-try" "/etc/fonts/conf.d" "/etc/fonts/conf.d" "--ro-bind-try" "/etc/fonts/fonts.conf" "/etc/fonts/fonts.conf" "--ro-bind-try" "/home/user/.cache/fontconfig" "/home/user/.cache/fontconfig" "--ro-bind-try" "/home/user/.local/share/fonts" "/home/user/.local/share/fonts" "--ro-bind-try" "/usr/lib/fontconfig/cache" "/usr/lib/fontconfig/cache" "--bind-try" "/home/user/.cache/glycin/usr/libexec/glycin-loaders/2+/glycin-svg" "/home/user/.cache/glycin/usr/libexec/glycin-loaders/2+/glycin-svg" "--setenv" "XDG_CACHE_HOME" "/home/user/.cache/glycin/usr/libexec/glycin-loaders/2+/glycin-svg" "--seccomp" "37" "/usr/libexec/glycin-loaders/2+/glycin-svg" "--dbus-fd" "36"
2025-11-04T20:41:56.405112Z DEBUG glycin::dbus: Loader stderr: Setting process memory limit
2025-11-04T20:41:56.424788Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:56.426040Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 1.216124ms
2025-11-04T20:41:56.427048Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:56.428100Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:56.428936Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 820.415µs
2025-11-04T20:41:56.429748Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:56.430832Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:56.431799Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 954.086µs
2025-11-04T20:41:56.434905Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:56.435872Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:56.436823Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 920.235µs
2025-11-04T20:41:56.437593Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:56.438525Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:56.439306Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 764.077µs
2025-11-04T20:41:56.440044Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:56.441071Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:56.441908Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 810.755µs
2025-11-04T20:41:57.760120Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:57.763338Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:57.764932Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 1.558714ms
2025-11-04T20:41:57.766703Z DEBUG glycin::pool: Using existing loader from pool.
2025-11-04T20:41:57.767843Z DEBUG glycin_utils::editing::change_memory_format: Starting to transform image format from B8g8r8a8Premultiplied to R8g8b8a8
2025-11-04T20:41:57.768629Z DEBUG glycin_utils::editing::change_memory_format: Transformation completed after 766.507µs
15:41:58: Debug: window wxMenuBar@0x7f44a820b010 ("menubar") lost focus even though it didn't have it
2025-11-04T20:42:27.769276Z DEBUG glycin::pool: Cleaning up loaders
2025-11-04T20:42:27.769321Z DEBUG glycin::pool: Loader "/usr/libexec/glycin-loaders/2+/glycin-svg": drop true users 0 (max 18446744073709551615), idle 30.000524276s (max 30s)
2025-11-04T20:42:27.769331Z DEBUG glycin::pool: Dropping loader "/usr/libexec/glycin-loaders/2+/glycin-svg" 1
2025-11-04T20:42:27.769337Z DEBUG glycin::dbus: Winding down process
2025-11-04T20:42:27.769362Z DEBUG glycin::dbus: Killing process due to cancellation (late): "bwrap" "--unshare-all" "--die-with-parent" "--chdir" "/" "--ro-bind" "/usr" "/usr" "--dev" "/dev" "--ro-bind-try" "/etc/ld.so.cache" "/etc/ld.so.cache" "--ro-bind-try" "/nix/store" "/nix/store" "--tmpfs" "/tmp-home" "--tmpfs" "/tmp-run" "--clearenv" "--setenv" "HOME" "/tmp-home" "--setenv" "XDG_RUNTIME_DIR" "/tmp-run" "--setenv" "XDG_RUNTIME_DIR" "/run/user/1000" "--symlink" "/usr/lib" "/lib" "--symlink" "/usr/lib64" "/lib64" "--ro-bind-try" "/etc/fonts/conf.d" "/etc/fonts/conf.d" "--ro-bind-try" "/etc/fonts/fonts.conf" "/etc/fonts/fonts.conf" "--ro-bind-try" "/home/user/.cache/fontconfig" "/home/user/.cache/fontconfig" "--ro-bind-try" "/home/user/.local/share/fonts" "/home/user/.local/share/fonts" "--ro-bind-try" "/usr/lib/fontconfig/cache" "/usr/lib/fontconfig/cache" "--bind-try" "/home/user/.cache/glycin/usr/libexec/glycin-loaders/2+/glycin-svg" "/home/user/.cache/glycin/usr/libexec/glycin-loaders/2+/glycin-svg" "--setenv" "XDG_CACHE_HOME" "/home/user/.cache/glycin/usr/libexec/glycin-loaders/2+/glycin-svg" "--seccomp" "37" "/usr/libexec/glycin-loaders/2+/glycin-svg" "--dbus-fd" "36"
2025-11-04T20:42:27.769888Z DEBUG glycin::dbus: Process exited: None Err(Os { code: 10, kind: Uncategorized, message: "No child processes" })
2025-11-04T20:42:27.769925Z DEBUG glycin::dbus: Failed to send process return value to coordinating thread: Err(Os { code: 10, kind: Uncategorized, message: "No child processes" })
2025-11-04T20:42:27.771879Z DEBUG glycin::dbus: stderr disconnected without error
2025-11-04T20:42:27.771913Z DEBUG glycin::dbus: stdout disconnected without error
Is it possible create a mininal reproducible test with Erlang? I tested a minimal C++ example and it calls bwrap successfully.
I found information about this issue:
https://github.com/containers/bubblewrap/issues/705
I checked Erlang 28.0.1 (asdf build) and Erlang 26.2.5.15 (in Fedora repos) and last signal setting for SIGCHLD is SIG_IGN. It causes than signalfd not works well and freezes the wx thread.
This is a minimal reproduction of this issue in C++:
#include <wx/wx.h>
#include <signal.h> // Required for signal()
// Define a unique ID for the menu item
enum
{
ID_Quit = 1
};
// Custom Frame class
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
private:
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
// Event table to route events to the correct functions
wxDECLARE_EVENT_TABLE();
};
// Event table implementation
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
wxEND_EVENT_TABLE()
// MyFrame constructor
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
// This triggers the `bwrap` issue
signal(SIGCHLD, SIG_IGN);
// Create a menu bar
wxMenuBar* menuBar = new wxMenuBar();
// Create a "File" menu
wxMenu* fileMenu = new wxMenu();
fileMenu->Append(ID_Quit, "&Exit\tAlt-F4", "Quit this program"); // Add an Exit item
// Create a "Help" menu
wxMenu* helpMenu = new wxMenu();
helpMenu->Append(wxID_ABOUT, "&About\tF1", "Show info about this program");
// Append menus to the menu bar
menuBar->Append(fileMenu, "&File");
menuBar->Append(helpMenu, "&Help");
// Set the menu bar for the frame
SetMenuBar(menuBar);
// Create a status bar
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
}
void MyFrame::OnQuit(wxCommandEvent& event)
{
Close(true); // Close the frame
}
void MyFrame::OnAbout(wxCommandEvent& event)
{
wxMessageBox("This is a wxWidgets Menu Example",
"About Menu Example", wxOK | wxICON_INFORMATION);
}
// Custom App class
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
// Implement the App class's OnInit function
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame("Menu Example", wxPoint(50, 50), wxSize(450, 340));
frame->Show(true);
return true;
}
// Macro to implement the application entry point
wxIMPLEMENT_APP(MyApp);
compile with g++ example.cpp $(wx-config --libs) $(wx-config --cflags) -o MenuExample
The "fix" could require remove or change this line. https://github.com/erlang/otp/blob/bc3132beee5483db4a83a39d9987bb9efe2429ac/erts/emulator/sys/unix/sys.c#L822
But also it could be fixed in bwrap, setting SIGCHLD to SIG_DFL before to call poll.
I did a PR to bwrap project with a possible fix.
https://github.com/containers/bubblewrap/pull/711
I tested it copying the bwrap binary to /home/user/bin directory and observer:start(). works again.
I would appreciate the workaround in otp/erts/emulator/sys/unix/sys.c, The release latency of bubblewrap is quite high.
Maybe report upstream to Fedora that they can't use libraries that assumes how signal are handled in the program that loads them.
I don't know how we can fix that, we have that there for a reason.
This issue with bubblewrap is mencioned in https://bugzilla.redhat.com/show_bug.cgi?id=2413966, but it doesn't have a proper issue report.
In the PR, the reviewer requested a modification but I haven't received a reply. Also in the same PR has other related issues linked.
@dgud the reviewer made a contrary assumption in this comment https://github.com/containers/bubblewrap/pull/711#issuecomment-3518910086 . I know that namespaces/containers are a sensitive topic for security and isolation, but I don't think that reset a signal can cause a harm.
@MichaelKrusemarkBosch you can compile the bubblewrap PR branch and copy the bwrap binary to a directory as /usr/local/bin and it make observer:start(). working this again.