Skip to content

amuled -o corrupts non-ASCII log lines on stdout (uses C-locale wxConvLibc, never calls setlocale); on-disk logfile is fine #40

Description

@ngosang

Summary

amuled -o (log to stdout) corrupts every log line that contains non-ASCII
characters — e.g. No shareable files found in directory: <path> for a shared
directory whose name has accented/Latin-1 bytes. The bytes come out as ?,
U+FFFD (EF BF BD) and stray control bytes, often losing the line's
timestamp/prefix and bleeding into adjacent lines.

The on-disk logfile (~/.aMule/logfile) for the very same lines is perfectly
fine
(correct UTF-8). Only the stdout stream is corrupted.

amuled does not crash; the share scan completes normally.

Environment

  • aMule 3.0.0 (CMake build), wxBase(GTK3) 3.2.8, Boost 1.83, Debian, x86-64
  • amuled -o, headless, in a C/POSIX locale (e.g. a minimal container: LANG
    unset, LC_CTYPE=POSIX)

Minimal deterministic reproduction

mkdir -p /share/AAA_before $(printf '/share/bad_\x8e\x7f_x') $(printf '/share/caf\xe9_\xf1_y') /share/ZZZ_after
# share /share recursively, then run amuled in a C locale logging to stdout:
LC_ALL=C amuled -o -c <configdir>

stdout shows the two ASCII dirs cleanly but the two non-ASCII dirs come out as
mangled bytes with no timestamp/prefix. ~/.aMule/logfile shows all four lines
correctly (UTF-8).

Root cause

CLogger::DoLine writes each line to two sinks with different conversions
(src/Logger.cpp):

// logfile  -> UTF-8 (clean)
m_ApplogBuf += line;
FlushApplog();                 // wxStringInputStream => wxConvUTF8  (Logger.cpp:298-304)

// stdout   -> C-locale (corrupted)
if (m_StdoutLog || toStdout) {
    printf("%s", (const char*)unicode2char(line));   // Logger.cpp:274
}

unicode2char() converts via wxConvLibc — the C-library locale converter
(src/libs/common/StringFunctions.cpp:42-60). It only works if the current C
locale is UTF-8-capable.

But amuled never calls setlocale(LC_ALL, "") — that call exists only for the
external connectors (src/ExternalConnector.cpp:675, used by amulecmd/amuleweb),
not for CamuleDaemonApp. So amuled's C locale stays at the default "C"
regardless of LANG/LC_ALL, and wxConvLibc mangles every non-ASCII character
written to stdout. The logfile path uses wxConvUTF8 and is therefore unaffected.

Because the converter often emits incomplete/replacement sequences mid-buffer, the
mangled output also loses line boundaries and merges into neighbouring lines.

Evidence

  • strace -f -e write shows amuled's actual write() to the logfile fd is clean,
    correctly-UTF-8-encoded, one full line per write.
  • ~/.aMule/logfile on disk: clean UTF-8 for the exact same directories.
  • The corrupted bytes are only ever on the stdout stream.
  • Setting LANG/LC_ALL/LC_CTYPE=C.UTF-8 (or C.utf8) on the process has no
    effect
    — consistent with amuled never calling setlocale.

Suggested fix (either)

  1. Make the stdout sink use UTF-8 to match the logfile, e.g. write
    line.utf8_str() instead of unicode2char(line) in CLogger::DoLine
    (Logger.cpp:274); or
  2. Call setlocale(LC_ALL, "") during CamuleDaemonApp startup so wxConvLibc
    honours the environment locale (same as the connectors already do).

Option 1 is more robust since it does not depend on the deployment locale.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions