Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, '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" + '
Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, '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('^' + ".*" + ' Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, '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('^' + ".*" + ' Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, '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" + ' Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, '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('^' + ".*" + ' Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, '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); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Fix NativeAOT tracing tests crash and mark as incompatible by Copilot · Pull Request #123553 · dotnet/runtime · GitHub
Skip to content

Fix NativeAOT tracing tests crash and mark as incompatible - #123553

Merged
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot
Jan 28, 2026
Merged

Fix NativeAOT tracing tests crash and mark as incompatible#123553
mdh1418 merged 27 commits into
mainfrom
copilot/fix-runtime-tests-nativeaot

Conversation

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

NativeAOT tracing tests in src/tests/tracing/userevents/* crash with ArgumentNullException in ResolveRecordTracePath because Assembly.Location returns empty string in NativeAOT builds. Additionally, NativeAOT has a different directory layout with executables placed in a native/ subdirectory, and NativeAOT tests run executables directly without using corerun.

This PR fixes the crash by implementing directory-based runtime detection and simplifying the API to remove the unreliable Assembly.Location dependency. After fixing the crash, tests hit the expected failure due to record-trace's limitation with NativeAOT, so they are marked as NativeAotIncompatible with reference to tracking issue #123697.

Changes Made

  • Removed Assembly.Location dependency: Removed traceeAssemblyPath parameter from UserEventsTestRunner.Run() API - tests no longer pass unreliable Assembly.Location
  • Directory-based NativeAOT detection: Detect NativeAOT by checking if AppContext.BaseDirectory ends with "native" subdirectory using Path.GetFileName()
  • Normalized directory structure: Both runtimes now use .../scenario/scenario/ as the scenario directory
    • CoreCLR: AppContext.BaseDirectory = .../scenario/scenario/
    • NativeAOT: AppContext.BaseDirectory = .../scenario/scenario/native/, navigate up one level to normalize
  • Directory validation: Added validation that directory name matches scenario name for safety
  • Simplified path resolution: Both runtimes now use identical path resolution logic (2 levels up to userevents root)
  • Assembly path construction: For CoreCLR, construct assembly path as {scenarioName}.dll from scenario directory
  • Unified tracee execution: Use Environment.ProcessPath for both runtimes (returns corerun for CoreCLR, native executable for NativeAOT)
    • CoreCLR: Arguments use {userEventsScenarioDir}/{scenarioName}.dll and tracee
    • NativeAOT: Arguments use tracee only
  • Use ArgumentList: Use ProcessStartInfo.ArgumentList for both record-trace and tracee processes to properly handle paths with spaces
  • Updated all test files: Modified all 5 test files (basic, custommetadata, activity, multithread, managedevent) to remove Assembly.Location parameter
  • Mark as NativeAotIncompatible: Added Directory.Build.props to mark tests as NativeAotIncompatible with reference to tracking issue [NativeAOT] Profilers unable to trace userevents from NativeAOT apps #123697
  • Code quality: Removed trailing whitespace and improved argument logging

Technical Notes

NativeAOT Detection and Normalization:

stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=false;stringuserEventsScenarioDir=baseDir;if(Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native"){// NativeAOT places its compiled test executables under a 'native' subdirectory.isNativeAot=true;userEventsScenarioDir=Path.GetFullPath(Path.Combine(baseDir,".."));}// Validate directory name matches scenario nameif(Path.GetFileName(userEventsScenarioDir.TrimEnd(Path.DirectorySeparatorChar))!=scenarioName){Console.Error.WriteLine("Could not resolve the userevents test scenario directory.");return-1;}

Path Resolution (identical for both runtimes):

  • userEventsScenarioDir = .../tracing/userevents/<scenario>/<scenario>/
  • Record-trace: Navigate up 2 levels → .../tracing/userevents/common/userevents_common/record-trace
  • Script: {userEventsScenarioDir}/{scenarioName}.script

Process Execution (using ArgumentList):

// record-tracerecordTraceStartInfo.ArgumentList.Add("-n");recordTraceStartInfo.ArgumentList.Add(recordTracePath);recordTraceStartInfo.ArgumentList.Add("--script-file");recordTraceStartInfo.ArgumentList.Add(scriptFilePath);// ... etc// traceeif(isNativeAot){traceeStartInfo.ArgumentList.Add("tracee");}else{stringassemblyPath=Path.Combine(userEventsScenarioDir,$"{scenarioName}.dll");traceeStartInfo.ArgumentList.Add(assemblyPath);traceeStartInfo.ArgumentList.Add("tracee");}

Tracee Execution:

  • Use Environment.ProcessPath for both (returns corerun for CoreCLR, native exe for NativeAOT)
  • CoreCLR tests: corerun {userEventsScenarioDir}/{scenarioName}.dll tracee
  • NativeAOT tests: {native-executable} tracee

Why Tests Remain NativeAotIncompatible:

The crash is fixed, allowing tests to progress further on NativeAOT. However, tests still fail at the expected point due to record-trace's limitation with NativeAOT process discovery. See #123697 for details on the tracking issue.

The tests are marked as NativeAotIncompatible in Directory.Build.props with a reference to the tracking issue until record-trace adds support for NativeAOT process discovery.

// Before: relied on Assembly.Location which is unreliable in NativeAOTpublicstaticintRun(string[]args,stringscenarioName,stringtraceeAssemblyPath, ...){
...
return RunOrchestrator(scenarioName,traceeAssemblyPath, ...);}// In tests:UserEventsTestRunner.Run(args,"basic",typeof(Basic).Assembly.Location, ...);// After: uses directory-based detection, no Assembly.Location neededpublicstaticintRun(string[]args,stringscenarioName, ...){
...
return RunOrchestrator(scenarioName, ...);}// In tests (cleaner API):UserEventsTestRunner.Run(args,"basic", ...);// Runtime detection in RunOrchestrator:stringbaseDir=AppContext.BaseDirectory;boolisNativeAot=Path.GetFileName(baseDir.TrimEnd(Path.DirectorySeparatorChar))=="native";stringuserEventsScenarioDir=isNativeAot?Path.GetFullPath(Path.Combine(baseDir,"..")):baseDir;
Original prompt

Can you repro that all src/tests/tracing/userevents/* runtime tests are failing for NativeAOT? See #123552. After reproing, can you fix the Record-Trace path resolution? Afterwards can you check whether the TMPDIR being set will fix the diagnostic port discovery for NativeAOT apps given microsoft/one-collect#226, I'm guessing it will still fail.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 3 commits January 23, 2026 17:39
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title [WIP] Repro failing runtime tests for NativeAOT and fix Record-Trace resolutionFix NativeAOT tracing test crashes from null Assembly.LocationJan 23, 2026
CopilotAI requested a review from mdh1418January 23, 2026 17:43
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
@jkotas

Copy link
Copy Markdown
Member

@copilot Please revert #123541 as part of this PR.

davidwrightonand others added 5 commits January 23, 2026 22:00
…ling to actually tail call (#123513)
call.tail in the interpreter isn't guaranteed to tail-call in some
cases, so we need to put in a ret instruction after the tail-call to
ensure that the runtime doesn't execute invalid code. The code for doing
a ret is extracted into a helper routine, and now called from both the
CEE_JMP and CEE_RET pathways. The only change made to the code was to
unify where the ip adjustment was to not happen in the EmitRet logic and
instead keep it all in the same place in CEE_RET handling case.
This fixes these test cases on Windows Arm64
JIT/Directed/pinvoke/jump
JIT/Directed/pinvoke/tail_pinvoke
These are all crashing:
```
11:31:58.741 Running test: tracing/userevents/custommetadata/custommetadata/custommetadata.cmd
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
at System.ArgumentNullException.Throw(String)
at System.IO.Path.Combine(String, String, String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.ResolveRecordTracePath(String)
at Tracing.UserEvents.Tests.Common.UserEventsTestRunner.RunOrchestrator(String, String, Func`2, Int32, Int32)
at Tracing.UserEvents.Tests.CustomMetadata.CustomMetadata.Main(String[] args)
```
Test started running with #123112
Cc @dotnet/ilc-contrib
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please revert #123541 as part of this PR.

Done. Reverted PR #123541 by deleting Directory.Build.props in commit 8339d8e.

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing test crashes from null Assembly.LocationFix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundJan 23, 2026
CopilotAI requested a review from jkotasJanuary 23, 2026 22:04
@jkotas

Copy link
Copy Markdown
Member

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mdh1418

Copy link
Copy Markdown
Member

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. tracing/userevents/basic/basic/native/basic instead of the test runner's expectation of tracing/userevents/basic/basic/basic.dll.

Instead of using typeof(<scenario class>).Assembly.Location in each of the userevents tests, can we instead conform the UserEventsTestRunner to use the AppContext.BaseDirectory, and resolve the record-trace executable and scenario script from there? The record-trace executable will live under the test shared common directory which is tracing/userevents/common/userevents_common/record-trace, and each scenario's script lives just above that native subdirectory, e.g. tracing/userevents/basic/basic/basic.script.

Afterwards can you run the /azp run runtime-nativeaot-outerloop pipeline by commenting that independently.

…OT compatibility
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot on NativeAOT, it looks like the runtime tests layout is a bit different as they will embed an extra native subdirectory to hold the scenario's nativeAOT asset (assembly?).
e.g. `tracing/us...

Updated to use AppContext.BaseDirectory instead of Assembly.Location. The traceeAssemblyPath parameter has been removed from UserEventsTestRunner.Run(), and all test files now simply pass the scenario name. Path resolution now works correctly for both CoreCLR and NativeAOT layouts. Changes committed in 9bd0752.

CopilotAI changed the title Fix NativeAOT tracing test crashes and revert NativeAotIncompatible workaroundFix NativeAOT tracing tests using AppContext.BaseDirectoryJan 23, 2026
CopilotAI changed the title Fix NativeAOT tracing tests using directory-based runtime detectionFix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationJan 28, 2026
CopilotAI requested a review from mdh1418January 28, 2026 00:04
@mdh1418
mdh1418 marked this pull request as ready for review January 28, 2026 00:33
CopilotAI review requested due to automatic review settings January 28, 2026 00:33

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

Fixes a NativeAOT crash in tracing/userevents tests caused by reliance on Assembly.Location (empty in NativeAOT), and then marks the tests as NativeAotIncompatible due to a known record-trace limitation.

Changes:

  • Simplified UserEventsTestRunner.Run API by removing the traceeAssemblyPath parameter and switching to AppContext.BaseDirectory-based layout resolution (including native/ normalization).
  • Updated all userevents scenarios to call the new UserEventsTestRunner.Run signature (no Assembly.Location).
  • Documented and enforced NativeAOT incompatibility for these tests via Directory.Build.props.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/tests/tracing/userevents/common/UserEventsTestRunner.csRemoves Assembly.Location dependency; adds directory-based NativeAOT detection and unified tracee launching.
src/tests/tracing/userevents/basic/basic.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/activity/activity.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/custommetadata/custommetadata.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/multithread/multithread.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/managedevent/managedevent.csUpdates scenario runner invocation to new API (drops Assembly.Location).
src/tests/tracing/userevents/Directory.Build.propsMarks tests as NativeAotIncompatible with explanatory comment about record-trace limitations.

Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/common/UserEventsTestRunner.cs Outdated
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

- Use ProcessStartInfo.ArgumentList instead of string concatenation to properly
handle paths with spaces
- Remove trailing whitespace from blank lines in both code and XML comments
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>

CopilotAI commented Jan 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot apply changes based on the comments in this thread

Applied all review feedback in commit a770aec:

  • Changed to use ArgumentList instead of string concatenation for proper handling of paths with spaces
  • Removed trailing whitespace from blank lines in both code and XML comments

CopilotAIand others added 2 commits January 28, 2026 00:58
When using ArgumentList, the Arguments property returns empty string.
Use string.Join to display the actual arguments being passed.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Apply ArgumentList to recordTraceStartInfo for consistency with
traceeStartInfo and to properly handle paths with spaces.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
Replace detailed explanation with simple reference to tracking issue.
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
CopilotAI changed the title Fix NativeAOT tracing tests crash and mark as incompatible due to record-trace limitationFix NativeAOT tracing tests crash and mark as incompatibleJan 28, 2026
Comment threadsrc/tests/tracing/userevents/Directory.Build.props Outdated
@mdh1418

Copy link
Copy Markdown
Member

/ba-g "The failures on linux-x64/osx-x64 are #123667, the failure on wasm is linked by build-analysis, the failure on windows arm64 is a CI availability issue, but since these changes only affect tests that don't run on windows, this PR doesn't affect win-arm64 lanes"

@mdh1418
mdh1418 merged commit fa45d5a into mainJan 28, 2026
72 of 78 checks passed
@mdh1418
mdh1418 deleted the copilot/fix-runtime-tests-nativeaot branch January 28, 2026 21:25
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Feb 28, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Tests][NativeAOT] UserEvents Tests failing to discover Record-Trace path

8 participants

@jkotas@mdh1418@am11@stephentoub@davidwrighton@MichalStrehovsky