Skip to content

Commit 9cf89bf

Browse files
authored
EventPipe support for ProcessInfo (#87562)
* initial changes for process name * add support to get managedEntrypointAssemblyName * FB * FB2 * fix main merge issues * Using assembly location for coreclr per FB * FB * FB * FB
1 parent f9d6130 commit 9cf89bf

File tree

8 files changed

+101
-17
lines changed

8 files changed

+101
-17
lines changed

eng/pipelines/runtime.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ extends:
248248
extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml
249249
extraStepsParameters:
250250
creator: dotnet-bot
251-
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'
251+
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'
252252
liveLibrariesBuildConfig: Release
253253
testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
254254
extraVariablesTemplates:

src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp

Lines changed: 85 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
#include "holder.h"
2929
#include "SpinLock.h"
3030

31+
#ifndef DIRECTORY_SEPARATOR_CHAR
32+
#ifdef TARGET_UNIX
33+
#define DIRECTORY_SEPARATOR_CHAR '/'
34+
#else // TARGET_UNIX
35+
#define DIRECTORY_SEPARATOR_CHAR '\\'
36+
#endif // TARGET_UNIX
37+
#endif
38+
3139
#ifdef TARGET_UNIX
3240
// Per module (1 for NativeAOT), key that will be used to implement TLS in Unix
3341
pthread_key_t eventpipe_tls_key;
@@ -41,7 +49,6 @@ thread_local EventPipeAotThreadHolderTLS EventPipeAotThreadHolderTLS::g_threadHo
4149
ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle;
4250
CrstStatic _ep_rt_aot_config_lock;
4351

44-
ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line;
4552

4653
#ifndef TARGET_UNIX
4754
uint32_t *_ep_rt_aot_proc_group_offsets;
@@ -88,9 +95,63 @@ ep_rt_aot_sample_profiler_write_sampling_event_for_threads (
8895
const ep_char8_t *
8996
ep_rt_aot_entrypoint_assembly_name_get_utf8 (void)
9097
{
91-
// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
92-
// TODO: Implement EventPipe assembly name - return filename in nativeaot?
93-
return reinterpret_cast<const ep_char8_t*>("");
98+
// We are (intentionally for now) using the module name rather than entry assembly
99+
// 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
100+
static const ep_char8_t * entrypoint_assembly_name = nullptr;
101+
if (entrypoint_assembly_name == nullptr) {
102+
ep_char8_t * entrypoint_assembly_name_local;
103+
const TCHAR * wszModuleFileName = NULL;
104+
HANDLE moduleHandle = PalGetModuleHandleFromPointer((void*)&ep_rt_aot_entrypoint_assembly_name_get_utf8);
105+
if(PalGetModuleFileName(&wszModuleFileName, moduleHandle) == 0) {
106+
entrypoint_assembly_name_local = reinterpret_cast<ep_char8_t *>(malloc(1));
107+
if(entrypoint_assembly_name_local==NULL) {
108+
return NULL;
109+
}
110+
*entrypoint_assembly_name_local = '\0';
111+
}
112+
else {
113+
#ifdef HOST_WINDOWS
114+
const wchar_t* process_name_const = wcsrchr(wszModuleFileName, DIRECTORY_SEPARATOR_CHAR);
115+
if (process_name_const != NULL) {
116+
process_name_const++;
117+
}
118+
else {
119+
process_name_const = reinterpret_cast<const wchar_t *>(wszModuleFileName);
120+
}
121+
size_t len = -1;
122+
const wchar_t* extension = wcsrchr(process_name_const, '.');
123+
if (extension != NULL) {
124+
len = extension - process_name_const;
125+
}
126+
entrypoint_assembly_name_local = ep_rt_utf16_to_utf8_string(reinterpret_cast<const ep_char16_t *>(process_name_const), len);
127+
#else
128+
const ep_char8_t* process_name_const = strrchr(wszModuleFileName, DIRECTORY_SEPARATOR_CHAR);
129+
if (process_name_const != NULL) {
130+
process_name_const++;
131+
}
132+
else {
133+
process_name_const = reinterpret_cast<const ep_char8_t *>(wszModuleFileName);
134+
}
135+
size_t len = strlen(process_name_const);
136+
const ep_char8_t *extension = strrchr(process_name_const, '.');
137+
if (extension != NULL) {
138+
len = extension - process_name_const;
139+
}
140+
ep_char8_t* process_name = reinterpret_cast<ep_char8_t *>(malloc(len + 1));
141+
if (process_name == NULL) {
142+
return NULL;
143+
}
144+
memcpy(process_name, process_name_const, len);
145+
process_name[len] = '\0';
146+
entrypoint_assembly_name_local = reinterpret_cast<ep_char8_t*>(process_name);
147+
#endif // HOST_WINDOWS
148+
}
149+
150+
if (PalInterlockedCompareExchangePointer((void**)(&entrypoint_assembly_name), (void*)(entrypoint_assembly_name_local), nullptr) != nullptr)
151+
free(entrypoint_assembly_name_local);
152+
}
153+
154+
return entrypoint_assembly_name;
94155
}
95156

96157
const ep_char8_t *
@@ -101,6 +162,20 @@ ep_rt_aot_diagnostics_command_line_get (void)
101162
#ifdef TARGET_WINDOWS
102163
const ep_char16_t* command_line = reinterpret_cast<const ep_char16_t *>(::GetCommandLineW());
103164
return ep_rt_utf16_to_utf8_string(command_line, -1);
165+
#elif TARGET_LINUX
166+
FILE *cmdline_file = ::fopen("/proc/self/cmdline", "r");
167+
if (cmdline_file == nullptr)
168+
return "";
169+
170+
char *line = NULL;
171+
size_t line_len = 0;
172+
if (::getline (&line, &line_len, cmdline_file) == -1) {
173+
::fclose (cmdline_file);
174+
return "";
175+
}
176+
177+
::fclose (cmdline_file);
178+
return reinterpret_cast<const ep_char8_t*>(line);
104179
#else
105180
return "";
106181
#endif
@@ -388,10 +463,10 @@ ep_rt_aot_file_close (ep_rt_file_handle_t file_handle)
388463

389464
bool
390465
ep_rt_aot_file_write (
391-
ep_rt_file_handle_t file_handle,
392-
const uint8_t *buffer,
393-
uint32_t bytes_to_write,
394-
uint32_t *bytes_written)
466+
ep_rt_file_handle_t file_handle,
467+
const uint8_t *buffer,
468+
uint32_t bytes_to_write,
469+
uint32_t *bytes_written)
395470
{
396471
#ifdef TARGET_WINDOWS
397472
return ::WriteFile (file_handle, buffer, bytes_to_write, reinterpret_cast<LPDWORD>(bytes_written), NULL) != FALSE;
@@ -722,12 +797,12 @@ void ep_rt_aot_lock_requires_lock_not_held (const ep_rt_lock_handle_t *lock)
722797
void ep_rt_aot_spin_lock_requires_lock_held (const ep_rt_spin_lock_handle_t *spin_lock)
723798
{
724799
EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock));
725-
EP_ASSERT (spin_lock->lock->OwnedByCurrentThread ());
800+
EP_ASSERT (spin_lock->lock->OwnedByCurrentThread ());
726801
}
727802

