Skip to content

fix(libc): format guest wide arguments in syslog on Linux - #4359

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
milescoviello:fix/syslog-wide-format
Oct 12, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
milescoviello:fix/syslog-wide-format

Conversation

@milescoviello

@milescoviello milescoviello commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

On Linux, vsyslog (and syslog) formats the message with the host's vsnprintf, so a %ls, %S, %lc or %C argument is read as glibc's 32-bit wchar_t instead of the guest's 16-bit units. glibc fails the conversion and the message is dropped: on main syslog(LOG_DEBUG, "wide %ls %d %S", u"guest", 5, u"text") writes [syslog:15] with nothing after it. Windows already formats syslog messages with the guest formatter, and the narrow printf family does so on Linux for formats with a guest wide conversion (#1804).

FreeBSD 11.4 lib/libc/gen/syslog.c line 229 formats the message with

(void)vfprintf(fp, fmt, ap);

and lib/libc/stdio/vfprintf.c lines 831-843 converts %S and %ls from the guest's wchar_t:

case 'S':
	flags |= LONGINT;
	/*FALLTHROUGH*/
case 's':
	if (flags & LONGINT) {
		wchar_t *wcp;
...
			convbuf = __wcsconv(wcp, prec);

vsyslog now formats through the guest's vsnprintf, which hands formats with a guest wide conversion to the guest formatter (UTF-8 output, as for printf) and every other format to glibc as before. No title is claimed.

Tested

Ubuntu 24.04, GCC 13.3 (CI's compiler), Release with CI's configure flags.

  • guest_syslog logs "wide %ls %d %S" with u"guest", 5 and u"text" and expects [syslog:15] wide guest 5 text.
  • With only the test applied to main's library sources it aborts (the captured line is [syslog:15] with an empty message).
  • With the fix it passes, and all 294 guest_* tests pass (-E '^guest_video_out_').

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • AI-assisted: yes

vsyslog formats the message with the host's vsnprintf on Linux, so a
%ls, %S, %lc or %C argument is read as glibc's 32-bit wchar_t instead
of the guest's 16-bit units. glibc fails the conversion and the message
is dropped: on main syslog(LOG_DEBUG, "wide %ls %d %S", u"guest", 5,
u"text") writes "[syslog:15] " with nothing after it. Windows already
formats syslog messages with the guest formatter, and the narrow printf
family does so on Linux for formats with a guest wide conversion.

FreeBSD 11.4 lib/libc/gen/syslog.c line 229 formats the message with

	(void)vfprintf(fp, fmt, ap);

and lib/libc/stdio/vfprintf.c (lines 831-843) converts %S and %ls from
the guest's wchar_t:

	case 'S':
		flags |= LONGINT;
		/*FALLTHROUGH*/
	case 's':
		if (flags & LONGINT) {
			wchar_t *wcp;
	...
				convbuf = __wcsconv(wcp, prec);

vsyslog now formats through the guest's vsnprintf, which hands formats
with a guest wide conversion to the guest formatter (UTF-8 output, as
for printf) and every other format to glibc as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the libc label Oct 12, 2026
@xXPBSXx

xXPBSXx commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Windows test: head 42bf2a2ad merged onto current main ffa198407 (clean merge, no conflicts). Windows 10, MinGW GCC (WinLibs), Ninja Release, -j4: full build 0 errors; ctest with the filter guest_syslog: guest_syslog passed (1 test(s), 0 failed); python tools/check_conventions.py --base upstream/main passed. I did not run the new tests against main without the change. The title names Linux, so this Windows run only shows that the change builds and the tests still pass on Windows.

AI-assisted (Claude Code).

@oneandonlydean oneandonlydean self-assigned this Oct 12, 2026
@oneandonlydean
oneandonlydean merged commit 15e64ab into boykopovar:main Oct 12, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants