Commits from dotnet/coreclr#24229 - Fixes for IBC profile data on Linux
authorBrian Sullivan <briansul@microsoft.com>
Fri, 26 Apr 2019 23:21:51 +0000 (16:21 -0700)
committerBrian Sullivan <briansul@microsoft.com>
Fri, 26 Apr 2019 23:21:51 +0000 (16:21 -0700)
Added public static function GetManagedCommandLine() and SaveManagedCommandLine()

Moved GetManagedCommandLine and SaveManagedCommandLine to ceeload to link

Disabled the setup for BBSweep on Linux as the PAL doesn’t support process named objects

Commit migrated from https://github.com/dotnet/coreclr/commit/36e4846e9053cf966b7c07d28fdb47b983afbfca

src/coreclr/src/vm/ceeload.cpp
src/coreclr/src/vm/ceeload.h
src/coreclr/src/vm/ceemain.cpp
src/coreclr/src/vm/corhost.cpp
src/coreclr/src/vm/eventpipe.cpp
src/coreclr/src/vm/eventpipe.h

index 0de5dd4..ab5d6e8 100644 (file)
@@ -74,7 +74,6 @@
 #include "peimagelayout.inl"
 #include "ildbsymlib.h"
 
-
 #if defined(PROFILING_SUPPORTED)
 #include "profilermetadataemitvalidator.h"
 #endif
@@ -11653,6 +11652,102 @@ static bool GetBasename(LPCWSTR _src, __out_ecount(dstlen) __out_z LPWSTR _dst,
     return true;
 }
 