728803
void ep_rt_aot_spin_lock_requires_lock_not_held (const ep_rt_spin_lock_handle_t *spin_lock)
729804
{
730-
EP_ASSERT (spin_lock->lock == NULL || !spin_lock->lock->OwnedByCurrentThread ());
805+
EP_ASSERT (spin_lock->lock == NULL || !spin_lock->lock->OwnedByCurrentThread ());
731806
}
732807

733808
#endif /* EP_CHECKED_BUILD */

src/tests/Common/CoreCLRTestLibrary/Utilities.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public static bool IsWindowsIoTCore
9595
public static bool IsMonoRuntime => Type.GetType("Mono.RuntimeStructs") != null;
9696
public static bool IsNotMonoRuntime => !IsMonoRuntime;
9797
public static bool IsNativeAot => IsNotMonoRuntime && !IsReflectionEmitSupported;
98+
99+
public static bool HasAssemblyFiles => !string.IsNullOrEmpty(typeof(Utilities).Assembly.Location);
100+
public static bool IsSingleFile => !HasAssemblyFiles;
101+
98102
#if NETCOREAPP
99103
public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported;
100104
public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported;

src/tests/tracing/eventpipe/diagnosticport/diagnosticport.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,10 +403,9 @@ public static async Task<bool> TEST_CanGetProcessInfo2WhileSuspended()
403403
}
404404
else if (TestLibrary.Utilities.IsNativeAot)
405405
{
406-
// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
407-
// https://github.com/dotnet/runtime/issues/83051
408-
// NativeAOT currently always returns empty string
409-
Utils.Assert(processInfo2.ManagedEntrypointAssemblyName == string.Empty);
406+
string expectedName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
407+
Utils.Assert(expectedName.Equals(processInfo2.ManagedEntrypointAssemblyName),
408+
$"ManagedEntrypointAssemblyName must match. Expected: {expectedName}, Received: {processInfo2.ManagedEntrypointAssemblyName}");
410409
}
411410
else
412411
{

src/tests/tracing/eventpipe/processinfo/processinfo.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ public static int Main()
149149
// /path/to/corerun /path/to/processinfo.dll
150150
// or
151151
// "C:\path\to\CoreRun.exe" C:\path\to\processinfo.dll
152-
string currentProcessCommandLine = $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}";
152+
string currentProcessCommandLine = TestLibrary.Utilities.IsSingleFile
153+
? currentProcess.MainModule.FileName
154+
: $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}";
153155
string receivedCommandLine = NormalizeCommandLine(commandLine);
154156
Utils.Assert(currentProcessCommandLine.Equals(receivedCommandLine, StringComparison.OrdinalIgnoreCase), $"CommandLine must match current process. Expected: {currentProcessCommandLine}, Received: {receivedCommandLine} (original: {commandLine})");
155157
}

