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)
- 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
- 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.
Summary
amuled -o(log to stdout) corrupts every log line that contains non-ASCIIcharacters — e.g.
No shareable files found in directory: <path>for a shareddirectory 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'stimestamp/prefix and bleeding into adjacent lines.
The on-disk logfile (
~/.aMule/logfile) for the very same lines is perfectlyfine (correct UTF-8). Only the stdout stream is corrupted.
amuled does not crash; the share scan completes normally.
Environment
amuled -o, headless, in a C/POSIX locale (e.g. a minimal container:LANGunset,
LC_CTYPE=POSIX)Minimal deterministic reproduction
stdout shows the two ASCII dirs cleanly but the two non-ASCII dirs come out as
mangled bytes with no timestamp/prefix.
~/.aMule/logfileshows all four linescorrectly (UTF-8).
Root cause
CLogger::DoLinewrites each line to two sinks with different conversions(
src/Logger.cpp):unicode2char()converts viawxConvLibc— the C-library locale converter(
src/libs/common/StringFunctions.cpp:42-60). It only works if the current Clocale is UTF-8-capable.
But amuled never calls
setlocale(LC_ALL, "")— that call exists only for theexternal 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, andwxConvLibcmangles every non-ASCII characterwritten to stdout. The logfile path uses
wxConvUTF8and 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 writeshows amuled's actualwrite()to the logfile fd is clean,correctly-UTF-8-encoded, one full line per write.
~/.aMule/logfileon disk: clean UTF-8 for the exact same directories.LANG/LC_ALL/LC_CTYPE=C.UTF-8(orC.utf8) on the process has noeffect — consistent with amuled never calling
setlocale.Suggested fix (either)
line.utf8_str()instead ofunicode2char(line)inCLogger::DoLine(
Logger.cpp:274); orsetlocale(LC_ALL, "")duringCamuleDaemonAppstartup sowxConvLibchonours the environment locale (same as the connectors already do).
Option 1 is more robust since it does not depend on the deployment locale.