#ifdef TARGET_UNIX
-typedef char TCHAR;
-#define _T(s) s
-
-#else
-
-#ifndef _INC_WINDOWS
-typedef wchar_t TCHAR;
-#define _T(s) L##s
-#endif
-
-#endif
-
-#ifdef TARGET_UNIX
-
class EEThreadId
{
pthread_t m_id;
#include <sal.h>
#include <stdarg.h>
-#include "gcenv.structs.h"
+#include "gcenv.structs.h" // CRITICAL_SECTION
#include "IntrinsicConstants.h"
+#include "PalRedhawkCommon.h"
#ifndef PAL_REDHAWK_INCLUDED
#define PAL_REDHAWK_INCLUDED
#endif // !_MSC_VER
#ifndef _INC_WINDOWS
-//#ifndef DACCESS_COMPILE
// There are some fairly primitive type definitions below but don't pull them into the rest of Redhawk unless
// we have to (in which case these definitions will move to CommonTypes.h).
#ifdef TARGET_UNIX
#define __stdcall
+typedef char TCHAR;
+#define _T(s) s
+#else
+typedef wchar_t TCHAR;
+#define _T(s) L##s
#endif
-#ifndef __GCENV_BASE_INCLUDED__
-#define CALLBACK __stdcall
-#define WINAPI __stdcall
-#define WINBASEAPI __declspec(dllimport)
-#endif //!__GCENV_BASE_INCLUDED__
-
#ifdef TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '/'
#else // TARGET_UNIX
#define DECLARE_HANDLE(_name) typedef HANDLE _name
-// defined in gcrhenv.cpp
-bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount);
-
struct FILETIME
{
uint32_t dwLowDateTime;
#define NULL_AREA_SIZE (64*1024)
#endif
-//#endif // !DACCESS_COMPILE
#endif // !_INC_WINDOWS
#ifndef DACCESS_COMPILE
#ifndef _INC_WINDOWS
-#ifndef __GCENV_BASE_INCLUDED__
+#ifndef TRUE
#define TRUE 1
+#endif
+#ifndef FALSE
#define FALSE 0
-#endif // !__GCENV_BASE_INCLUDED__
+#endif
#define INVALID_HANDLE_VALUE ((HANDLE)(intptr_t)-1)
#ifdef FEATURE_ETW
REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalEventEnabled(REGHANDLE regHandle, _In_ const EVENT_DESCRIPTOR* eventDescriptor);
+REDHAWK_PALIMPORT uint32_t REDHAWK_PALAPI PalEventRegister(const GUID * arg1, void * arg2, void * arg3, REGHANDLE * arg4);
+REDHAWK_PALIMPORT uint32_t REDHAWK_PALAPI PalEventUnregister(REGHANDLE arg1);
+REDHAWK_PALIMPORT uint32_t REDHAWK_PALAPI PalEventWrite(REGHANDLE arg1, const EVENT_DESCRIPTOR * arg2, uint32_t arg3, EVENT_DATA_DESCRIPTOR * arg4);
#endif
REDHAWK_PALIMPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer);
REDHAWK_PALIMPORT void PalPrintFatalError(const char* message);
+REDHAWK_PALIMPORT char* PalCopyTCharAsChar(const TCHAR* toCopy);
+
#ifdef TARGET_UNIX
REDHAWK_PALIMPORT int32_t __cdecl _stricmp(const char *string1, const char *string2);
#endif // TARGET_UNIX
EnterCriticalSection(arg1);
}
-extern "C" uint32_t __stdcall EventRegister(const GUID *, void *, void *, REGHANDLE *);
-inline uint32_t PalEventRegister(const GUID * arg1, void * arg2, void * arg3, REGHANDLE * arg4)
-{
- return EventRegister(arg1, arg2, arg3, arg4);
-}
-
-extern "C" uint32_t __stdcall EventUnregister(REGHANDLE);
-inline uint32_t PalEventUnregister(REGHANDLE arg1)
-{
- return EventUnregister(arg1);
-}
-
-extern "C" uint32_t __stdcall EventWrite(REGHANDLE, const EVENT_DESCRIPTOR *, uint32_t, EVENT_DATA_DESCRIPTOR *);
-inline uint32_t PalEventWrite(REGHANDLE arg1, const EVENT_DESCRIPTOR * arg2, uint32_t arg3, EVENT_DATA_DESCRIPTOR * arg4)
-{
- return EventWrite(arg1, arg2, arg3, arg4);
-}
-
extern "C" void __stdcall FlushProcessWriteBuffers();
inline void PalFlushProcessWriteBuffers()
{
#include <string.h>
-bool RhConfig::ReadConfigValue(_In_z_ const char *name, uint64_t* pValue, bool decimal)
+#define DOTNET_PREFIX _T("DOTNET_")
+#define DOTNET_PREFIX_LEN STRING_LENGTH(DOTNET_PREFIX)
+
+namespace
+{
+ void GetEnvironmentConfigName(const char* name, TCHAR* buffer, uint32_t bufferSize)
+ {
+ assert(DOTNET_PREFIX_LEN + strlen(name) < bufferSize);
+ memcpy(buffer, DOTNET_PREFIX, (DOTNET_PREFIX_LEN) * sizeof(TCHAR));
+ #ifdef TARGET_WINDOWS
+ size_t nameLen = strlen(name);
+ for (size_t i = 0; i < nameLen; i++)
+ {
+ buffer[DOTNET_PREFIX_LEN + i] = name[i];
+ }
+ buffer[DOTNET_PREFIX_LEN + nameLen] = '\0';
+ #else
+ strcpy(buffer + DOTNET_PREFIX_LEN, name);
+ #endif
+ }
+}
+
+bool RhConfig::Environment::TryGetBooleanValue(const char* name, bool* value)
+{
+ uint64_t intValue;
+ if (!TryGetIntegerValue(name, &intValue))
+ return false;
+
+ *value = intValue != 0;
+ return true;
+}
+
+bool RhConfig::Environment::TryGetIntegerValue(const char* name, uint64_t* value, bool decimal)
{
+ TCHAR variableName[64];
+ GetEnvironmentConfigName(name, variableName, ARRAY_SIZE(variableName));
+
TCHAR buffer[CONFIG_VAL_MAXLEN + 1]; // hex digits plus a nul terminator.
const uint32_t cchBuffer = ARRAY_SIZE(buffer);
+ uint32_t cchResult = PalGetEnvironmentVariable(variableName, buffer, cchBuffer);
+ if (cchResult == 0 || cchResult >= cchBuffer)
+ return false;
- uint32_t cchResult = 0;
- TCHAR variableName[64] = _T("DOTNET_");
- assert(ARRAY_SIZE("DOTNET_") - 1 + strlen(name) < ARRAY_SIZE(variableName));
-#ifdef TARGET_WINDOWS
- for (size_t i = 0; i < strlen(name); i++)
+ // Environment variable was set. Convert it to an integer.
+ uint64_t uiResult = 0;
+ for (uint32_t i = 0; i < cchResult; i++)
{
- variableName[ARRAY_SIZE("DOTNET_") - 1 + i] = name[i];
- }
-#else
- strcat(variableName, name);
-#endif
+ TCHAR ch = buffer[i];
- cchResult = PalGetEnvironmentVariable(variableName, buffer, cchBuffer);
- if (cchResult != 0 && cchResult < cchBuffer)
- {
- // Environment variable was set. Convert it to an integer.
- uint64_t uiResult = 0;
- for (uint32_t i = 0; i < cchResult; i++)
+ if (decimal)
{
- TCHAR ch = buffer[i];
+ uiResult *= 10;
- if (decimal)
- {
- uiResult *= 10;
-
- if ((ch >= '0') && (ch <= '9'))
- uiResult += ch - '0';
- else
- return false; // parse error
- }
+ if ((ch >= '0') && (ch <= '9'))
+ uiResult += ch - '0';
else
- {
- uiResult *= 16;
-
- if ((ch >= '0') && (ch <= '9'))
- uiResult += ch - '0';
- else if ((ch >= 'a') && (ch <= 'f'))
- uiResult += (ch - 'a') + 10;
- else if ((ch >= 'A') && (ch <= 'F'))
- uiResult += (ch - 'A') + 10;
- else
- return false; // parse error
- }
+ return false; // parse error
+ }
+ else
+ {
+ uiResult *= 16;
+
+ if ((ch >= '0') && (ch <= '9'))
+ uiResult += ch - '0';
+ else if ((ch >= 'a') && (ch <= 'f'))
+ uiResult += (ch - 'a') + 10;
+ else if ((ch >= 'A') && (ch <= 'F'))
+ uiResult += (ch - 'A') + 10;
+ else
+ return false; // parse error
}
+ }
+
+ *value = uiResult;
+ return true;
+}
+
+bool RhConfig::Environment::TryGetStringValue(const char* name, char** value)
+{
+ TCHAR variableName[64];
+ GetEnvironmentConfigName(name, variableName, ARRAY_SIZE(variableName));
+
+ TCHAR buffer[260];
+ uint32_t bufferLen = ARRAY_SIZE(buffer);
+ uint32_t actualLen = PalGetEnvironmentVariable(variableName, buffer, bufferLen);
+ if (actualLen == 0)
+ return false;
- *pValue = uiResult;
+ if (actualLen < bufferLen)
+ {
+ *value = PalCopyTCharAsChar(buffer);
return true;
}
+ // Expand the buffer to get the value
+ bufferLen = actualLen + 1;
+ NewArrayHolder<TCHAR> newBuffer {new (nothrow) TCHAR[bufferLen]};
+ actualLen = PalGetEnvironmentVariable(variableName, newBuffer, bufferLen);
+ if (actualLen >= bufferLen)
+ return false;
+
+#ifdef TARGET_WINDOWS
+ *value = PalCopyTCharAsChar(newBuffer);
+#else
+ *value = newBuffer.Extract();
+#endif
+ return true;
+}
+
+bool RhConfig::ReadConfigValue(_In_z_ const char *name, uint64_t* pValue, bool decimal)
+{
+ if (Environment::TryGetIntegerValue(name, pValue, decimal))
+ return true;
+
// Check the embedded configuration
const char *embeddedValue = nullptr;
if (GetEmbeddedVariable(name, &embeddedValue))
#ifndef DACCESS_COMPILE
+#include <sal.h>
+
class RhConfig
{
#define CONFIG_INI_NOT_AVAIL (void*)0x1 //signal for ini file failed to load
#define CONFIG_KEY_MAXLEN 50 //arbitrary max length of config keys increase if needed
#define CONFIG_VAL_MAXLEN 16 //64 bit uint in hex
-
private:
struct ConfigPair
{
void* volatile g_embeddedSettings = NULL;
public:
+ class Environment
+ {
+ public: // static
+ static bool TryGetBooleanValue(const char* name, bool* value);
+ static bool TryGetIntegerValue(const char* name, uint64_t* value, bool decimal = false);
+
+ // Get environment variable configuration as a string. On success, the caller owns the returned string value.
+ static bool TryGetStringValue(const char* name, char** value);
+ };
bool ReadConfigValue(_In_z_ const char* wszName, uint64_t* pValue, bool decimal = false);
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
+// defined in gcrhenv.cpp
+bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount);
+
// #SwitchToThreadSpinning
//
// If you call __SwitchToThread in a loop waiting for a condition to be met,
#include <eventpipe/ep-stack-contents.h>
#include <eventpipe/ep-rt.h>
+#ifdef TARGET_WINDOWS
+#include <windows.h>
+#else
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
// The regdisplay.h, StackFrameIterator.h, and thread.h includes are present only to access the Thread
// class and can be removed if it turns out that the required ep_rt_thread_handle_t can be
// implemented in some manner that doesn't rely on the Thread class.
return static_cast<int64_t>(((static_cast<uint64_t>(value.dwHighDateTime)) << 32) | static_cast<uint64_t>(value.dwLowDateTime));
}
+ep_rt_file_handle_t
+ep_rt_aot_file_open_write (const ep_char8_t *path)
+{
+ if (!path)
+ return INVALID_HANDLE_VALUE;
+
+#ifdef TARGET_WINDOWS
+ ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1);
+ if (!path_utf16)
+ return INVALID_HANDLE_VALUE;
+
+ HANDLE res = ::CreateFileW (reinterpret_cast<LPCWSTR>(path_utf16), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ ep_rt_utf16_string_free (path_utf16);
+ return static_cast<ep_rt_file_handle_t>(res);
+#else
+ mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ int fd = creat (path, perms);
+ if (fd == -1)
+ return INVALID_HANDLE_VALUE;
+
+ return (ep_rt_file_handle_t)(ptrdiff_t)fd;
+#endif
+}
+
+bool
+ep_rt_aot_file_close (ep_rt_file_handle_t file_handle)
+{
+#ifdef TARGET_WINDOWS
+ return ::CloseHandle (file_handle) != FALSE;
+#else
+ int fd = (int)(ptrdiff_t)file_handle;
+ close (fd);
+ return true;
+#endif
+}
+
+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)
+{
+#ifdef TARGET_WINDOWS
+ return ::WriteFile (file_handle, buffer, bytes_to_write, reinterpret_cast<LPDWORD>(bytes_written), NULL) != FALSE;
+#else
+ int fd = (int)(ptrdiff_t)file_handle;
+ int ret;
+ do {
+ ret = write (fd, buffer, bytes_to_write);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret == -1) {
+ if (bytes_written != NULL) {
+ *bytes_written = 0;
+ }
+
+ return false;
+ }
+
+ if (bytes_written != NULL)
+ *bytes_written = ret;
+
+ return true;
+#endif
+}
+
uint8_t *
ep_rt_aot_valloc0 (size_t buffer_size)
{
#include <eventpipe/ep-session-provider.h>
#include "rhassert.h"
+#include <RhConfig.h>
#ifdef TARGET_UNIX
#define sprintf_s snprintf
bool
ep_rt_config_value_get_enable (void)
{
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: EventPipe Configuration values - RhConfig?
- // (CLRConfig::INTERNAL_EnableEventPipe) != 0
- // If EventPipe environment variables are specified, parse them and start a session.
- // TODO: Not start a session for now
+ // See https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables
+ bool value;
+ if (RhConfig::Environment::TryGetBooleanValue("EnableEventPipe", &value))
+ return value;
+
return false;
}
ep_rt_config_value_get_config (void)
{
STATIC_CONTRACT_NOTHROW;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: EventPipe Configuration values - RhConfig?
- // (CLRConfig::INTERNAL_EventPipeConfig)
- // PalDebugBreak();
+
+ // See https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables
+ char* value;
+ if (RhConfig::Environment::TryGetStringValue("EventPipeConfig", &value))
+ return (ep_char8_t*)value;
+
return nullptr;
-// return ep_rt_utf16_to_utf8_string (reinterpret_cast<ep_char16_t *>(value.GetValue ()), -1);
}
static
ep_rt_config_value_get_output_path (void)
{
STATIC_CONTRACT_NOTHROW;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: EventPipe Configuration values - RhConfig?
- // (CLRConfig::INTERNAL_EventPipeOutputPath)
- //PalDebugBreak();
+
+ // See https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables
+ char* value;
+ if (RhConfig::Environment::TryGetStringValue("EventPipeOutputPath", &value))
+ return (ep_char8_t*)value;
+
return nullptr;
}
ep_rt_config_value_get_circular_mb (void)
{
STATIC_CONTRACT_NOTHROW;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: EventPipe Configuration values - RhConfig?
- // (CLRConfig::INTERNAL_EventPipeCircularMB)
- //PalDebugBreak();
+
+ // See https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables
+ uint64_t value;
+ if (RhConfig::Environment::TryGetIntegerValue("EventPipeCircularMB", &value))
+ {
+ EP_ASSERT(value <= UINT32_MAX);
+ return static_cast<uint32_t>(value);
+ }
+
return 0;
}
ep_rt_config_value_get_output_streaming (void)
{
STATIC_CONTRACT_NOTHROW;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: EventPipe Configuration values - RhConfig?
- // (CLRConfig::INTERNAL_EventPipeOutputStreaming)
- //PalDebugBreak();
+
+ bool value;
+ if (RhConfig::Environment::TryGetBooleanValue("EventPipeOutputStreaming", &value))
+ return value;
+
return false;
}
ep_rt_config_value_get_enable_stackwalk (void)
{
STATIC_CONTRACT_NOTHROW;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: EventPipe Configuration values - RhConfig?
- // (CLRConfig::INTERNAL_EventPipeEnableStackwalk)
- //PalDebugBreak();
+
+ bool value;
+ if (RhConfig::Environment::TryGetBooleanValue("EventPipeEnableStackwalk", &value))
+ return value;
+
return true;
}
{
STATIC_CONTRACT_NOTHROW;
- ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1);
- ep_return_null_if_nok (path_utf16 != NULL);
-
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: Find out the way to open a file in native
- // PalDebugBreak();
-
- return 0;
+ extern ep_rt_file_handle_t ep_rt_aot_file_open_write (const ep_char8_t *);
+ return ep_rt_aot_file_open_write (path);
}
static
{
STATIC_CONTRACT_NOTHROW;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: Find out the way to close a file in native
- // PalDebugBreak();
- return true;
+ extern bool ep_rt_aot_file_close (ep_rt_file_handle_t);
+ return ep_rt_aot_file_close (file_handle);
}
static
STATIC_CONTRACT_NOTHROW;
EP_ASSERT (buffer != NULL);
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: Find out the way to write to a file in native
- // PalDebugBreak();
-
- return false;
+ extern bool ep_rt_aot_file_write (ep_rt_file_handle_t, const uint8_t*, uint32_t, uint32_t*);
+ return ep_rt_aot_file_write (file_handle, buffer, bytes_to_write, bytes_written);
}
static
*/
#undef ep_rt_file_handle_t
-typedef class CFileStream * ep_rt_file_handle_t;
+typedef void * ep_rt_file_handle_t;
#undef ep_rt_wait_event_handle_t
typedef struct _rt_aot_event_internal_t ep_rt_wait_event_handle_t;
(void)!write(STDERR_FILENO, message, strlen(message));
}
+REDHAWK_PALEXPORT char* PalCopyTCharAsChar(const TCHAR* toCopy)
+{
+ NewArrayHolder<char> copy {new (nothrow) char[strlen(toCopy) + 1]};
+ strcpy(copy, toCopy);
+ return copy.Extract();
+}
+
static int W32toUnixAccessControl(uint32_t flProtect)
{
int prot = 0;
#define PalRaiseFailFastException RaiseFailFastException
-uint32_t PalEventWrite(REGHANDLE arg1, const EVENT_DESCRIPTOR * arg2, uint32_t arg3, EVENT_DATA_DESCRIPTOR * arg4)
-{
- return EventWrite(arg1, arg2, arg3, arg4);
-}
-
#include "gcenv.h"
#include "gcenv.ee.h"
#include "gcconfig.h"
return !!EventEnabled(regHandle, eventDescriptor);
}
+REDHAWK_PALEXPORT uint32_t REDHAWK_PALAPI PalEventRegister(const GUID * arg1, void * arg2, void * arg3, REGHANDLE * arg4)
+{
+ return EventRegister(arg1, reinterpret_cast<PENABLECALLBACK>(arg2), arg3, arg4);
+}
+
+REDHAWK_PALEXPORT uint32_t REDHAWK_PALAPI PalEventUnregister(REGHANDLE arg1)
+{
+ return EventUnregister(arg1);
+}
+
+REDHAWK_PALEXPORT uint32_t REDHAWK_PALAPI PalEventWrite(REGHANDLE arg1, const EVENT_DESCRIPTOR * arg2, uint32_t arg3, EVENT_DATA_DESCRIPTOR * arg4)
+{
+ return EventWrite(arg1, arg2, arg3, arg4);
+}
+
REDHAWK_PALEXPORT void REDHAWK_PALAPI PalTerminateCurrentProcess(uint32_t arg2)
{
TerminateProcess(GetCurrentProcess(), arg2);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), message, (DWORD)strlen(message), &dwBytesWritten, NULL);
}
+REDHAWK_PALEXPORT char* PalCopyTCharAsChar(const TCHAR* toCopy)
+{
+ int len = ::WideCharToMultiByte(CP_UTF8, 0, toCopy, -1, nullptr, 0, nullptr, nullptr);
+ if (len == 0)
+ return nullptr;
+
+ char* converted = new (nothrow) char[len];
+ int written = ::WideCharToMultiByte(CP_UTF8, 0, toCopy, -1, converted, len, nullptr, nullptr);
+ assert(len == written);
+ return converted;
+}
+
REDHAWK_PALEXPORT _Ret_maybenull_ _Post_writable_byte_size_(size) void* REDHAWK_PALAPI PalVirtualAlloc(_In_opt_ void* pAddress, uintptr_t size, uint32_t allocationType, uint32_t protect)
{
return VirtualAlloc(pAddress, size, allocationType, protect);
<ExcludeList Include="$(XunitTestBinBase)/tracing/eventpipe/buffersize/**">
<Issue>https://github.com/dotnet/runtime/issues/83051</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/tracing/eventpipe/config/**">
- <Issue>https://github.com/dotnet/runtime/issues/83051</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/tracing/eventpipe/diagnosticport/**">
<Issue>https://github.com/dotnet/runtime/issues/83051</Issue>
</ExcludeList>
class NameConfigWithPid
{
+ private const string WaitForInput = "waitforinput";
static int Main(string[] args)
{
if (args.Length == 0)
else
Console.WriteLine($"args[0] = `{args[0]}`");
- if (args.Length > 0 && args[0] == "waitforinput")
+ if (args.Length > 0 && args[0] == WaitForInput)
{
Console.Error.WriteLine("WaitingForInput in ErrorStream");
Console.WriteLine("WaitingForInput");
}
string coreRoot = Environment.GetEnvironmentVariable("CORE_ROOT");
- string corerun = Path.Combine(coreRoot, "corerun");
- if (OperatingSystem.IsWindows())
- corerun = corerun + ".exe";
- // Use dll directory as temp directory
- string tempDir = Path.GetDirectoryName(typeof(NameConfigWithPid).Assembly.Location);
+ // Use app directory as temp directory
+ string tempDir = AppContext.BaseDirectory;
string outputPathBaseName = $"eventPipeStream{Thread.CurrentThread.ManagedThreadId}_{(ulong)Stopwatch.GetTimestamp()}";
string outputPathPattern = Path.Combine(tempDir, outputPathBaseName + "_{pid}_{pid}.nettrace");
- process.StartInfo.FileName = corerun;
- process.StartInfo.Arguments = typeof(NameConfigWithPid).Assembly.Location + " waitforinput";
+ process.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName;
+ process.StartInfo.Arguments = TestLibrary.Utilities.IsNativeAot
+ ? WaitForInput
+ : $"{typeof(NameConfigWithPid).Assembly.Location} {WaitForInput}";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardError = true;
Console.Out.Flush();
process.Start();
- string readFromTargetProcess = process.StandardError.ReadLine();
+ string readFromTargetProcess = process.StandardError.ReadLine();
Console.WriteLine($"Readline '{readFromTargetProcess}'");
if (readFromTargetProcess != "WaitingForInput in ErrorStream")
{
Thread.Sleep(1000);
}
Console.WriteLine($"Unable to delete {expectedPath}");
- return 2;
+ return 2;
}
}
}
<!-- Tracing tests routinely time out with jitstress and gcstress -->
<GCStressIncompatible>true</GCStressIncompatible>
<JitOptimizationSensitive>true</JitOptimizationSensitive>
+ <EventSourceSupport Condition="'$(TestBuildMode)' == 'nativeaot'">true</EventSourceSupport>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
+ <ProjectReference Include="$(TestSourceDir)Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj" />
</ItemGroup>
</Project>