+static LPCWSTR s_pCommandLine = NULL;
+
+// Rerieve the full command line for the current process.
+LPCWSTR GetManagedCommandLine()
+{
+    LIMITED_METHOD_CONTRACT;
+    return s_pCommandLine;
+}
+
+void Append_Next_Item(LPWSTR* ppCursor, SIZE_T* pRemainingLen, LPCWSTR pItem, bool addSpace)
+{
+    // read the writeback args and setup pCursor and remainingLen
+    LPWSTR pCursor      = *ppCursor;
+    SIZE_T remainingLen = *pRemainingLen;
+
+    // Calculate the length of pItem
+    SIZE_T itemLen = wcslen(pItem);
+
+    // Append pItem at pCursor
+    wcscpy_s(pCursor, remainingLen, pItem);
+    pCursor      += itemLen;
+    remainingLen -= itemLen;
+
+    // Also append a space after pItem, if requested
+    if (addSpace)
+    {
+        // Append a space at pCursor
+        wcscpy_s(pCursor, remainingLen, W(" "));
+        pCursor      += 1;
+        remainingLen -= 1;
+    }
+
+    // writeback and update ppCursor and pRemainingLen
+    *ppCursor      = pCursor;
+    *pRemainingLen = remainingLen;
+}
+
+void SaveManagedCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv)
+{
+    CONTRACTL
+    {
+        NOTHROW;
+        GC_NOTRIGGER;
+        MODE_ANY;
+    }
+    CONTRACTL_END;
+
+    // Get the command line.
+    LPCWSTR osCommandLine = GetCommandLineW();
+
+#ifndef FEATURE_PAL
+    // On Windows, osCommandLine contains the executable and all arguments.
+    s_pCommandLine = osCommandLine;
+#else
+    // On UNIX, the PAL doesn't have the command line arguments, so we must build the command line.
+    // osCommandLine contains the full path to the executable.
+    SIZE_T  commandLineLen = (wcslen(osCommandLine) + 1);
+
+    // We will append pwzAssemblyPath to the 'corerun' osCommandLine
+    commandLineLen += (wcslen(pwzAssemblyPath) + 1);
+    
+    for (int i = 0; i < argc; i++)
+    {
+        commandLineLen += (wcslen(argv[i]) + 1);
+    }
+    commandLineLen++;  // Add 1 for the null-termination
+
+    // Allocate a new string for the command line.
+    LPWSTR pNewCommandLine = new WCHAR[commandLineLen];
+    SIZE_T remainingLen    = commandLineLen;
+    LPWSTR pCursor         = pNewCommandLine;
+
+    Append_Next_Item(&pCursor, &remainingLen, osCommandLine,   true);
+    Append_Next_Item(&pCursor, &remainingLen, pwzAssemblyPath, true);
+
+    for (int i = 0; i < argc; i++)
+    {
+        bool moreArgs = (i < (argc-1));
+        Append_Next_Item(&pCursor, &remainingLen, argv[i], moreArgs);
+    }
+
+    s_pCommandLine = pNewCommandLine;
+#endif 
+}
+
+// Release any memory that we allocated for the managed command line
+void ReleaseManagedCommandLine()
+{
+    LIMITED_METHOD_CONTRACT;
+
+#ifdef FEATURE_PAL
+    delete[] s_pCommandLine; 
+    s_pCommandLine = NULL;
+#endif
+}
+
 static void ProfileDataAllocateScenarioInfo(ProfileEmitter * pEmitter, LPCSTR scopeName, GUID* pMvid)
 {
     CONTRACTL
@@ -11681,7 +11776,9 @@ static void ProfileDataAllocateScenarioInfo(ProfileEmitter * pEmitter, LPCSTR sc
     // Allocate and initialize the scenario header section
     //
     {
-        LPCWSTR  pCmdLine    = GetCommandLineW();
+        // Get the managed command line.
+        LPCWSTR pCmdLine = GetManagedCommandLine();
+
         S_SIZE_T cCmdLine = S_SIZE_T(wcslen(pCmdLine));
         cCmdLine += 1;
         if (cCmdLine.IsOverflow())
index 04d78c3..adfefcc 100644 (file)
@@ -3419,4 +3419,11 @@ struct VASigCookieEx : public VASigCookie
     const BYTE *m_pArgs;        // pointer to first unfixed unmanaged arg
 };
 
+// Rerieve the full command line for the current process.
+LPCWSTR GetManagedCommandLine();
+// Save the command line for the current process.
+void SaveManagedCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv);
+// Release any memory that we allocated for the managed command line
+void ReleaseManagedCommandLine();
+
 #endif // !CEELOAD_H_
index 10216f5..e595e88 100644 (file)
@@ -770,8 +770,9 @@ void EEStartupHelper(COINITIEE fFlags)
 
 #ifndef CROSSGEN_COMPILE
 
-
-#ifdef FEATURE_PREJIT
+        // Cross-process named objects are not supported in PAL
+        // (see CorUnix::InternalCreateEvent - src/pal/src/synchobj/event.cpp.272)
+#if defined(FEATURE_PREJIT) && !defined(FEATURE_PAL)
         // Initialize the sweeper thread.
         if (g_pConfig->GetZapBBInstr() != NULL)
         {
@@ -785,7 +786,7 @@ void EEStartupHelper(COINITIEE fFlags)
             _ASSERTE(hBBSweepThread);
             g_BBSweep.SetBBSweepThreadHandle(hBBSweepThread);
         }
-#endif // FEATURE_PREJIT
+#endif // FEATURE_PREJIT && FEATURE_PAL
 
 #ifdef FEATURE_INTERPRETER
         Interpreter::Initialize();
@@ -2604,7 +2605,6 @@ INT32 GetLatchedExitCode (void)
     return LatchedExitCode;
 }
 
-    
 // ---------------------------------------------------------------------------
 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
 // Return an int uniquely describing which language this thread is using for ui.
index b42fc28..c588e31 100644 (file)
 #include "dwreport.h"
 #endif // !FEATURE_PAL
 
-#include "stringarraylist.h"
-#ifdef FEATURE_PERFTRACING
-#include "eventpipe.h"
-#endif // FEATURE_PERFTRACING
-
 #ifdef FEATURE_COMINTEROP
 #include "winrttypenameconverter.h"
 #endif
@@ -343,10 +338,8 @@ void SetCommandLineArgs(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR* argv)
     }
     CONTRACTL_END;
 
-    // Send the command line to EventPipe.
-#ifdef FEATURE_PERFTRACING
-    EventPipe::SaveCommandLine(pwzAssemblyPath, argc, argv);
-#endif // FEATURE_PERFTRACING
+    // Record the command line.
+    SaveManagedCommandLine(pwzAssemblyPath, argc, argv);
 
     // Send the command line to System.Environment.
     struct _gc
@@ -476,6 +469,11 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
 
         GCPROTECT_END();
 
+        // When running under FEATURE_PAL, the SetCommandLineArgs call above will
+        // call SaveManagedCommandLine which will allocate memory using new WCHAR[]
+        // We can release this memory now.
+        //
+        ReleaseManagedCommandLine();
     }
 
     UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
