Skip to content

[Native] Migrate configuration diagnostics to printf#12155

Merged
jonathanpeppers merged 15 commits into
mainfrom
dev/simonrozsival/nativeaot-config-printf-logging
Jul 21, 2026
Merged

[Native] Migrate configuration diagnostics to printf#12155
jonathanpeppers merged 15 commits into
mainfrom
dev/simonrozsival/nativeaot-config-printf-logging

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

Continue the printf-style logging migration introduced by #12140 for native configuration and parsing diagnostics.

This PR converts CoreCLR/NativeAOT host-environment messages and the shared MonoVM/CoreCLR/NativeAOT integer-parsing messages to the printf helpers from #12140. Shared code now has one logging path instead of runtime-specific format branches.

Base/dependency: #12140 must merge first. This PR targets dev/simonrozsival/nativeaot-printf-logging so its diff contains only this migration.

Part of #12139.

Scope

Only two files change:

  • src/native/clr/include/host/host-environment.hh
  • src/native/common/include/runtime-base/strings.hh

These files do not overlap #12141, #12142, #12145, #12148, #12150, or #12153.

Changes

Host environment diagnostics

host-environment.hh is shared by CoreCLR and NativeAOT, but not MonoVM.

  • migrate generated system-property diagnostics to %s formatting;
  • migrate XDG directory creation diagnostics to %s formatting;
  • migrate XDG directory failure diagnostics while preserving the original errno text;
  • retain optional_string() handling for null C-string inputs.

Integer parsing diagnostics

strings.hh is shared by all three runtimes. Its variable diagnostics now use log_errorf() without runtime-specific branches:

  • an invalid starting index, using %zu for size_t;
  • signed/unsigned range failures, using explicitly converted %lld / %llu values;
  • values that do not represent an integer in the selected %d base;
  • trailing non-numeric characters.

The header forward-declares only log_errorf() instead of including the heavyweight formatting declarations from shared/log_types.hh.

Behavior preserved

  • integer conversion logic, range checks, errno handling, and output assignment are unchanged;
  • the copied parse buffer remains NUL-terminated before %s logging;
  • host environment variables and XDG directory creation behavior are unchanged;
  • debug category gating and unconditional error/warning semantics remain unchanged.

Runtime behavior

Runtime Result
NativeAOT Uses #12140 printf helpers for all migrated diagnostics
CoreCLR Uses #12140 printf helpers for shared parsing and host-environment diagnostics
MonoVM Uses the matching MonoVM log_errorf() implementation for shared parsing diagnostics

Measured impact

Representative Android arm64 Release objects compiled before the MonoVM path was unified:

Runtime/object Before After Difference
NativeAOT host-environment.cc.o 131,288 B 130,848 B -440 B
CoreCLR timing-internal.cc.o 194,048 B 193,088 B -960 B

These call sites did not contain explicit std::format expressions, so the impact is smaller than #12150/#12153; the change prevents their formatted logging templates from being instantiated.

Non-goals

  • no new configuration or parsing behavior;
  • no changes to environment-variable storage, XDG path construction, or integer parsing buffers;
  • no new logging tests;
  • no attempt to migrate unrelated configuration code outside these two headers.

Validation

  • git diff --check;
  • NDK Clang C++23 syntax compilation of all 36 Android arm64 Release NativeAOT source variants;
  • NDK Clang C++23 syntax compilation of all 38 Android arm64 Release CoreCLR source variants;
  • NDK Clang C++23 syntax compilation of all 31 Android arm64 Release MonoVM source variants;
  • representative before/after object compilation and size comparison;
  • focused review of signed/unsigned conversions, format widths, null termination, include dependencies, and runtime behavior;
  • latest head: 72cad5d01.

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
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
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
Convert host environment and integer parsing diagnostics to #12140 printf helpers while preserving MonoVM formatting branches.

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

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

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.

Pull request overview

Migrates native configuration and integer-parsing diagnostics in the CoreCLR/NativeAOT code paths from std::format-style logging to the printf-checked log_*f() helpers introduced in #12140, reducing formatted-template instantiations while keeping MonoVM behavior unchanged.

Changes:

  • Convert HostEnvironment diagnostics in host-environment.hh to log_debugf() / log_warnf() with %s formatting and optional_string() for null safety.
  • Convert string_segment::to_integer() diagnostics in strings.hh to runtime-guarded log_errorf() for CoreCLR/NativeAOT (MonoVM retains existing log_error() + {} formatting).
  • Add an explicit shared/log_types.hh include for non-MonoVM builds in strings.hh to avoid reliance on caller include order.
Show a summary per file
File Description
src/native/common/include/runtime-base/strings.hh Adds non-MonoVM logging header include and migrates integer-parsing diagnostics to log_errorf() under runtime guards.
src/native/clr/include/host/host-environment.hh Migrates CoreCLR/NativeAOT host environment debug/warn diagnostics to printf-style log_*f() calls.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment thread src/native/common/include/runtime-base/strings.hh Outdated
@simonrozsival simonrozsival added the drop-libcpp Work to remove the libc++ dependency from Android NativeAOT label Jul 17, 2026
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
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 [CoreCLR/NativeAOT] Migrate configuration diagnostics to printf [Native] Migrate configuration diagnostics to printf Jul 17, 2026
@jonathanpeppers

Copy link
Copy Markdown
Member

/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 — ✅ LGTM (with 1 minor suggestion)

Clean, well-scoped continuation of the printf-logging migration (#12139). Verified independently against the diff and full file context.

What I checked

  • %s safetyoptional_string() returns const char* and the to_integer parse buffer s is explicitly NUL-terminated before logging, so all %s conversions are well-defined.
  • Format widths%zu for size_t start_index, %d for the int base, and %lld/%llu for the range bounds all match their argument types. The double casts (int64_tlong long, uint64_tunsigned long long) correctly bridge the fixed-width types to the printf promotion types across ABIs.
  • Range semantics — signed/unsigned min/max printing preserves the original std::format output for both signed and unsigned T.
  • Forward declaration — the manual log_errorf declaration exactly matches the canonical one in shared/log_types.hh (signature + format(printf,2,3) attribute), and LogCategories is in scope via helpers.hhjava-interop-util.h.
  • Behavior parity — errno handling, conversion logic, and XDG directory diagnostics are unchanged.

Notes

  • 💡 One inline suggestion about the duplicated forward declaration (drift risk) — non-blocking.
  • CI shows pending/no checks yet, expected since this PR targets the dev/simonrozsival/nativeaot-printf-logging base branch (dependency on #12140). Not mergeable until #12140 lands and CI is green.

Nice reduction in template instantiation with measured object-size wins. 👍

Generated by Android PR Reviewer for #12155 · 77.7 AIC · ⌖ 12.8 AIC · ⊞ 6.8K
Comment /review to run again

Comment thread src/native/common/include/runtime-base/strings.hh Outdated
simonrozsival added a commit that referenced this pull request Jul 20, 2026
## 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.
Base automatically changed from dev/simonrozsival/nativeaot-printf-logging to main July 20, 2026 13:44
jonathanpeppers pushed a commit that referenced this pull request Jul 20, 2026
## Summary

Continue the printf-style logging migration introduced by #12140 in the shared native timing infrastructure.

The timing headers are used by MonoVM, CoreCLR, and NativeAOT. All three runtimes now use the same printf-style path for variable timing diagnostics rather than maintaining MonoVM-only `std::format` branches.

**Base/dependency:** #12140 must merge first. This PR targets `dev/simonrozsival/nativeaot-printf-logging` so its diff contains only the timing migration.

Part of #12139.

## Scope

Only two shared timing headers change:

- `src/native/common/include/runtime-base/timing.hh`
- `src/native/common/include/runtime-base/timing-internal.hh`

These files do not overlap #12141, #12142, #12145, #12148, #12150, or #12155.

## Changes

### Managed timing records

- replace the owning `std::format` result in `Timing::do_log()` with `log_writef()` for every runtime;
- preserve the exact `message; elapsed: seconds:milliseconds::nanoseconds` field order;
- pass duration values as explicitly converted `unsigned long long` values matching `%llu`.

### Fast timing diagnostics

Migrate variable diagnostics to `log_warnf()` for every runtime:

- timing event buffer reallocation sizes;
- `CLOCK_MONOTONIC_RAW` errors;
- unknown event-kind values;
- invalid event-index source method names.

Constant warning messages continue using the existing non-formatting `string_view` overload.

## Behavior preserved

- timing enablement and category gating are unchanged;
- timing sequence acquisition/release is unchanged;
- elapsed duration units, values, and output order are unchanged;
- event-buffer growth, clock error handling, unknown-event fallback, and index validation are unchanged;
- no timing data structures, locks, vectors, strings, or event lifecycle code change.

## Runtime behavior

| Runtime | Result |
|---|---|
| NativeAOT | Uses #12140 printf helpers for variable timing diagnostics |
| CoreCLR | Uses #12140 printf helpers for variable timing diagnostics |
| MonoVM | Uses the matching MonoVM printf helper implementation from #12140 |

## Measured impact

Representative Android arm64 Release objects compiled before the MonoVM path was unified:

| Runtime/object | Before | After | Difference |
|---|---:|---:|---:|
| CoreCLR `internal-pinvokes-clr.cc.o` | 145,472 B | 17,080 B | -128,392 B (-88.26%) |
| NativeAOT `host.cc.o` | 176,104 B | 175,960 B | -144 B |

CoreCLR's representative object drops from 58 formatting symbols to zero. NativeAOT's representative object still contains formatting symbols from other included functionality, but the timing call sites migrated here no longer instantiate them.

## Non-goals

- no new timing tests or logging test framework;
- no change to timing data ownership or synchronization;
- no changes to the logging helper implementation introduced by #12140;
- no attempt to migrate unrelated timing output/file-generation code outside these shared timing headers.

## Validation

- `git diff --check`;
- NDK Clang C++23 syntax compilation of all 36 Android arm64 Release NativeAOT source variants;
- NDK Clang C++23 syntax compilation of all 38 Android arm64 Release CoreCLR source variants;
- NDK Clang C++23 syntax compilation of all 31 Android arm64 Release MonoVM source variants;
- representative before/after object compilation, size comparison, and symbol inspection;
- focused review of chrono values, integer format widths, source-location output, and category semantics;
- latest head: `21ff66b26`.

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

Copilot-Session: 0f0df1cb-536b-4c53-902e-cbbb9d8e9a15
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f0df1cb-536b-4c53-902e-cbbb9d8e9a15
Resolve the logging declaration conflicts by retaining the lightweight canonical header, and preserve the reviewed NativeAOT status string constants.

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

Copilot-Session: 0f0df1cb-536b-4c53-902e-cbbb9d8e9a15
Include the lightweight declaration header from both implementations and the printf-only abort helper so signatures remain checked without adding the std::format surface.

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

Copilot-Session: 0f0df1cb-536b-4c53-902e-cbbb9d8e9a15
@jonathanpeppers

Copy link
Copy Markdown
Member

/review

@github-actions

github-actions Bot commented Jul 21, 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 notes (no blocking issues)

Reviewed the printf-logging migration for native configuration/parsing diagnostics. The core changes are correct and safe.

✅ Verified correct

  • Format specifiers match argument types: %zu for size_t start_index; %lld/%llu with explicit static_cast<long long>/static_cast<unsigned long long> for the range bounds; %d for the int base; %s for C-strings. All call sites are further guarded by the __attribute__((format(printf, ...))) declarations in the new log_functions.hh, so any mismatch would fail the build.
  • No null-%s UB: optional_string() returns "<null>" (never nullptr) for null inputs, and the parse buffer s in strings.hh is always NUL-terminated before logging, so %s is safe on bionic.
  • Behavior preserved: integer conversion, range checks, errno handling, XDG directory creation, and debug-category gating are unchanged. Dropping the sv literals is correct for printf-style formatting.
  • Header refactor is sound: centralizing the log_*f declarations in src/native/common/include/shared/log_functions.hh and including it from the per-runtime log_types.hh removes duplication cleanly; strings.hh now only depends on the function declarations it actually uses.

⚠️ Notes (non-blocking)

  1. PR description is out of date with the diff. The description states "Only two files change" (host-environment.hh, strings.hh) and references head 72cad5d01, but this PR actually touches 9 files at head 71cfe50 — including the new common/include/shared/log_functions.hh and the log_types.hh/log_functions.cc/helpers.cc refactors and the bridge-processing.cc constant dedup. Worth updating the description so reviewers aren't surprised by the broader scope.
  2. See the inline 💡 on bridge-processing.cc about scoping the ABSENT/PRESENT constants inside the failure branch.

CI

Checks are still pending (no completed required checks at review time). Since format-string correctness here relies on the compiler's printf attribute checks, the native build must go green before merge — please confirm the NativeAOT/CoreCLR/MonoVM builds pass before merging.

Nice, low-risk migration overall. 👍

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

Comment thread src/native/nativeaot/host/bridge-processing.cc
@jonathanpeppers jonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jul 21, 2026
@jonathanpeppers
jonathanpeppers merged commit 249f962 into main Jul 21, 2026
44 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/simonrozsival/nativeaot-config-printf-logging branch July 21, 2026 21:15
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 ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants