#include "peimagelayout.inl"
#include "ildbsymlib.h"
-
#if defined(PROFILING_SUPPORTED)
#include "profilermetadataemitvalidator.h"
#endif
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
// 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())
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_
#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)
{
_ASSERTE(hBBSweepThread);
g_BBSweep.SetBBSweepThreadHandle(hBBSweepThread);
}
-#endif // FEATURE_PREJIT
+#endif // FEATURE_PREJIT && FEATURE_PAL
#ifdef FEATURE_INTERPRETER
Interpreter::Initialize();
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.
#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
}
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
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;
#include "eventtracebase.h"
#include "sampleprofiler.h"
#include "win32threadpool.h"
+#include "ceemain.h"
#ifdef FEATURE_PAL
#include "pal.h"
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;
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(
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);
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
// 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();
static EventPipeBufferManager *s_pBufferManager;
static EventPipeFile *s_pFile;
static EventPipeEventSource *s_pEventSource;
- static LPCWSTR s_pCommandLine;
static HANDLE s_fileSwitchTimerHandle;
static ULONGLONG s_lastFlushSwitchTime;
};