index 3a13dbd..0490756 100644 (file)
@@ -19,6 +19,7 @@
 #include "eventtracebase.h"
 #include "sampleprofiler.h"
 #include "win32threadpool.h"
+#include "ceemain.h"
 
 #ifdef FEATURE_PAL
 #include "pal.h"
@@ -33,7 +34,6 @@ EventPipeSession *EventPipe::s_pSession = NULL;
 EventPipeBufferManager *EventPipe::s_pBufferManager = NULL;
 EventPipeFile *EventPipe::s_pFile = NULL;
 EventPipeEventSource *EventPipe::s_pEventSource = NULL;
-LPCWSTR EventPipe::s_pCommandLine = NULL;
 HANDLE EventPipe::s_fileSwitchTimerHandle = NULL;
 ULONGLONG EventPipe::s_lastFlushSwitchTime = 0;
 
@@ -223,12 +223,6 @@ void EventPipe::Shutdown()
     delete s_pEventSource;
     s_pEventSource = NULL;
 
-    // On Windows, this is just a pointer to the return value from
-    // GetCommandLineW(), so don't attempt to free it.
-#ifdef FEATURE_PAL
-    delete[] s_pCommandLine;
-    s_pCommandLine = NULL;
-#endif
 }
 
 EventPipeSessionID EventPipe::Enable(
@@ -380,7 +374,7 @@ void EventPipe::DisableInternal(EventPipeSessionID id, EventPipeProviderCallback
         SampleProfiler::Disable();
 
         // Log the process information event.
-        s_pEventSource->SendProcessInfo(s_pCommandLine);
+        s_pEventSource->SendProcessInfo(GetManagedCommandLine());
 
         // Log the runtime information event.
         ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal);
@@ -890,47 +884,6 @@ StackWalkAction EventPipe::StackWalkCallback(CrawlFrame *pCf, StackContents *pDa
     return SWA_CONTINUE;
 }
 
-void EventPipe::SaveCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv)
-{
-    CONTRACTL
-    {
-        THROWS;
-        GC_TRIGGERS;
-        MODE_COOPERATIVE;
-        PRECONDITION(pwzAssemblyPath != NULL);
-        PRECONDITION(argc <= 0 || argv != NULL);
-    }
-    CONTRACTL_END;
-
-    // Get the command line.
-    LPCWSTR osCommandLine = GetCommandLineW();
-
-#ifndef FEATURE_PAL
-    // On Windows, osCommandLine contains the executable and all arguments.
-    s_pCommandLine = osCommandLine;
-#else
-    // On UNIX, the PAL doesn't have the command line arguments, so we must build the command line.
-    // osCommandLine contains the full path to the executable.
-    SString commandLine(osCommandLine);
-    commandLine.Append((WCHAR)' ');
-    commandLine.Append(pwzAssemblyPath);
-
-    for (int i = 0; i < argc; i++)
-    {
-        commandLine.Append((WCHAR)' ');
-        commandLine.Append(argv[i]);
-    }
-
-    // Allocate a new string for the command line.
-    SIZE_T commandLineLen = commandLine.GetCount();
-    WCHAR *pCommandLine = new WCHAR[commandLineLen + 1];
-    wcsncpy(pCommandLine, commandLine.GetUnicode(), commandLineLen);
-    pCommandLine[commandLineLen] = '\0';
-
-    s_pCommandLine = pCommandLine;
-#endif
-}
-
 EventPipeEventInstance *EventPipe::GetNextEvent()
 {
     CONTRACTL
index c8094e3..ad0e84e 100644 (file)
@@ -330,9 +330,6 @@ public:
     // Get the managed call stack for the specified thread.
     static bool WalkManagedStackForThread(Thread *pThread, StackContents &stackContents);
 
-    // Save the command line for the current process.
-    static void SaveCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv);
-
     // Get next event.
     static EventPipeEventInstance *GetNextEvent();
 
@@ -399,7 +396,6 @@ private:
     static EventPipeBufferManager *s_pBufferManager;
     static EventPipeFile *s_pFile;
     static EventPipeEventSource *s_pEventSource;
-    static LPCWSTR s_pCommandLine;
     static HANDLE s_fileSwitchTimerHandle;
     static ULONGLONG s_lastFlushSwitchTime;
 };