AutoTrace - launch dotnet trace to capture trace as soon as the runtime is available...
authorAndrew Au <andrewau@microsoft.com>
Fri, 3 May 2019 22:43:43 +0000 (15:43 -0700)
committerAndrew Au <cshung@gmail.com>
Mon, 3 Jun 2019 06:17:41 +0000 (23:17 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/360d41f4ff93b6507863cb324a247fd7380b4f79

src/coreclr/src/vm/CMakeLists.txt
src/coreclr/src/vm/autotrace.cpp [new file with mode: 0644]
src/coreclr/src/vm/autotrace.h [new file with mode: 0644]
src/coreclr/src/vm/diagnosticserver.cpp

index 9db2594..f8048d3 100644 (file)
@@ -4,6 +4,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
 include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${ARCH_SOURCES_DIR})
 
+add_definitions(-DFEATURE_AUTO_TRACE)
 add_definitions(-DUNICODE)
 add_definitions(-D_UNICODE)
 
@@ -308,6 +309,7 @@ set(VM_SOURCES_WKS
     comwaithandle.cpp
     customattribute.cpp
     custommarshalerinfo.cpp
+    autotrace.cpp
     diagnosticserver.cpp
     dllimportcallback.cpp
     eeconfig.cpp
@@ -422,6 +424,7 @@ set(VM_HEADERS_WKS
     comwaithandle.h
     customattribute.h
     custommarshalerinfo.h
+    autotrace.h
     diagnosticserver.h
     diagnosticsprotocol.h
     dllimportcallback.h
diff --git a/src/coreclr/src/vm/autotrace.cpp b/src/coreclr/src/vm/autotrace.cpp
new file mode 100644 (file)
index 0000000..e30585b
--- /dev/null
@@ -0,0 +1,69 @@
+#include "common.h" // Required for pre-compiled header
+
+#ifdef FEATURE_AUTO_TRACE
+
+#include "pal.h"
+
+HANDLE auto_trace_event;
+
+void auto_trace_init()
+{
+    auto_trace_event = CreateEventW(
+        /* lpEventAttributes = */ NULL,
+        /* bManualReset      = */ FALSE,
+        /* bInitialState     = */ FALSE,
+        /* lpName            = */ nullptr
+    );
+}
+
+void auto_trace_launch()
+{
+    DWORD currentProcessId = GetCurrentProcessId();
+    STARTUPINFO si;
+    ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(STARTUPINFO);
+#ifndef FEATURE_PAL
+    si.dwFlags = STARTF_USESHOWWINDOW;
+    si.wShowWindow = SW_HIDE;
+#endif
+    
+    PROCESS_INFORMATION result;
+    #ifdef FEATURE_PAL
+    const char16_t* commandFormat = u"/Users/andrewau/git/diagnostics/src/Tools/dotnet-trace/run.sh collect --providers Microsoft-Windows-DotNETRuntime:FFFFFFFFFFFFFFBF -p %d";
+    #else
+    const char16_t* commandFormat = u"C:\\Windows\\System32\\cmd.exe /c run.cmd collect --providers Microsoft-Windows-DotNETRuntime:FFFFFFFFFFFFFFBF -p %d";
+    #endif
+    size_t len = wcslen(commandFormat) + 10 + 1;
+    char16_t* command = new char16_t[len];
+    _snwprintf_s(command, len, _TRUNCATE, commandFormat, currentProcessId);
+    const char16_t* currentDirectory = u"C:\\Dev\\diagnostics\\src\\Tools\\dotnet-trace";
+
+    BOOL code = CreateProcessW(
+        /* lpApplicationName    = */ nullptr,
+        /* lpCommandLine        = */ command,
+        /* lpCommandLine        = */ nullptr,
+        /* lpThreadAttributes   = */ nullptr,
+        /* bInheritHandles      = */ false,
+        /* dwCreationFlags      = */ CREATE_NEW_CONSOLE,
+        /* lpEnvironment        = */ nullptr,
+        /* lpCurrentDirectory   = */ currentDirectory,
+        /* lpStartupInfo        = */ &si,
+        /* lpProcessInformation = */ &result
+    );
+    delete[] command;
+}
+
+void auto_trace_wait()
+{
+    WaitForSingleObject(auto_trace_event, INFINITE);
+}
+
+void auto_trace_signal()
+{
+    #ifdef SetEvent
+    #undef SetEvent
+    #endif
+    SetEvent(auto_trace_event);    
+}
+
+#endif // FEATURE_AUTO_TRACE
\ No newline at end of file
diff --git a/src/coreclr/src/vm/autotrace.h b/src/coreclr/src/vm/autotrace.h
new file mode 100644 (file)
index 0000000..0a3c721
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __AUTO_TRACE_H__
+#define __AUTO_TRACE_H__
+#ifdef FEATURE_AUTO_TRACE
+
+void auto_trace_init();
+void auto_trace_launch();
+void auto_trace_wait();
+void auto_trace_signal();
+
+#endif // FEATURE_AUTO_TRACE
+#endif // __AUTO_TRACE_H__
\ No newline at end of file
index ae26ec9..5ec60aa 100644 (file)
 #include "pal.h"
 #endif // FEATURE_PAL
 
+#ifdef FEATURE_AUTO_TRACE
+#include "autotrace.h"
+#endif
+
 #ifdef FEATURE_PERFTRACING
 
 IpcStream::DiagnosticsIpc *DiagnosticServer::s_pIpc = nullptr;
@@ -45,9 +49,12 @@ static DWORD WINAPI DiagnosticsServerThread(LPVOID lpThreadParameter)
         {
             // FIXME: Ideally this would be something like a std::shared_ptr
             IpcStream *pStream = pIpc->Accept(LoggingCallback);
+            
             if (pStream == nullptr)
                 continue;
-
+#ifdef FEATURE_AUTO_TRACE
+            auto_trace_signal();
+#endif
             DiagnosticsIpc::IpcMessage message;
             if (!message.Initialize(pStream))
             {
@@ -128,6 +135,10 @@ bool DiagnosticServer::Initialize()
 
         if (s_pIpc != nullptr)
         {
+#ifdef FEATURE_AUTO_TRACE
+            auto_trace_init();
+            auto_trace_launch();
+#endif
             DWORD dwThreadId = 0;
             HANDLE hThread = ::CreateThread( // TODO: Is it correct to have this "lower" level call here?
                 nullptr,                     // no security attribute
@@ -148,6 +159,9 @@ bool DiagnosticServer::Initialize()
             }
             else
             {
+#ifdef FEATURE_AUTO_TRACE
+                auto_trace_wait();
+#endif
                 // FIXME: Maybe hold on to the thread to abort/cleanup at exit?
                 ::CloseHandle(hThread);