Convert Debugger.Log and Debugger.Launch to QCalls (#46617)
authorJan Kotas <jkotas@microsoft.com>
Wed, 6 Jan 2021 13:49:22 +0000 (05:49 -0800)
committerGitHub <noreply@github.com>
Wed, 6 Jan 2021 13:49:22 +0000 (05:49 -0800)
src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs
src/coreclr/vm/debugdebugger.cpp
src/coreclr/vm/debugdebugger.h
src/coreclr/vm/ecalllist.h

index 1d026a6..4015192 100644 (file)
@@ -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
         //
index 29e6e3b..5027ebf 100644 (file)
@@ -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)
 {
index 3a36f98..28b8218 100644 (file)
@@ -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
index d72d88e..bdab73a 100644 (file)
@@ -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()