From Claude Code
Version: 46 and 46+ — reproduces on both, so this is not a regression
OS: Ubuntu 24.04.4, x86-64, X11 build
Severity: crash; blocks ngspice's own make check in a headless environment
Reproduction
$ echo quit | env -u DISPLAY ngspice -p
...
please check if X-server is running,
or ngspice is compiled properly (see INSTALL)
Segmentation fault (core dumped) # exit 139
No circuit is involved — quit alone is enough.
Scope, same binary, same environment:
┌────────────────┬───────────────┬─────────────┐
│ invocation │ DISPLAY unset │ DISPLAY set │
├────────────────┼───────────────┼─────────────┤
│ ngspice -p │ SIGSEGV (139) │ 0 │
├────────────────┼───────────────┼─────────────┤
│ ngspice -i │ SIGSEGV (139) │ 0 │
├────────────────┼───────────────┼─────────────┤
│ ngspice -b │ 1 (clean) │ — │
├────────────────┼───────────────┼─────────────┤
│ ngspice (bare) │ 1 (clean) │ — │
└────────────────┴───────────────┴─────────────┘
Impact on the test suite
tests/regression/pipe runs $(top_builddir)/src/ngspice -p < $1. Consequently:
$ env -u DISPLAY make -C tests/regression check
... Segmentation fault (core dumped) ../../../src/ngspice -p < $1
make: *** [check] Error 2
With a display present the same suite is 59/59 PASS. A CI or container consumer therefore cannot run make check at all, and the failure looks like a test failure rather than a crash.
Pointer to the area (not a proven root cause — the binary is stripped, so no symbolised frame)
src/frontend/display.c:203-215: when dispdev is NULL, externalerror() emits the message above and the code falls back with dispdev = FindDev("error"). The "error" row in the device table at display.c:44 is { "error", 0, 0, 0, 0, 0, 0, ...} — its entries are null. valgrind reports:
Invalid read of size 4
Access not within mapped region at address 0x10
which is consistent with a member read through a null pointer shortly afterwards.
Suggested fix
Give the "error" device real no-op entries, or have -p/-i exit cleanly with the diagnostic instead of continuing into the graphics path — the same way -b already does.