Skip to content

[Native] Add printf-style native logging#12140

Open
simonrozsival wants to merge 8 commits into
mainfrom
dev/simonrozsival/nativeaot-printf-logging
Open

[Native] Add printf-style native logging#12140
simonrozsival wants to merge 8 commits into
mainfrom
dev/simonrozsival/nativeaot-printf-logging

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

Introduce printf-style native logging primitives and migrate the initial NativeAOT formatted logging call sites to them.

This is the first implementation step from #12139 toward removing the Android NativeAOT dependency on libc++.

Changes

  • add log_writev(), log_writef(), log_debugf(), log_infof(), log_warnf(), and log_errorf() alongside the existing std::format APIs;
  • implement the same printf helpers in the CLR and MonoVM shared logging backends so shared runtime code can use one logging path;
  • add Helpers::abort_applicationf() for formatted fatal messages without truncating tombstone text;
  • include <cstdio> explicitly for vasprintf();
  • omit an unused log_fatalf() wrapper; formatted fatal termination uses abort_applicationf() instead;
  • replace the NativeAOT GC-user-peer initialization error's std::format;
  • replace the NativeAOT JNI on-load debug message's {} formatting;
  • avoid std::format inside Helpers::abort_application().

The existing std::format APIs remain available so unrelated call sites can be migrated incrementally. The current stacked migrations are #12148 (shared runtime utilities), #12150 (JNI reference logging), #12153 (timing logging), and #12155 (configuration diagnostics).

Runtime behavior

  • NativeAOT and CoreCLR use the CLR shared logging implementation.
  • MonoVM uses its own shared logging implementation with the same printf helper surface.
  • category filtering and Android log priorities remain unchanged.
  • null format pointers are logged as <null> rather than passed to __android_log_vprint().

Validation

  • git diff --check;
  • Release build of src/native/native-nativeaot.csproj;
  • Release build of src/native/native-clr.csproj;
  • NDK Clang C++23 syntax compilation of the CLR helper changes across NativeAOT/CoreCLR configurations;
  • NDK Clang C++23 syntax compilation of the MonoVM printf implementation in 8 Android configurations;
  • focused review of va_list, category filtering, format checking, source-location behavior, and Android log-priority mapping;
  • latest head: 09f0690da.

Part of #12139.

Introduce printf-style native logging and abort helpers while preserving the existing std::format APIs for MonoVM and CoreCLR. Migrate the NativeAOT-specific formatted call sites to the new primitives.

Refs #12139

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 187b207a-083b-461e-9071-e9aab61c9d07
Copilot AI review requested due to automatic review settings July 16, 2026 23:21
@simonrozsival simonrozsival added the drop-libcpp Work to remove the libc++ dependency from Android NativeAOT label Jul 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@simonrozsival

Copy link
Copy Markdown
Member Author

CI failure analysis

The public dotnet-android build #1513800 completed with 40 of 42 jobs passing. The two failed jobs are unrelated to the logging changes in this PR:

  • MSBuild+Emulator 9 failed only DotNetInstallAndRunMinorAPILevels(True, "net10.0-android36.1", NativeAOT). The linker found duplicate __unw_* symbols in .NET 10.0.9's libRuntime.WorkstationGC.a and NDK 29.0.14206865's libunwind.a. The same test fails with the same collision in the independent [NativeAOT] Reduce owning C++ standard library state #12142 build.

  • MSBuild+Emulator 7 had 16 auto-retry failures. Sampled CoreCLR, NativeAOT, fast-deployment, and dotnet run logs converge on an Android emulator installation failure:

    java.lang.NullPointerException: Attempt to invoke virtual method
    'boolean android.app.usage.StorageStatsManager.isQuotaSupported(java.lang.String)'
    on a null object reference
    

    Bundletool and adb install then fail while creating the package-install session. This is an emulator/system-service failure rather than a product assertion.

The NativeAOT/libunwind collision is additional real-world evidence for #12139.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 70f63eb7-6599-414c-a947-d860705aa0fa
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 70f63eb7-6599-414c-a947-d860705aa0fa
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 70f63eb7-6599-414c-a947-d860705aa0fa
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Code Review — ⚠️ Minor suggestions (no blockers)

Reviewed the printf-style native logging primitives and the NativeAOT call-site migration. This is clean, well-scoped work.

What I verified

  • printf format attributes are correct. Helpers::abort_applicationf uses format(printf, 3, 4); since it's a static member (no implicit this), the 3/4 indices are right. The free functions log_writef (3,4) and log_debugf/log_infof/... (2,3) are also indexed correctly.
  • Category-guard semantics are consistent. The new (log_categories & category) == 0 early-return matches the modern CLR DO_LOG_FMT macro (!= 0 to log), so behavior is unchanged for the migrated log_debugf/log_infof paths. log_warnf/errorf/fatalf are unguarded, matching the existing log_warn/log_error/log_fatal.
  • Null-format safety. log_writev and abort_applicationf both guard nullptr formats with "<null>"/safe_format, and abort_applicationf correctly falls back to safe_format when vasprintf returns < 0.
  • abort_application no longer routes fatal text through std::format — good, this preserves full tombstone text and drops the libc++ dependency as intended.
  • Leak of the vasprintf buffer in abort_applicationf is acceptable: it's a [[noreturn]] abort path, so the process dies immediately.
  • Host-native regression test is a nice addition — it exercises %s/%p/%d forwarding, priority mapping, and disabled-category suppression against Android log stubs.

Suggestions (both inline, non-blocking)

  • 💡 Add an explicit #include <cstdio> in helpers.cc for vasprintf rather than relying on a transitive include.
  • 💡 log_warnf/log_errorf/log_fatalf are currently unused — confirm the follow-up migration PRs consume them so they don't rot.

CI

GitHub commit status is currently pending (checks not yet reported) at 4a27f68. Not treating this as a failure, but the PR isn't mergeable until the Azure DevOps pipeline is green.

Nice, focused first step toward dropping the NativeAOT libc++ dependency. 👍

Generated by Android PR Reviewer for #12140 · 104.3 AIC · ⌖ 13.1 AIC · ⊞ 6.8K
Comment /review to run again

Comment thread src/native/clr/include/shared/log_types.hh Outdated
Comment thread src/native/clr/shared/helpers.cc
Keep the printf logging PR focused on the runtime implementation instead of introducing new host-native logging test infrastructure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 70f63eb7-6599-414c-a947-d860705aa0fa
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 70f63eb7-6599-414c-a947-d860705aa0fa
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 70f63eb7-6599-414c-a947-d860705aa0fa
@simonrozsival simonrozsival changed the title [NativeAOT] Add printf-style native logging [Native] Add printf-style native logging Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drop-libcpp Work to remove the libc++ dependency from Android NativeAOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants