From e4c6c4c4422b15c526642ee139e89bda4f83b242 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 6 Jan 2021 05:49:22 -0800 Subject: [PATCH] Convert Debugger.Log and Debugger.Launch to QCalls (#46617) --- .../src/System/Diagnostics/Debugger.cs | 9 ++- src/coreclr/vm/debugdebugger.cpp | 68 +++++++--------------- src/coreclr/vm/debugdebugger.h | 4 +- src/coreclr/vm/ecalllist.h | 4 +- 4 files changed, 32 insertions(+), 53 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 1d026a6..4015192 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -5,6 +5,7 @@ // and is used for communicating with a debugger. using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Diagnostics { @@ -50,7 +51,7 @@ namespace System.Diagnostics } } - [MethodImpl(MethodImplOptions.InternalCall)] + [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] private static extern bool LaunchInternal(); // Returns whether or not a debugger is attached to the process. @@ -74,8 +75,10 @@ namespace System.Diagnostics // Posts a message for the attached debugger. If there is no // debugger attached, has no effect. The debugger may or may not // report the message depending on its settings. - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern void Log(int level, string? category, string? message); + public static void Log(int level, string? category, string? message) => LogInternal(level, category, message); + + [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] + private static extern void LogInternal(int level, string? category, string? message); // Checks to see if an attached debugger has logging enabled // diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp index 29e6e3b..5027ebf 100644 --- a/src/coreclr/vm/debugdebugger.cpp +++ b/src/coreclr/vm/debugdebugger.cpp @@ -158,36 +158,25 @@ FCIMPL0(void, DebugDebugger::Break) } FCIMPLEND -FCIMPL0(FC_BOOL_RET, DebugDebugger::Launch) +BOOL QCALLTYPE DebugDebugger::Launch() { - FCALL_CONTRACT; + QCALL_CONTRACT; #ifdef DEBUGGING_SUPPORTED if (CORDebuggerAttached()) { - FC_RETURN_BOOL(TRUE); + return TRUE; } - else if (g_pDebugInterface != NULL) - { - HRESULT hr = S_OK; - - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - hr = g_pDebugInterface->LaunchDebuggerForUser(GetThread(), NULL, TRUE, TRUE); - - HELPER_METHOD_FRAME_END(); - if (SUCCEEDED (hr)) - { - FC_RETURN_BOOL(TRUE); - } + if (g_pDebugInterface != NULL) + { + HRESULT hr = g_pDebugInterface->LaunchDebuggerForUser(GetThread(), NULL, TRUE, TRUE); + return SUCCEEDED(hr); } #endif // DEBUGGING_SUPPORTED - FC_RETURN_BOOL(FALSE); + return FALSE; } -FCIMPLEND - FCIMPL0(FC_BOOL_RET, DebugDebugger::IsDebuggerAttached) { @@ -229,42 +218,33 @@ FCIMPLEND // appending a newline to anything. // It will also call OutputDebugString() which will send a native debug event. The message // string there will be a composite of the two managed string parameters and may include a newline. -FCIMPL3(void, DebugDebugger::Log, - INT32 Level, - StringObject* strModuleUNSAFE, - StringObject* strMessageUNSAFE - ) +void QCALLTYPE DebugDebugger::Log(INT32 Level, PCWSTR pwzModule, PCWSTR pwzMessage) { CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(strModuleUNSAFE, NULL_OK)); - PRECONDITION(CheckPointer(strMessageUNSAFE, NULL_OK)); + QCALL_CHECK; + PRECONDITION(CheckPointer(pwzModule, NULL_OK)); + PRECONDITION(CheckPointer(pwzMessage, NULL_OK)); } CONTRACTL_END; - STRINGREF strModule = (STRINGREF)ObjectToOBJECTREF(strModuleUNSAFE); - STRINGREF strMessage = (STRINGREF)ObjectToOBJECTREF(strMessageUNSAFE); - - HELPER_METHOD_FRAME_BEGIN_2(strModule, strMessage); - // OutputDebugString will log to native/interop debugger. - if (strModule != NULL) + if (pwzModule != NULL) { - WszOutputDebugString(strModule->GetBuffer()); + WszOutputDebugString(pwzModule); WszOutputDebugString(W(" : ")); } - if (strMessage != NULL) + if (pwzMessage != NULL) { - WszOutputDebugString(strMessage->GetBuffer()); + WszOutputDebugString(pwzMessage); } // If we're not logging a module prefix, then don't log the newline either. // Thus if somebody is just logging messages, there won't be any extra newlines in there. // If somebody is also logging category / module information, then this call to OutputDebugString is // already prepending that to the message, so we append a newline for readability. - if (strModule != NULL) + if (pwzModule != NULL) { WszOutputDebugString(W("\n")); } @@ -283,21 +263,21 @@ FCIMPL3(void, DebugDebugger::Log, // Strings may contain embedded nulls, but we need to handle null-terminated // strings, so use truncate now. StackSString switchName; - if( strModule != NULL ) + if (pwzModule != NULL) { // truncate if necessary - COUNT_T iLen = (COUNT_T) wcslen(strModule->GetBuffer()); + COUNT_T iLen = (COUNT_T) wcslen(pwzModule); if (iLen > MAX_LOG_SWITCH_NAME_LEN) { iLen = MAX_LOG_SWITCH_NAME_LEN; } - switchName.Set(strModule->GetBuffer(), iLen); + switchName.Set(pwzModule, iLen); } SString message; - if( strMessage != NULL ) + if (pwzMessage != NULL) { - message.Set(strMessage->GetBuffer(), (COUNT_T) wcslen(strMessage->GetBuffer())); + message.Set(pwzMessage, (COUNT_T) wcslen(pwzMessage)); } g_pDebugInterface->SendLogMessage (Level, &switchName, &message); @@ -305,11 +285,7 @@ FCIMPL3(void, DebugDebugger::Log, } #endif // DEBUGGING_SUPPORTED - - HELPER_METHOD_FRAME_END(); } -FCIMPLEND - FCIMPL0(FC_BOOL_RET, DebugDebugger::IsLogging) { diff --git a/src/coreclr/vm/debugdebugger.h b/src/coreclr/vm/debugdebugger.h index 3a36f98..28b8218 100644 --- a/src/coreclr/vm/debugdebugger.h +++ b/src/coreclr/vm/debugdebugger.h @@ -20,9 +20,9 @@ class DebugDebugger { public: static FCDECL0(void, Break); - static FCDECL0(FC_BOOL_RET, Launch); + static BOOL QCALLTYPE Launch(); static FCDECL0(FC_BOOL_RET, IsDebuggerAttached); - static FCDECL3(void, Log, INT32 Level, StringObject* strModule, StringObject* strMessage); + static void QCALLTYPE Log(INT32 Level, PCWSTR pwzModule, PCWSTR pwzMessage); // receives a custom notification object from the target and sends it to the RS via // code:Debugger::SendCustomDebuggerNotification diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index d72d88e..bdab73a 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -120,9 +120,9 @@ FCFuncEnd() FCFuncStart(gDiagnosticsDebugger) FCFuncElement("BreakInternal", DebugDebugger::Break) - FCFuncElement("LaunchInternal", DebugDebugger::Launch) + QCFuncElement("LaunchInternal", DebugDebugger::Launch) FCFuncElement("get_IsAttached", DebugDebugger::IsDebuggerAttached) - FCFuncElement("Log", DebugDebugger::Log) + QCFuncElement("LogInternal", DebugDebugger::Log) FCFuncElement("IsLogging", DebugDebugger::IsLogging) FCFuncElement("CustomNotification", DebugDebugger::CustomNotification) FCFuncEnd() -- 2.7.4