diff --git a/src/coreclr/gc/env/gcenv.structs.h b/src/coreclr/gc/env/gcenv.structs.h index 0019ae6c988672..9f287ec7bf8c26 100644 --- a/src/coreclr/gc/env/gcenv.structs.h +++ b/src/coreclr/gc/env/gcenv.structs.h @@ -17,20 +17,6 @@ typedef void * HANDLE; #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; diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h index 0b2d71739fe863..a718812f23ddce 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h @@ -17,8 +17,9 @@ #include #include -#include "gcenv.structs.h" +#include "gcenv.structs.h" // CRITICAL_SECTION #include "IntrinsicConstants.h" +#include "PalRedhawkCommon.h" #ifndef PAL_REDHAWK_INCLUDED #define PAL_REDHAWK_INCLUDED @@ -50,7 +51,6 @@ #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). @@ -65,14 +65,13 @@ typedef void * LPOVERLAPPED; #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 @@ -101,9 +100,6 @@ typedef struct _GUID { #define DECLARE_HANDLE(_name) typedef HANDLE _name -// defined in gcrhenv.cpp -bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount); - struct FILETIME { uint32_t dwLowDateTime; @@ -502,7 +498,6 @@ typedef enum _EXCEPTION_DISPOSITION { #define NULL_AREA_SIZE (64*1024) #endif -//#endif // !DACCESS_COMPILE #endif // !_INC_WINDOWS @@ -510,10 +505,12 @@ typedef enum _EXCEPTION_DISPOSITION { #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) @@ -750,6 +747,9 @@ REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalRegisterHijackCallback(_In_ PalH #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); @@ -776,6 +776,8 @@ REDHAWK_PALIMPORT uint64_t PalQueryPerformanceFrequency(); 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 diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawkFunctions.h b/src/coreclr/nativeaot/Runtime/PalRedhawkFunctions.h index b03fc004c295ea..4c176593b9ff05 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawkFunctions.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawkFunctions.h @@ -37,24 +37,6 @@ inline void PalEnterCriticalSection(CRITICAL_SECTION * arg1) 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() { diff --git a/src/coreclr/nativeaot/Runtime/RhConfig.cpp b/src/coreclr/nativeaot/Runtime/RhConfig.cpp index a321b37cff259a..928778b09f4650 100644 --- a/src/coreclr/nativeaot/Runtime/RhConfig.cpp +++ b/src/coreclr/nativeaot/Runtime/RhConfig.cpp @@ -11,60 +11,120 @@ #include -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 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)) diff --git a/src/coreclr/nativeaot/Runtime/RhConfig.h b/src/coreclr/nativeaot/Runtime/RhConfig.h index 86e8c38a52bcfd..214a79c5c93b24 100644 --- a/src/coreclr/nativeaot/Runtime/RhConfig.h +++ b/src/coreclr/nativeaot/Runtime/RhConfig.h @@ -14,13 +14,14 @@ #ifndef DACCESS_COMPILE +#include + 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 { @@ -36,6 +37,15 @@ class RhConfig 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); diff --git a/src/coreclr/nativeaot/Runtime/SpinLock.h b/src/coreclr/nativeaot/Runtime/SpinLock.h index a343a1881f057c..56200d8b9398a6 100644 --- a/src/coreclr/nativeaot/Runtime/SpinLock.h +++ b/src/coreclr/nativeaot/Runtime/SpinLock.h @@ -3,6 +3,9 @@ #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, diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 72c040c57767f3..c629f2b86c5eb6 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -9,6 +9,14 @@ #include #include +#ifdef TARGET_WINDOWS +#include +#else +#include +#include +#include +#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. @@ -333,6 +341,73 @@ ep_rt_aot_system_timestamp_get (void) return static_cast(((static_cast(value.dwHighDateTime)) << 32) | static_cast(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(path_utf16), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ep_rt_utf16_string_free (path_utf16); + return static_cast(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(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) { diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index ffa5abbad7199b..d17566514a379f 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -19,6 +19,7 @@ #include #include "rhassert.h" +#include #ifdef TARGET_UNIX #define sprintf_s snprintf @@ -415,11 +416,11 @@ inline 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; } @@ -429,12 +430,13 @@ ep_char8_t * 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(value.GetValue ()), -1); } static @@ -443,10 +445,12 @@ ep_char8_t * 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; } @@ -456,10 +460,15 @@ uint32_t 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(value); + } + return 0; } @@ -469,10 +478,11 @@ bool 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; } @@ -482,10 +492,11 @@ bool 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; } @@ -996,14 +1007,8 @@ ep_rt_file_open_write (const ep_char8_t *path) { 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 @@ -1013,10 +1018,8 @@ ep_rt_file_close (ep_rt_file_handle_t file_handle) { 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 @@ -1031,11 +1034,8 @@ ep_rt_file_write ( 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 diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h index df06d264c8d7b4..22c777f692812e 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -58,7 +58,7 @@ typedef class MethodDesc ep_rt_method_desc_t; */ #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; diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index e950a1e70d6ee1..a856be48f4ab8c 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -738,6 +738,13 @@ REDHAWK_PALEXPORT void PalPrintFatalError(const char* message) (void)!write(STDERR_FILENO, message, strlen(message)); } +REDHAWK_PALEXPORT char* PalCopyTCharAsChar(const TCHAR* toCopy) +{ + NewArrayHolder copy {new (nothrow) char[strlen(toCopy) + 1]}; + strcpy(copy, toCopy); + return copy.Extract(); +} + static int W32toUnixAccessControl(uint32_t flProtect) { int prot = 0; diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp index c6a00826461faf..c7b1f3e313fa39 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp @@ -24,11 +24,6 @@ #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" @@ -634,6 +629,21 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalEventEnabled(REGHANDLE regHandle, _In_ 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(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); @@ -719,6 +729,18 @@ REDHAWK_PALEXPORT void PalPrintFatalError(const char* message) 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); diff --git a/src/tests/issues.targets b/src/tests/issues.targets index b7fc2b47ac67df..4ce8e15a067bc6 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1087,9 +1087,6 @@ https://github.com/dotnet/runtime/issues/83051 - - https://github.com/dotnet/runtime/issues/83051 - https://github.com/dotnet/runtime/issues/83051 diff --git a/src/tests/tracing/eventpipe/config/name_config_with_pid.cs b/src/tests/tracing/eventpipe/config/name_config_with_pid.cs index 779d945bd86a4f..edd89453074e35 100644 --- a/src/tests/tracing/eventpipe/config/name_config_with_pid.cs +++ b/src/tests/tracing/eventpipe/config/name_config_with_pid.cs @@ -9,6 +9,7 @@ class NameConfigWithPid { + private const string WaitForInput = "waitforinput"; static int Main(string[] args) { if (args.Length == 0) @@ -16,7 +17,7 @@ static int Main(string[] args) 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"); @@ -39,17 +40,16 @@ static int Main(string[] args) } 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; @@ -63,7 +63,7 @@ static int Main(string[] args) Console.Out.Flush(); process.Start(); - string readFromTargetProcess = process.StandardError.ReadLine(); + string readFromTargetProcess = process.StandardError.ReadLine(); Console.WriteLine($"Readline '{readFromTargetProcess}'"); if (readFromTargetProcess != "WaitingForInput in ErrorStream") { @@ -101,7 +101,7 @@ static int Main(string[] args) Thread.Sleep(1000); } Console.WriteLine($"Unable to delete {expectedPath}"); - return 2; + return 2; } } } diff --git a/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj b/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj index 6089c06c5b0f2c..187b43060edfb8 100644 --- a/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj +++ b/src/tests/tracing/eventpipe/config/name_config_with_pid.csproj @@ -5,8 +5,10 @@ true true + true +