src/tests/tracing/eventpipe/processinfo/processinfo.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
<ItemGroup>
1616
<Compile Include="$(MSBuildProjectName).cs" />
1717
<ProjectReference Include="../common/common.csproj" />
18+
<ProjectReference Include="$(TestSourceDir)Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj" />
1819
</ItemGroup>
1920
</Project>

src/tests/tracing/eventpipe/processinfo2/processinfo2.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ public static int Main()
150150
// /path/to/corerun /path/to/processinfo.dll
151151
// or
152152
// "C:\path\to\CoreRun.exe" C:\path\to\processinfo.dll
153-
string currentProcessCommandLine = $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}";
153+
string currentProcessCommandLine = TestLibrary.Utilities.IsSingleFile
154+
? currentProcess.MainModule.FileName
155+
: $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}";
154156
string receivedCommandLine = NormalizeCommandLine(commandLine);
155157
Utils.Assert(currentProcessCommandLine.Equals(receivedCommandLine, StringComparison.OrdinalIgnoreCase), $"CommandLine must match current process. Expected: {currentProcessCommandLine}, Received: {receivedCommandLine} (original: {commandLine})");
156158
}

src/tests/tracing/eventpipe/processinfo2/processinfo2.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
<ItemGroup>
1616
<Compile Include="$(MSBuildProjectName).cs" />
1717
<ProjectReference Include="../common/common.csproj" />
18+
<ProjectReference Include="$(TestSourceDir)Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj" />
1819
</ItemGroup>
1920
</Project>

0 commit comments

Comments
 (0)