Linux: "Qoder Remote Control Sync" helper SIGSEGVs during history sync after a turn with images

Environment

  • Qoder Desktop 0.4.8 (stable), Linux x86_64
  • Arch Linux / Omarchy 2026.9.7, kernel 7.2.8-9-omarchy, Wayland (Hyprland)
  • Remote Control: enabled (Settings → Mobile)
  • Chat session contains image attachments / tool-result images
  • Bundled: @img/sharp 0.34.5, @img/sharp-libvips-linux-x64 1.2.4 (libvips 8.17.3)
  • System GLib/libgobject 2.90.0
  • Helper process: Qoder Remote Control Sync, node.mojom.NodeService, --max-old-space-size=512

Summary

Completing an assistant turn in a chat that contains images starts the Remote Control history sync. 9–17 ms after the sync logs REMOTE_CONTROL_IMAGE_INVALID (stage resources), the Qoder Remote Control Sync utility process dies with SIGSEGV (exit code 139). The main process survives and respawns the helper, which retries — in one episode this produced 6 crashes in 24 seconds. I collected 11 coredumps over 4 episodes; every core has the same stack.

Steps to reproduce

  1. Enable Remote Control (Settings → Mobile).
  2. Open a chat session that contains image attachments.
  3. Complete an assistant turn (this triggers the history sync; in my case it was a long final report).
  4. Watch main.log: REMOTE_CONTROL_IMAGE_INVALID is followed 9–17 ms later by the helper crash.

Reproduced 4/4 episodes, 11 cores. reason:"killed", exitCode:15 entries in the log are normal helper shutdowns; the crashes are the exitCode:139 entries.

Expected

The sync either completes, or skips the offending image and continues. The helper process stays alive.

Actual

SIGSEGV in a libuv worker thread inside the bundled sharp/libvips addon. The helper exits with 139, gets respawned, and the retry loop can crash repeatedly. The main window stays responsive; no data was lost and there was no OOM pressure.

Log evidence (timestamps UTC; main.1.log)

[2026-10-18T18:29:55.586Z] [WARN] [main] [QoderRemoteControl] Remote Control 操作未完成 {"sessionId":"<redacted>","stage":"resources","failureCode":"REMOTE_CONTROL_IMAGE_INVALID"}
[2026-10-18T18:29:55.595Z] [ERROR] [main] [App] Electron child process exited {"type":"Utility","reason":"crashed","exitCode":139,"serviceName":"node.mojom.NodeService","name":"Qoder Remote Control Sync"}

Core dump stack (gdb, all 11 cores identical)

SIGSEGV, SEGV_MAPERR, PC = 0x0, thread = libuv-worker

#0  0x0000000000000000              (call through null)
#1  g_object_unref                  (system libgobject-2.0.so.0, GLib 2.90.0)
#2  sharp-linux-x64.node + 0x1835d
#3  sharp-linux-x64.node + 0x2000c
#4  sharp-linux-x64.node + 0x16eac
    ... node::ThreadPoolWork / libuv-worker

Analysis

Verified from the core and the shipped binaries:

  • The crashing path is the image-handling (“resources”) stage of the Remote Control sync, on its error path.
  • sharp-linux-x64.node has no NEEDED entry for libgobject but references g_object_unref as an undefined symbol, so it binds at runtime to the system libgobject that Electron loads.
  • The bundled libvips-cpp.so.8.17.3 statically embeds GLib: it defines and exports its own g_object_unref, g_object_ref, g_malloc, etc. (1788 g_* symbols), and has no NEEDED entry for libglib/libgobject.

Inference: two independent GLib implementations coexist in the helper. A VipsImage allocated/finalized through the bundled GLib is unref’d through the system GLib (or vice versa), so the object’s class pointer is incompatible and the finalize vfunc resolves to NULL — which matches the deterministic PC = 0. Because this happens on the validation-failure path, any image the sync considers invalid can trigger it.

Secondary observation: at least one image URL that the sync reported as REMOTE_CONTROL_IMAGE_INVALID returned a valid PNG when fetched manually, so I could not confirm that the image was genuinely invalid — the validation itself may also be worth a look.

Suggested fixes

  1. Ensure a single GLib implementation for the image pipeline (e.g. link libvips/libgobject against the same GLib, or prevent the addon’s g_* symbols from binding across the two copies).
  2. Treat per-image sync failures as non-fatal: log, skip the image, keep the helper alive.

Workaround

Disabling Settings → Mobile → Remote Control stops the crashes. As of 2026-10-18 the updater reports server-no-update, so 0.4.8 is the latest offered build.

Attachments

I can provide a redacted main.log excerpt. Core dumps are not attached: they contain full process memory, including chat content.

One thing that stood out to me is the repeated crash-and-restart cycle. Even before the underlying issue is fixed, maybe the sync helper could stop retrying the same failed job after a few crashes. That might at least prevent it from getting stuck in a loop.