Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Convert corehost hostmisc trace and fx_ver to C by Copilot · Pull Request #128420 · dotnet/runtime · GitHub
Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Convert corehost hostmisc trace and fx_ver to C by Copilot · Pull Request #128420 · dotnet/runtime · GitHub
Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Convert corehost hostmisc trace and fx_ver to C by Copilot · Pull Request #128420 · dotnet/runtime · GitHub
Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Convert corehost hostmisc trace and fx_ver to C by Copilot · Pull Request #128420 · dotnet/runtime · GitHub
Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Convert corehost hostmisc trace and fx_ver to C by Copilot · Pull Request #128420 · dotnet/runtime · GitHub
Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Convert corehost hostmisc trace and fx_ver to C by Copilot · Pull Request #128420 · dotnet/runtime · GitHub
Skip to content

Convert corehost hostmisc trace and fx_ver to C - #128420

Merged
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c
Jun 12, 2026
Merged

Convert corehost hostmisc trace and fx_ver to C#128420
elinor-fung merged 23 commits into
mainfrom
copilot/hostmisc-c

Conversation

CopilotAI commented May 20, 2026

Copy link
Copy Markdown
Contributor

Split of #126367: converting the trace and fx_ver modules in src/native/corehost/hostmisc from C++ to C, and reshaping pal/utils for a C-callable surface.

