Menu ▾ ▴

#2259 Headless UI: segfault at startup, log_archdep() dereferences NULL from vice_banner()

v3.x
closed-fixed
gpz
None
Linux
Archdep
2026-09-18
2026-09-18
No

Disclosure: this investigation and write-up were done with the help of Claude Code
(Anthropic). Every factual claim below is backed by a reproducible command line, a
file:line citation, or an SVN revision, given inline.

Version: git mirror VICE-Team/svn-mirror @ cbc2f46 (VICE Version 3.10)
Platform: Linux x86_64 (Ubuntu, kernel 6.8)
Configure: ./configure --enable-headlessui --disable-pdf-docs --without-pulse \
--without-alsa --disable-catweasel --without-oss

Every emulator binary built with the headless UI segfaults before the emulator starts
-- no arguments needed:

$ ./x64sc -default
Segmentation fault (core dumped)

Backtrace:

#0  __strlen_sse2 ()
#1  log_archdep (logtxt=0x0, pretxt=0x0) at log.c:615
#2  log_helper (level=128, format=" ") at log.c:767
#3  log_message (log=-1, format=" ") at log.c:819
#4  vice_banner () at main.c:141
#5  main_program () at main.c:524

log_archdep() computes logtxt + strlen(logtxt) + 1 with no NULL check, and this path
reaches it with logtxt == NULL. Guarding both parameters at the top of log_archdep()
is enough to get the headless build running; I did that locally to test something
unrelated and saw no other startup problem.

Note on the tracker's request for a startup logfile: the crash happens before logging
is usable, so -logfile produces nothing. There is no log to attach for this one.

Discussion

  • gpz

    gpz - 2026-09-18

    mmmh i'd rather know where that NULL pointer comes from.... it should never happen :)

     
  • gpz

    gpz - 2026-09-18

    i can not reproduce this, please post the output of

    grep -n2 SVN src/config.h

    and

    grep -n2 SVN_REV src/svnversion.h

     

    Last edit: gpz 2026-09-18
  • Enver Haase-Beer

    You are right that it should never happen, and the NULL does not originate where the backtrace ends. Tracing it back -- and correcting my own report -- this is not headless-specific.

    log_helper() declares

    char *nocolorpre = NULL;
    char *nocolortxt = NULL;
    

    and fills them only inside

    if ((log_to_file) || (!log_colorize)) {
        nocolorpre = logskipcolors(pretxt);
        nocolortxt = logskipcolors(logtxt);
    }
    

    but the stdout branch below then does

    if (archdep_default_logger_is_terminal() == 0) {
        terminalpre = nocolorpre;
        terminaltxt = nocolortxt;
    }
    

    unconditionally. With colorize on and no log file open, those two are still NULL and go straight into log_archdep().

    The third condition is what makes it look impossible: archdep_default_logger_is_terminal() (arch/shared/archdep_default_logger.c:133, the POSIX one) returns 0 when stdout is a FIFO or a regular file. In a terminal it returns 1 and the NULL path is never taken. Redirect stdout, and it is.

    What made it bite here is that this machine had no ~/.local/state/vice, so the default log file could not be opened and log_to_file stayed 0. Creating that directory makes the crash disappear, which is presumably why it has not been seen.

    mv ~/.local/state/vice ~/.local/state/vice.bak   # default log file cannot be opened
    ./x64sc -default > out.txt 2>&1
    Segmentation fault (core dumped)
    
    stdout            colorize             result
    ----------------  -------------------  --------
    a regular file    on (default)         segfault
    a pipe            on (default)         segfault
    a terminal        on                   runs
    a regular file    off (+logcolorize)   runs
    

    So the guard I put in log_archdep() treats the symptom. The fix belongs in log_helper(): either build the no-color strings whenever the stdout branch might use them, or stop handing it pointers that were never filled.

    Build details you asked for. config.h: VERSION "3.10", PACKAGE_VERSION "3.10", USE_HEADLESSUI defined, HAVE_DEBUG_GTK3UI and HAVE_DEBUG_THREADS both undefined. svnversion.h: not present -- this is a build from the git mirror (VICE-Team/svn-mirror at cbc2f46) rather than an SVN checkout, so nothing generates it; happy to rebuild from SVN trunk if you need the file itself. gcc 13.3.0, Ubuntu 24.04, x86_64:

    ./configure --enable-headlessui --disable-pdf-docs --without-pulse \
                --without-alsa --disable-catweasel --without-oss
    

    I have only tested headless, but nothing in this path is UI-specific -- a GTK or SDL build with output redirected and no writable log file should do the same.

    As with the original report, investigated with the help of Claude Code (Anthropic).

     
  • gpz

    gpz - 2026-09-18

    i can still not reproduce this, please post the output of

    grep -n2 SVN src/config.h

     
  • gpz

    gpz - 2026-09-18

    fixed in r46240 - it would have helped if you didn't hide the actual cause of the problem (the non existing log dir) in that very verbose text (produced by Claude i assume)

     
  • gpz

    gpz - 2026-09-18
    • status: open-need-info --> closed-fixed
     

Log in to post a comment.