otp icon indicating copy to clipboard operation
otp copied to clipboard

Debugger/Observer don't start

Open MichaelKrusemarkBosch opened this issue 2 months ago • 10 comments

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.

MichaelKrusemarkBosch avatar Oct 30 '25 11:10 MichaelKrusemarkBosch

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?

filmor avatar Nov 03 '25 09:11 filmor

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?

filmor avatar Nov 03 '25 10:11 filmor

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.

jhogberg avatar Nov 03 '25 10:11 jhogberg

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.

joelpelaez avatar Nov 04 '25 20:11 joelpelaez

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.

joelpelaez avatar Nov 04 '25 20:11 joelpelaez

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.

joelpelaez avatar Nov 05 '25 01:11 joelpelaez

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.

joelpelaez avatar Nov 05 '25 14:11 joelpelaez

I would appreciate the workaround in otp/erts/emulator/sys/unix/sys.c, The release latency of bubblewrap is quite high.

MichaelKrusemarkBosch avatar Nov 25 '25 13:11 MichaelKrusemarkBosch

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.

dgud avatar Nov 25 '25 15:11 dgud

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.

joelpelaez avatar Nov 25 '25 17:11 joelpelaez