diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 65769749869b4..4d75c6feeec7a 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -248,7 +248,7 @@ extends: extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml extraStepsParameters: creator: dotnet-bot - testBuildArgs: 'nativeaot tree ";nativeaot;Loader;Interop;tracing/eventpipe/config;tracing/eventpipe/diagnosticport;tracing/eventpipe/reverse;tracing/eventpipe/processenvironment;tracing/eventpipe/simpleruntimeeventvalidation;" test tracing/eventcounter/runtimecounters.csproj /p:BuildNativeAotFrameworkObjects=true' + testBuildArgs: 'nativeaot tree ";nativeaot;Loader;Interop;tracing/eventpipe/config;tracing/eventpipe/diagnosticport;tracing/eventpipe/reverse;tracing/eventpipe/processenvironment;tracing/eventpipe/simpleruntimeeventvalidation;tracing/eventpipe/processinfo2;" test tracing/eventcounter/runtimecounters.csproj /p:BuildNativeAotFrameworkObjects=true' liveLibrariesBuildConfig: Release testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) extraVariablesTemplates: diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 90d2c27523c28..944d7714880b9 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -28,6 +28,14 @@ #include "holder.h" #include "SpinLock.h" +#ifndef DIRECTORY_SEPARATOR_CHAR +#ifdef TARGET_UNIX +#define DIRECTORY_SEPARATOR_CHAR '/' +#else // TARGET_UNIX +#define DIRECTORY_SEPARATOR_CHAR '\\' +#endif // TARGET_UNIX +#endif + #ifdef TARGET_UNIX // Per module (1 for NativeAOT), key that will be used to implement TLS in Unix pthread_key_t eventpipe_tls_key; @@ -41,7 +49,6 @@ thread_local EventPipeAotThreadHolderTLS EventPipeAotThreadHolderTLS::g_threadHo ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; CrstStatic _ep_rt_aot_config_lock; -ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line; #ifndef TARGET_UNIX uint32_t *_ep_rt_aot_proc_group_offsets; @@ -88,9 +95,63 @@ ep_rt_aot_sample_profiler_write_sampling_event_for_threads ( const ep_char8_t * ep_rt_aot_entrypoint_assembly_name_get_utf8 (void) { - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // TODO: Implement EventPipe assembly name - return filename in nativeaot? - return reinterpret_cast(""); + // We are (intentionally for now) using the module name rather than entry assembly + // Cannot use __cpp_threadsafe_static_init feature since it will bring in the C++ runtime and need to use threadsafe way to initialize entrypoint_assembly_name + static const ep_char8_t * entrypoint_assembly_name = nullptr; + if (entrypoint_assembly_name == nullptr) { + ep_char8_t * entrypoint_assembly_name_local; + const TCHAR * wszModuleFileName = NULL; + HANDLE moduleHandle = PalGetModuleHandleFromPointer((void*)&ep_rt_aot_entrypoint_assembly_name_get_utf8); + if(PalGetModuleFileName(&wszModuleFileName, moduleHandle) == 0) { + entrypoint_assembly_name_local = reinterpret_cast(malloc(1)); + if(entrypoint_assembly_name_local==NULL) { + return NULL; + } + *entrypoint_assembly_name_local = '\0'; + } + else { +#ifdef HOST_WINDOWS + const wchar_t* process_name_const = wcsrchr(wszModuleFileName, DIRECTORY_SEPARATOR_CHAR); + if (process_name_const != NULL) { + process_name_const++; + } + else { + process_name_const = reinterpret_cast(wszModuleFileName); + } + size_t len = -1; + const wchar_t* extension = wcsrchr(process_name_const, '.'); + if (extension != NULL) { + len = extension - process_name_const; + } + entrypoint_assembly_name_local = ep_rt_utf16_to_utf8_string(reinterpret_cast(process_name_const), len); +#else + const ep_char8_t* process_name_const = strrchr(wszModuleFileName, DIRECTORY_SEPARATOR_CHAR); + if (process_name_const != NULL) { + process_name_const++; + } + else { + process_name_const = reinterpret_cast(wszModuleFileName); + } + size_t len = strlen(process_name_const); + const ep_char8_t *extension = strrchr(process_name_const, '.'); + if (extension != NULL) { + len = extension - process_name_const; + } + ep_char8_t* process_name = reinterpret_cast(malloc(len + 1)); + if (process_name == NULL) { + return NULL; + } + memcpy(process_name, process_name_const, len); + process_name[len] = '\0'; + entrypoint_assembly_name_local = reinterpret_cast(process_name); +#endif // HOST_WINDOWS + } + + if (PalInterlockedCompareExchangePointer((void**)(&entrypoint_assembly_name), (void*)(entrypoint_assembly_name_local), nullptr) != nullptr) + free(entrypoint_assembly_name_local); + } + + return entrypoint_assembly_name; } const ep_char8_t * @@ -101,6 +162,20 @@ ep_rt_aot_diagnostics_command_line_get (void) #ifdef TARGET_WINDOWS const ep_char16_t* command_line = reinterpret_cast(::GetCommandLineW()); return ep_rt_utf16_to_utf8_string(command_line, -1); +#elif TARGET_LINUX + FILE *cmdline_file = ::fopen("/proc/self/cmdline", "r"); + if (cmdline_file == nullptr) + return ""; + + char *line = NULL; + size_t line_len = 0; + if (::getline (&line, &line_len, cmdline_file) == -1) { + ::fclose (cmdline_file); + return ""; + } + + ::fclose (cmdline_file); + return reinterpret_cast(line); #else return ""; #endif @@ -388,10 +463,10 @@ ep_rt_aot_file_close (ep_rt_file_handle_t file_handle) bool ep_rt_aot_file_write ( - ep_rt_file_handle_t file_handle, - const uint8_t *buffer, - uint32_t bytes_to_write, - uint32_t *bytes_written) + ep_rt_file_handle_t file_handle, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) { #ifdef TARGET_WINDOWS return ::WriteFile (file_handle, buffer, bytes_to_write, reinterpret_cast(bytes_written), NULL) != FALSE; @@ -722,12 +797,12 @@ void ep_rt_aot_lock_requires_lock_not_held (const ep_rt_lock_handle_t *lock) void ep_rt_aot_spin_lock_requires_lock_held (const ep_rt_spin_lock_handle_t *spin_lock) { EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); - EP_ASSERT (spin_lock->lock->OwnedByCurrentThread ()); + EP_ASSERT (spin_lock->lock->OwnedByCurrentThread ()); } void ep_rt_aot_spin_lock_requires_lock_not_held (const ep_rt_spin_lock_handle_t *spin_lock) { - EP_ASSERT (spin_lock->lock == NULL || !spin_lock->lock->OwnedByCurrentThread ()); + EP_ASSERT (spin_lock->lock == NULL || !spin_lock->lock->OwnedByCurrentThread ()); } #endif /* EP_CHECKED_BUILD */ diff --git a/src/tests/Common/CoreCLRTestLibrary/Utilities.cs b/src/tests/Common/CoreCLRTestLibrary/Utilities.cs index a4f5c78796733..c298a46abca87 100644 --- a/src/tests/Common/CoreCLRTestLibrary/Utilities.cs +++ b/src/tests/Common/CoreCLRTestLibrary/Utilities.cs @@ -95,6 +95,10 @@ public static bool IsWindowsIoTCore public static bool IsMonoRuntime => Type.GetType("Mono.RuntimeStructs") != null; public static bool IsNotMonoRuntime => !IsMonoRuntime; public static bool IsNativeAot => IsNotMonoRuntime && !IsReflectionEmitSupported; + + public static bool HasAssemblyFiles => !string.IsNullOrEmpty(typeof(Utilities).Assembly.Location); + public static bool IsSingleFile => !HasAssemblyFiles; + #if NETCOREAPP public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported; public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported; diff --git a/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs index a1c08d4f1b9f5..7e2edfc3896fe 100644 --- a/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs +++ b/src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs @@ -403,10 +403,9 @@ public static async Task TEST_CanGetProcessInfo2WhileSuspended() } else if (TestLibrary.Utilities.IsNativeAot) { - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // https://github.com/dotnet/runtime/issues/83051 - // NativeAOT currently always returns empty string - Utils.Assert(processInfo2.ManagedEntrypointAssemblyName == string.Empty); + string expectedName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; + Utils.Assert(expectedName.Equals(processInfo2.ManagedEntrypointAssemblyName), + $"ManagedEntrypointAssemblyName must match. Expected: {expectedName}, Received: {processInfo2.ManagedEntrypointAssemblyName}"); } else { diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.cs b/src/tests/tracing/eventpipe/processinfo/processinfo.cs index a62865bf2dff8..4f0d6133cf1db 100644 --- a/src/tests/tracing/eventpipe/processinfo/processinfo.cs +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.cs @@ -149,7 +149,9 @@ public static int Main() // /path/to/corerun /path/to/processinfo.dll // or // "C:\path\to\CoreRun.exe" C:\path\to\processinfo.dll - string currentProcessCommandLine = $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}"; + string currentProcessCommandLine = TestLibrary.Utilities.IsSingleFile + ? currentProcess.MainModule.FileName + : $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}"; string receivedCommandLine = NormalizeCommandLine(commandLine); Utils.Assert(currentProcessCommandLine.Equals(receivedCommandLine, StringComparison.OrdinalIgnoreCase), $"CommandLine must match current process. Expected: {currentProcessCommandLine}, Received: {receivedCommandLine} (original: {commandLine})"); } diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj index d4947c794dceb..2c913f467d9e2 100644 --- a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj @@ -15,5 +15,6 @@ + diff --git a/src/tests/tracing/eventpipe/processinfo2/processinfo2.cs b/src/tests/tracing/eventpipe/processinfo2/processinfo2.cs index 0c04dd3caef87..589af8d1aa49f 100644 --- a/src/tests/tracing/eventpipe/processinfo2/processinfo2.cs +++ b/src/tests/tracing/eventpipe/processinfo2/processinfo2.cs @@ -150,7 +150,9 @@ public static int Main() // /path/to/corerun /path/to/processinfo.dll // or // "C:\path\to\CoreRun.exe" C:\path\to\processinfo.dll - string currentProcessCommandLine = $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}"; + string currentProcessCommandLine = TestLibrary.Utilities.IsSingleFile + ? currentProcess.MainModule.FileName + : $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}"; string receivedCommandLine = NormalizeCommandLine(commandLine); Utils.Assert(currentProcessCommandLine.Equals(receivedCommandLine, StringComparison.OrdinalIgnoreCase), $"CommandLine must match current process. Expected: {currentProcessCommandLine}, Received: {receivedCommandLine} (original: {commandLine})"); } diff --git a/src/tests/tracing/eventpipe/processinfo2/processinfo2.csproj b/src/tests/tracing/eventpipe/processinfo2/processinfo2.csproj index d4947c794dceb..2c913f467d9e2 100644 --- a/src/tests/tracing/eventpipe/processinfo2/processinfo2.csproj +++ b/src/tests/tracing/eventpipe/processinfo2/processinfo2.csproj @@ -15,5 +15,6 @@ +