These are pieces that both apphost and nethost would need (also, fxr_resolver, but didn't include that yet). My thought is to get the shared pieces in and then the apphost and nethost conversions with their separate sets of complications can be iterated on in parallel.

cc @dotnet/appmodel @AaronRobinsonMSFT

  • trace
    • trace.c replaces trace.cpp
    • trace.h exposes a C trace_* API with C++ inline forwarders.
  • fx_ver
    • hostmisc/fx_ver.{c,h} (moved from fxr/) implements the semver parser in C
    • fxr/fx_ver.cpp is now a thin C++ wrapper over c_fx_ver_t.
      • This is left as we are currently consuming via the C++ surface. The plan is to switch nethost and apphost to use the C version directly. After that, will evaluate the others (hostfxr, hostpolicy) as their usage is much more involved.
  • pal / utils:
    • pal.h / utils.h reorganized into a C-compatible section and a C++ pal:: section under #ifdef __cplusplus.
    • pal.*.c / utils.c provide implementations for functions needed for trace and fx_ver. pal.*.cpp / utils.cpp versions of those functions are wrappers around the C implementations.
  • build
    • minipal linked in for host binaries (minipal_objects for static libraries)

Windows x64 Release

BinaryMainPRΔ%
apphost.exe146,944137,728−9,216−6.27%
comhost.dll175,616166,400−9,216−5.25%
dotnet.exe148,992135,168−13,824−9.28%
hostfxr.dll342,528340,992−1,536−0.45%
hostpolicy.dll344,576342,528−2,048−0.59%
ijwhost.dll119,296109,056−10,240−8.58%
nethost.dll102,91289,088−13,824−13.43%
singlefilehost.exe10,374,14410,372,096−2,048−0.02%

Linux x64 Release

BinaryMainPRΔ%
apphost74,54471,792−2,752−3.69%
dotnet54,93652,552−2,384−4.34%
libhostfxr.so321,280320,352−928−0.29%
libhostpolicy.so306,704305,552−1,152−0.38%
libnethost.so70,62467,824−2,800−3.96%
singlefilehost10,790,22410,789,264−960−0.01%

Static libraries (libhostfxr.a/lib and libnethost.a/lib) do grow due to including minipal_objects - consumers can (probably should) link with dead code elimination.

CopilotAI review requested due to automatic review settings May 20, 2026 23:41
CopilotAI removed the request for review from CopilotMay 20, 2026 23:41
CopilotAI changed the title [WIP] Implement trace conversion in hostmisc filesBreak out hostmisc C conversion slice (trace + fx_ver + PAL delegation)May 20, 2026
CopilotAI requested a review from elinor-fungMay 20, 2026 23:46
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label May 21, 2026
@elinor-fungelinor-fung added area-Host and removed area-PAL-coreclr only for closed issues labels May 21, 2026
elinor-fungand others added 6 commits May 21, 2026 19:25
Replaces trace.cpp with a pure-C trace.c implementation. The trace
module is now C end-to-end on every platform: pal.windows.c and
pal.unix.c are pure C calling Win32/POSIX directly, with no C++ in
the trace call path.
Key changes:
* trace.cpp removed; trace.c provides trace_setup/enable/is_enabled/
verbose/info/warning/error/println/println_empty/flush plus the
va_list variants (trace_*_v) and trace_set/get_error_writer.
* trace.h keeps the trace::* C++ namespace as inline forwarders to
the new trace_* C functions, so existing corehost C++ callers
continue to work without source changes.
* pal.h reorganized into a C-compatible section at the top (pal_char_t,
_X with two-step expansion for C-mode MSVC, PAL_THREAD_LOCAL,
APPHOST_PATH_MAX, DIR_SEPARATOR_STR, pal_str_* macros, extern \"C\"
decls for pal_get_own_executable_path/pal_directory_exists/pal_getenv/
pal_xtoi) plus the existing pal:: namespace gated under #ifdef
__cplusplus.
* pal.unix.c provides the four pal_* functions trace.c needs on POSIX.
pal.windows.c provides pal_get_own_executable_path (via
GetModuleFileNameW) and pal_directory_exists (GetFileAttributesW +
FILE_ATTRIBUTE_DIRECTORY check, matching Unix S_ISDIR semantics).
pal_getenv and pal_xtoi are static inline in pal.h on Windows.
* utils.h gates its C++ surface under #ifdef __cplusplus and adds an
extern \"C\" declaration of utils_get_filename, used by trace.c when
TRACEFILE points to a directory. utils.c implements just that one
helper.
* The original spin lock (std::atomic_flag) is replaced with
minipal_mutex, lazy-initialized via InitOnceExecuteOnce on Windows
and pthread_once on POSIX. The corehost root CMakeLists.txt now adds
the minipal subdirectory; hostmisc/hostmisc_public link against
minipal/minipal_objects (gated NOT CLR_CMAKE_TARGET_BROWSER), and
libnethost/libhostfxr static archives bundle minipal_objects so the
symbols ship in the public archives.
* Trace behavior is preserved including the 'Tracing enabled @
<timestamp>' log line (a small strftime helper in trace.c emits the
same UTC GMT format as the original pal::get_timestamp).
* trace_enable now detects truncation when constructing the per-PID
trace path and reports it as a file open error rather than silently
using a bad path. trace_error_v emits a fixed fallback message via
stderr/error_writer if format/allocation fails, matching the old
C++ behavior where such failures propagated as exceptions.
First split of #126367 (rest of the C-conversion work follows).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the fx_ver semver parsing/comparison logic from the C++ class to
a pure-C implementation in hostmisc/fx_ver.c. The C++ `fx_ver_t` class is
preserved as a thin wrapper that delegates to the new `c_fx_ver_*` API,
so existing C++ callers compile unchanged.
Key changes:
* New `hostmisc/fx_ver.h`: declares `c_fx_ver_t` + `c_fx_ver_init/
cleanup/set/is_empty/parse/compare/as_str` in an `extern \"C\"` block, with
the existing `fx_ver_t` C++ class declarations gated under`#ifdef __cplusplus`.
* New `hostmisc/fx_ver.c`: ports parse_internal, valid_identifier(s),
try_stou, index_of_non_numeric, get_id_len, c_fx_ver_compare, and
c_fx_ver_as_str using pal_char_t buffers + malloc/free for owned
strings. The structure mirrors the original C++ logic.
* Rewritten `fxr/fx_ver.cpp`: every member function (constructors,
operators, as_str, compare, parse) now delegates to the C functions.
`as_str`/`compare` borrow `pal::string_t::c_str()` pointers into a
stack-allocated `c_fx_ver_t` (no allocation, no cleanup); `parse`
copies the C-allocated strings out into `pal::string_t` and calls
`c_fx_ver_cleanup`. Drops the validate-in-constructor `assert`s
(they referenced the now-static C helpers).
* `hostmisc/pal.h` adds three more C-callable string macros that fx_ver.c
needs: `pal_strchr`, `pal_strncmp`, `pal_strtoul`.
* CMake plumbing: `hostmisc/CMakeLists.txt` adds `fx_ver.c` and lists
`fx_ver.h` in HEADERS; `hostcommon/files.cmake` and the test
`test/fx_ver/CMakeLists.txt` are updated to point at the new
`hostmisc/fx_ver.h` location.
Validation:
* Native host build clean on Windows Release (host subset).
* Dedicated `test_fx_ver` semver test passes (exit code 0) against the
new C-backed implementation.
Second split of #126367.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Introduces a C-callable pal_getenv that returns a heap-allocated copy of
the named environment variable's value (or NULL if unset/empty). The
caller is responsible for free()ing the returned pointer.
Matches the existing C++ pal::getenv semantics, which always allocates
into a pal::string_t. Choosing the always-allocate API keeps the surface
small (one parameter, one return) and lets call sites use a single
unconditional free() for cleanup.
Also replaces trace.c's get_host_env_var with a thin DOTNET_HOST_<name> /
COREHOST_<name> fallback wrapper around pal_getenv. trace_setup and
trace_enable now use the heap-allocated values directly and free() them
at the end of the call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Four spots in trace.c had if/else pairs where both branches were single
statements with no braces. Add braces consistently so every if/else in
the new C code follows the 'if there is an else, both branches are
braced' rule.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Moves the two remaining ifdef'd platform-specific calls in trace.c into
pal.h as macros, alongside the existing pal_xtoi / pal_str* family:
* pal_get_pid() -> ((int)GetCurrentProcessId()) / ((int)getpid())
* pal_file_open(p, m) -> _wfsopen(p, m, _SH_DENYNO) / fopen(p, m)
trace.c no longer needs to ifdef around get-pid or fopen, and the
Windows-only <share.h> / Unix-only <unistd.h> includes drop out of
trace.c (share.h is now pulled in via pal.h's Windows section).
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Replaces the bodies of the C++ pal:: implementations with calls to the
new C pal_* APIs:
* pal::is_directory -> pal_directory_exists (both)
* pal::getenv -> pal_getenv (both)
* pal::get_own_executable_path -> pal_get_own_executable_path (both)
Where the original C++ behavior went beyond what the previous C contract
supported, the C side is extended so the C++ wrappers can stay trivial:
* pal_get_own_executable_path is now an always-allocate API
(returns pal_char_t* / NULL, caller frees) -- consistent with pal_getenv.
On Windows it does the GetModuleFileNameW doubling-buffer loop (starting
at MAX_PATH = 260) that the prior GetModuleFileNameWrapper had, so paths
longer than the old APPHOST_PATH_MAX still work and short paths use a
smaller initial allocation than the old 4 KB std::vector wrapper. On Unix
it just returns the malloc'd result of minipal_getexepath. trace.c is
updated for the new signature (free the result).
* pal_getenv on Windows now emits trace_warning on non-ERROR_ENVVAR_NOT_FOUND
GetEnvironmentVariableW failures, matching the warning the C++ pal::getenv
used to emit. Putting the warning inside pal_getenv (rather than capturing
GetLastError after it returns NULL in the C++ wrapper) avoids any
fragility around malloc/free perturbing GetLastError.
Pure-define wrappers (pal_strlen, pal_str_printf, pal_xtoi, pal_get_pid,
pal_file_open, etc.) are intentionally not delegated -- they are already
trivial macros and the C++ pal:: inlines compile to the same calls.
No behavior change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 21, 2026 19:26
CopilotAI changed the title Break out hostmisc C conversion slice (trace + fx_ver + PAL delegation)Convert corehost hostmisc trace and fx_ver to CMay 21, 2026
@elinor-fung
elinor-fung marked this pull request as ready for review May 22, 2026 16:32
CopilotAI review requested due to automatic review settings May 22, 2026 16:32

CopilotAI 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

This PR continues the corehost “hostmisc” C-migration by replacing the existing C++ trace implementation with a C implementation + C-callable header surface, and by moving the SemVer parser (fx_ver) into a C implementation with a thin C++ wrapper retained for existing callers. It also reshapes pal / utils so they can be consumed from C code, and updates CMake wiring to pull in minipal/minipal_objects where needed.

Changes:

  • Replace hostmisc/trace.cpp with hostmisc/trace.c and expose a C trace_* API in trace.h (with inline C++ shims for existing trace:: callers).
  • Move SemVer parsing into hostmisc/fx_ver.{c,h} (C API) and rework fxr/fx_ver.cpp into a C++ wrapper over c_fx_ver_*.
  • Add/adjust C PAL + utils helpers and update CMake to include/link minipal/minipal_objects for host binaries/static libraries.
Show a summary per file
FileDescription
src/native/minipal/CMakeLists.txtDisables CMAKE_INCLUDE_CURRENT_DIR in minipal directory scope.
src/native/corehost/CMakeLists.txtAdds minipal subdirectory to non-browser corehost builds.
src/native/corehost/hostmisc/CMakeLists.txtSwitches hostmisc sources to C implementations and wires minipal/minipal_objects linkage (non-browser).
src/native/corehost/hostmisc/pal.hReorganizes into a C-compatible section plus C++ pal:: section under __cplusplus.
src/native/corehost/hostmisc/pal.windows.cAdds Windows C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.unix.cAdds Unix C implementations for pal_getenv, pal_get_own_executable_path, pal_directory_exists.
src/native/corehost/hostmisc/pal.windows.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/pal.unix.cppRedirects selected C++ pal:: functions to the new C implementations.
src/native/corehost/hostmisc/utils.hMakes header C-safe (guards C++-only pieces) and declares utils_get_filename for C callers.
src/native/corehost/hostmisc/utils.cAdds C implementation of utils_get_filename used by trace.c.
src/native/corehost/hostmisc/trace.hIntroduces a C trace_* API and C++ inline forwarders for trace::.
src/native/corehost/hostmisc/trace.cNew C implementation of trace functionality (locking, env var reading, output).
src/native/corehost/hostmisc/fx_ver.hNew C SemVer API (c_fx_ver_*) plus C++ fx_ver_t wrapper declaration.
src/native/corehost/hostmisc/fx_ver.cNew C SemVer parsing/comparison implementation.
src/native/corehost/fxr/fx_ver.cppReplaces prior C++ semver logic with a thin wrapper over c_fx_ver_*.
src/native/corehost/hostcommon/files.cmakeUpdates include/header list to reference moved hostmisc/fx_ver.h.
src/native/corehost/nethost/CMakeLists.txtAdds minipal_objects to static lib link line.
src/native/corehost/fxr/staticlib/CMakeLists.txtAdds minipal_objects to static libhostfxr link line.
src/native/corehost/test/fx_ver/CMakeLists.txtUpdates include path for the relocated fx_ver.h.
src/native/corehost/hostmisc/trace.cppRemoved (replaced by trace.c).
src/native/corehost/fxr/fx_ver.hRemoved (replaced by hostmisc/fx_ver.h).

Copilot's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp Outdated
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Add a length parameter to index_of_non_numeric so the bounded digit-only
checks in try_stou and valid_identifier can share the same scan helper
instead of duplicating the [0-9] loop. The existing parse_internal call
passes (size_t)-1 to preserve the scan-until-'\0' behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment threadsrc/native/corehost/hostmisc/trace.c Outdated
Comment threadsrc/native/corehost/hostmisc/fx_ver.c Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
CopilotAI review requested due to automatic review settings June 11, 2026 21:26

CopilotAI 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's findings

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

Comment threadsrc/native/corehost/fxr/fx_ver.cpp
Comment threadsrc/native/corehost/fxr/fx_ver.cpp
@elinor-fung

Copy link
Copy Markdown
Member

/ba-g #129242

@elinor-fung
elinor-fung merged commit f5645e2 into mainJun 12, 2026
178 of 184 checks passed
@elinor-fung
elinor-fung deleted the copilot/hostmisc-c branch June 12, 2026 22:24
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview6 milestone Jun 17, 2026
elinor-fung added a commit that referenced this pull request Jun 22, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
elinor-fung added a commit that referenced this pull request Jun 22, 2026
Reconcile the apphost-in-C rewrite with the smaller C conversions that were
extracted from this branch and merged separately upstream:
- #128420 Convert corehost hostmisc trace and fx_ver to C
- #129480 Convert fxr_resolver and its hostmisc dependencies to C
Adopt upstream's now-merged C conversions (trace.c, fx_ver.c, fxr_resolver.c,
pal.unix.c/pal.windows.c, utils.c and their headers) and drop this branch's
redundant/divergent copies (hostmisc/fxr_resolver.c, pal.windows.c_impl.cpp,
hostmisc_c object library). Keep only the apphost-in-C delta on top:
apphost/apphost.c, apphost_hostfxr_resolver.{c,cpp,h}, dotnet/dotnet.cpp
(replacing corehost.cpp) and bundle_marker.c.
Adapt the apphost C layer to upstream's allocating C API (pal_get_own_executable_path,
pal_fullpath, utils_get_directory) and add the few apphost-only C helpers upstream
lacked: pal_load_library/unload_library/get_symbol/is_path_fully_qualified/utf8_to_palstr
(extern "C" wrappers in pal.windows.cpp/pal.unix.cpp) and utils_get_current_arch_name/
utils_get_host_version_description. Wire standalone apphost to link hostmisc+fxr_resolver
like dotnet, and singlefilehost to use apphost.c.
Validated: standalone apphost, dotnet, and singlefilehost all compile and link.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elinor-fungelinor-fung mentioned this pull request Jun 25, 2026
elinor-fung added a commit that referenced this pull request Jul 2, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
elinor-fung added a commit that referenced this pull request Jul 14, 2026
`libnethost` is shipped as static libraries for external consumption.
With #128420, it now includes
minipal_objects, which was compiled with LTCG, producing object files
that non-MSVC linkers such as lld-link reject with "is not a native COFF
file".
Disable interprocedural optimization on the host's copy of
minipal_objects. This mirrors the existing LTCG-disabling on libnethost
itself (#71056).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Split of #126367: converting the trace and fx_ver modules in
`src/native/corehost/hostmisc` from C++ to C, and reshaping
`pal`/`utils` for a C-callable surface.
These are pieces that both `apphost` and `nethost` would need (also,
`fxr_resolver`, but didn't include that yet). My thought is to get the
shared pieces in and then the `apphost` and `nethost` conversions with
their separate sets of complications can be iterated on in parallel.
- **trace**
- `trace.c` replaces `trace.cpp`
- `trace.h` exposes a C `trace_*` API with C++ inline forwarders.
- **fx_ver**
- `hostmisc/fx_ver.{c,h}` (moved from `fxr/`) implements the semver
parser in C
- `fxr/fx_ver.cpp` is now a thin C++ wrapper over `c_fx_ver_t`.
- This is left as we are currently consuming via the C++ surface. The
plan is to switch nethost and apphost to use the C version directly.
After that, will evaluate the others (hostfxr, hostpolicy) as their
usage is much more involved.
- **pal** / **utils**:
- `pal.h` / `utils.h` reorganized into a C-compatible section and a C++
`pal::` section under `#ifdef __cplusplus`.
- `pal.*.c` / `utils.c` provide implementations for functions needed for
trace and fx_ver. `pal.*.cpp` / `utils.cpp` versions of those functions
are wrappers around the C implementations.
- **build**
- `minipal` linked in for host binaries (`minipal_objects` for static
libraries)
**Windows x64 Release**
| Binary | Main | PR | Δ | % |
|--------------------|-----------:|-----------:|--------:|--------:|
| apphost.exe | 146,944 | 137,728 | −9,216 | −6.27% |
| comhost.dll | 175,616 | 166,400 | −9,216 | −5.25% |
| dotnet.exe | 148,992 | 135,168 | −13,824 | −9.28% |
| hostfxr.dll | 342,528 | 340,992 | −1,536 | −0.45% |
| hostpolicy.dll | 344,576 | 342,528 | −2,048 | −0.59% |
| ijwhost.dll | 119,296 | 109,056 | −10,240 | −8.58% |
| nethost.dll | 102,912 | 89,088 | −13,824 | −13.43% |
| singlefilehost.exe | 10,374,144 | 10,372,096 | −2,048 | −0.02% |
**Linux x64 Release**
| Binary | Main | PR | Δ | % |
|------------------|------------:|------------:|-------:|-------:|
| apphost | 74,544 | 71,792 | −2,752 | −3.69% |
| dotnet | 54,936 | 52,552 | −2,384 | −4.34% |
| libhostfxr.so | 321,280 | 320,352 | −928 | −0.29% |
| libhostpolicy.so | 306,704 | 305,552 | −1,152 | −0.38% |
| libnethost.so | 70,624 | 67,824 | −2,800 | −3.96% |
| singlefilehost | 10,790,224 | 10,789,264 | −960 | −0.01% |
Static libraries (`libhostfxr.a/lib` and `libnethost.a/lib`) do grow due
to including `minipal_objects` - consumers can (probably should) link
with dead code elimination.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
This is another slice of breaking up #126367. It continues the
conversion of the corehost stack from C++ to C, building on top of
#128420 (which converted `trace` and `fx_ver`). This converts
`fxr_resolver` and the `hostmisc` PAL/utils helpers that `fxr_resolver`
depends on.
- **`fxr_resolver`**
- `fxr_resolver.c` replaces most of `fxr_resolver.cpp`
- `fxr_resolver.h` has the C-compatible surface
- **pal** / **utils**
- Adds the implementations needed by `fxr_resolver`. - **Build wiring**
- Defines `CLR_CMAKE_TARGET_ARCH_UPPER` for an uppercase version of the
arch
**Windows x64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 136,704 | 124,416 | −12,288 | −8.99% |
| nethost | 87,552 | 71,680 | −15,872 | −18.13% |
| ijwhost | 108,032 | 94,208 | −13,824 | −12.80% |
| comhost | 165,376 | 151,552 | −13,824 | −8.36% |
| dotnet | 133,632 | 123,392 | −10,240 | −7.66% |
**macOS arm64 Release**
| Binary | Baseline | Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 116,384 | 95,232 | −21,152 | −18.17% |
| dotnet | 97,152 | 94,896 | −2,256 | −2.32% |
| libnethost.dylib | 114,304 | 92,368 | −21,936 | −19.19% |
**linux x64 Release**
| Binary | Baseline | This Branch | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| apphost | 73,896 | 49,248 | −24,648 | −33.4% |
| dotnet | 56,288 | 39,904 | −16,384 | −29.1% |
| libnethost.so | 68,024 | 43,376 | −24,648 | −36.2% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
Convert `nethost` to C. This builds on #128420 and #129480 to fully
convert `nethost` so it compiles and links as C-only — no C++ runtime
dependency.
- **pal**
- Add a C `pal_get_loaded_library` (look up an already-loaded library
without loading it). The C++ `pal::get_loaded_library` now delegates to
it.
- **fxr_resolver** - Convert the last C++-only piece, `try_get_existing_fxr`, to C.
- Remove the thin C++ wrappers in `fxr_resolver.cpp`
- Move `load_fxr_and_get_delegate` (used by `comhost` and `ijwhost`)
into its own header `load_fxr_and_get_delegate.h`
- **nethost**
- Replace `nethost.cpp` with `nethost.c` using the shared host bits that
have been converted to C. The RAII `error_writer_scope_t` is replaced by
manual save/restore of the error writer.
- **Build**
- Split `hostmisc` into C/C++ sources and add a C-only `hostmisc_c`
object library
**linux x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---|---|---|---|
| `libnethost.a` | 2,743,470 | 532,650 | -2,210,820 | -80.6% |
| `libnethost.so` | 43,376 | 35,072 | -8,304 | -19.1% |
**macOS arm64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|---:|---:|---:|---:|
| `libnethost.a` | 1,097,312 | 268,360 | −828,952 | −75.5% |
| `libnethost.dylib` | 92,368 | 89,088 | −3,280 | −3.6% |
**windows x64 Release**
| Binary | Baseline | PR | Δ bytes | Δ % |
|---|--:|--:|--:|--:|
| `libnethost.lib` | 2,951,176 | 1,677,420 | −1,273,756 | −43.2% |
| `nethost.dll` | 71,168 | 56,832 | −14,336 | −20.1% |
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 18, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@elinor-fung@AaronRobinsonMSFT