Skip to content

[Native] Join paths without dynamic strings - #12511

Open
simonrozsival wants to merge 21 commits into
mainfrom
dev/simonrozsival/use-join-paths-for-logger
Open

[Native] Join paths without dynamic strings#12511
simonrozsival wants to merge 21 commits into
mainfrom
dev/simonrozsival/use-join-paths-for-logger

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Aug 25, 2026

Copy link
Copy Markdown
Member

Summary

Replace shared CoreCLR/NativeAOT path-building local strings with C buffers while preserving the original distinction between static and dynamic storage.

Changes

  • make the low-level path formatter return the written length or the negative required capacity including NUL
  • use a single non-template retry overload with an explicit stack-buffer capacity
  • return the selected stack or exact-size malloc() buffer directly
  • free returned storage only when it differs from the caller-owned stack buffer
  • keep the former static_local_string XDG path stack-only
  • migrate fallback log paths, environment overrides, libmonodroid.so detection, and timing output paths
  • remove obsolete CLR local-string path helpers and dependencies

Validation

  • Local native builds intentionally skipped; relying on CI validation

Copilot AI lite review requested due to automatic review settings August 25, 2026 10:30
@simonrozsival simonrozsival added the drop-libcpp Work to remove the libc++ dependency from Android NativeAOT label Aug 25, 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.

Pull request overview

Replaces dynamic fallback-path construction with bounded, caller-owned storage for CoreCLR/NativeAOT logging.

Changes:

  • Adds Util::join_paths with separator handling and capacity checks.
  • Uses fixed stack storage for gref/lref fallback paths.
  • Skips and logs paths exceeding buffer capacity.
Show a summary per file
File Description
src/native/clr/runtime-base/logger.cc Builds fallback log paths without dynamic strings.
src/native/clr/include/runtime-base/util.hh Adds the bounded path-joining helper.

Review details

Suppressed comments (4)

src/native/clr/include/runtime-base/util.hh:343

  • 💡 Maintainability — The separator behavior here is intentionally different from path_combine: it strips one leading / only when first already ends with /, while empty components are copied unchanged. Please document this contract next to the helper, including that buffer_size includes space for the terminating NUL, so future callers do not infer a different normalization policy.
			bool remove_duplicate_separator = first.ends_with ('/') && second.starts_with ('/');
			bool add_separator = !first.empty () && !second.empty () && !first.ends_with ('/') && !second.starts_with ('/');
			size_t second_offset = remove_duplicate_separator ? 1uz : 0uz;

src/native/clr/include/runtime-base/util.hh:363

  • 💡 Native C++<cstring> guarantees the declaration in std, but this unqualified call relies on implementation-provided global namespace injection. Use std::memcpy here to keep the new helper portable.

Rule: Use C++ standard headers and names

				memcpy (destination, second.data () + second_offset, second_length);

src/native/clr/include/runtime-base/util.hh:355

  • 💡 Native C++<cstring> guarantees the declaration in std, but this unqualified call relies on implementation-provided global namespace injection. Use std::memcpy here to keep the new helper portable.

Rule: Use C++ standard headers and names

				memcpy (destination, first.data (), first.length ());

src/native/clr/runtime-base/logger.cc:84

  • 💡 Error message — When the fallback path is rejected, this is the only diagnostic, but it does not identify the directory or the capacity that was exceeded. Include the relevant lengths and path_buffer.size() so users can determine which configured path caused reference logging to be skipped.
		log_warnf (category, "Unable to open fallback log file: path is too long");
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

@simonrozsival simonrozsival changed the title [Native] Join fallback log paths without dynamic strings [Native] Join paths without dynamic strings Aug 25, 2026
@simonrozsival simonrozsival added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Aug 25, 2026
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12511

@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.

⚠️ Needs Changes — 0 errors, 1 warning, 0 suggestions.

The bounded helper is a clear improvement over implicit dynamic path storage, and all 44 CI checks are green. The remaining concern is direct boundary coverage for the new duplicated path primitive before it becomes a broader replacement for path_combine.

Generated by Android PR Reviewer for #12511 · gpt56 · 101.4 AIC · ⌖ 17.1 AIC · ⊞ 25.7K
Comment /review to run again

Comment thread src/native/clr/include/runtime-base/util.hh Outdated
simonrozsival and others added 10 commits August 25, 2026 17:04
Add a bounded caller-buffer path join helper and use it for reference log fallback paths, removing one dynamic_local_string use shared by CoreCLR and NativeAOT.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use caller-owned buffers for XDG directories, environment override files, and libmonodroid detection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return bytes written including the terminating NUL so callers can use their buffers directly and create string views only when needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return -1 on failure and the path length excluding the terminating NUL on success, matching strlen-style length semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The join_paths migrations remove the remaining callers of the local-string file_exists and path_combine helpers, so delete the dead overload family and strings.hh dependency.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the CLR path capacity constant directly now that XDG paths use caller-owned buffers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival
simonrozsival force-pushed the dev/simonrozsival/use-join-paths-for-logger branch from 9dfbdc6 to b558fd4 Compare August 25, 2026 15:04
Preserve dynamic_local_string semantics by treating SENSIBLE_PATH_MAX as an inline-storage threshold rather than a path limit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival simonrozsival removed the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Aug 25, 2026
simonrozsival and others added 3 commits August 25, 2026 17:28
Keep exact-size path allocation independent of libc++ and free each temporary after its final consumer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Calculate the exact path size, use the runtime-specific local buffer below its sensible threshold, and fall back to malloc only for larger paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoid redeclaring the existing result while retaining cleanup before returning.

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

Copy link
Copy Markdown
Member

/review

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12511

@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.

⚠️ Needs Changes

Findings: 0 errors · 1 warning · 0 suggestions

The exact-size calculation, overflow checks, separator handling, and NUL termination are clear, and the migrated call sites pair their allocations correctly. The new temporary-buffer API should preserve RAII so later early returns cannot leak heap-backed paths. The prior unresolved review feedback requesting focused boundary tests also still applies.

CI is still in progress: 13 of 44 checks have completed successfully, with 30 running and 1 queued; no failures are currently reported.

Generated by Android PR Reviewer for #12511 · gpt56 · 98.8 AIC · ⌖ 8.91 AIC · ⊞ 25.7K
Comment /review to run again

Comment thread src/native/common/include/shared/helpers.hh Outdated
simonrozsival and others added 4 commits August 25, 2026 20:39
Retry path formatting with exact heap storage only when the sensible stack buffer is insufficient.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return the selected stack or heap buffer from the path helper and centralize conditional heap cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rely on the C guarantee that free accepts null pointers and name stack-backed storage explicitly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use one non-template path helper implementation and make each caller provide its stack capacity.

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

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12511

Remove heap-buffer out parameters, free only returned heap pointers, and keep the former static XDG path buffer stack-only.

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

@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.

⚠️ Needs Changes

Findings: 0 errors · 0 warnings · 1 suggestion.

The stack-first/exact-size fallback contract is applied consistently across the migrated call sites, and cleanup covers each exit path. One redundant startup filesystem operation is called out inline. CI is still in progress (2 checks passed, 6 running, 1 queued), so this cannot be considered green yet.

Generated by Android PR Reviewer for #12511 · gpt56 · 97.5 AIC · ⌖ 19.6 AIC · ⊞ 25.7K
Comment /review to run again

Comment thread src/native/clr/runtime-base/logger.cc Outdated
simonrozsival and others added 2 commits August 25, 2026 23:50
Create the fallback logging directory only once before opening the fallback file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Give the length-returning formatter a distinct name while preserving join_paths as the stack-or-heap pointer API.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants