diff --git a/UIforETW/ChildProcess.cpp b/UIforETW/ChildProcess.cpp index 22746025..c3075bd3 100644 --- a/UIforETW/ChildProcess.cpp +++ b/UIforETW/ChildProcess.cpp @@ -22,8 +22,8 @@ limitations under the License. static const wchar_t* kPipeName = L"\\\\.\\PIPE\\UIforETWPipe"; -ChildProcess::ChildProcess(std::wstring exePath) - : exePath_(std::move(exePath)) +ChildProcess::ChildProcess(std::wstring exePath, bool printFailedExitCodes) + : exePath_(std::move(exePath)), printFailedExitCodes_(printFailedExitCodes) { // Create the pipe here so that it is guaranteed to be created before // we try starting the process. @@ -44,8 +44,9 @@ ChildProcess::~ChildProcess() { if (hProcess_) { + // Always get the exit code since this also waits for the process to exit. DWORD exitCode = GetExitCode(); - if (exitCode) + if (printFailedExitCodes_ && exitCode) outputPrintf(L"Process exit code was %08x (%lu)\n", exitCode, exitCode); CloseHandle(hProcess_); } diff --git a/UIforETW/ChildProcess.h b/UIforETW/ChildProcess.h index 4e926263..28510396 100644 --- a/UIforETW/ChildProcess.h +++ b/UIforETW/ChildProcess.h @@ -32,7 +32,7 @@ limitations under the License. class ChildProcess { public: - ChildProcess(std::wstring exePath); + ChildProcess(std::wstring exePath, bool printFailedExitCodes = true); // This waits for the child process to terminate, and prints // output with outputPrintf as it arrives. ~ChildProcess(); @@ -56,6 +56,9 @@ class ChildProcess private: // Path to the executable to be run, and its process handle. std::wstring exePath_; + + bool printFailedExitCodes_ = true; + // Process, thread, and event handles have an uninitialized state // of zero. Pipes and files have an uninitialized state of // INVALID_HANDLE_VALUE. Yay Windows! diff --git a/UIforETW/UIforETWDlg.cpp b/UIforETW/UIforETWDlg.cpp index 68e38460..a5b4ae9c 100644 --- a/UIforETW/UIforETWDlg.cpp +++ b/UIforETW/UIforETWDlg.cpp @@ -898,6 +898,15 @@ void CUIforETWDlg::OnBnClickedStarttracing() else UIETWASSERT(0); + { + // Force any existing sessions to stop. This makes starting tracing much more robust. + // Never show the commands executing, and never print the exit code. + ChildProcess child(GetXperfPath(), false); + child.Run(false, L"xperf.exe -stop UIforETWHeapSession -stop UIforETWSession -stop " + GetKernelLogger()); + // Swallow all of the output so that the normal failures will be silent. + child.GetOutput(); + } + std::wstring kernelProviders = L" Latency+POWER+DISPATCHER+DISK_IO_INIT+FILE_IO+FILE_IO_INIT+VIRT_ALLOC+MEMINFO"; if (!extraKernelFlags_.empty()) kernelProviders += L"+" + extraKernelFlags_; @@ -1030,7 +1039,7 @@ void CUIforETWDlg::OnBnClickedStarttracing() std::wstring heapStackWalk; if (bHeapStacks_) heapStackWalk = L" -stackwalk HeapCreate+HeapDestroy+HeapAlloc+HeapRealloc"; - std::wstring heapArgs = L" -start xperfHeapSession -heap -Pids 0" + heapStackWalk + heapBuffers + heapFile; + std::wstring heapArgs = L" -start UIforETWHeapSession -heap -Pids 0" + heapStackWalk + heapBuffers + heapFile; DWORD exitCode = 0; bool started = true; @@ -1158,7 +1167,7 @@ void CUIforETWDlg::StopTracingAndMaybeRecord(bool bSaveTrace) if (tracingMode_ == kHeapTracingToFile) { ETWMark("Tracing type was heap tracing to file."); - child.Run(bShowCommands_, L"xperf.exe -stop xperfHeapSession -stop UIforETWSession -stop " + GetKernelLogger()); + child.Run(bShowCommands_, L"xperf.exe -stop UIforETWHeapSession -stop UIforETWSession -stop " + GetKernelLogger()); } else { @@ -1430,7 +1439,7 @@ void CUIforETWDlg::UpdateTraceList() tempTraces.insert(tempTraces.end(), tempZips.begin(), tempZips.end()); std::sort(tempTraces.begin(), tempTraces.end()); // Function to stop the temporary traces from showing up. - auto ifInvalid = [](const std::wstring& name) { return name == L"kernel.etl" || name == L"user.etl" || name == L"heap.etl"; }; + auto ifInvalid = [](const std::wstring& name) { return name == L"UIForETWkernel.etl" || name == L"UIForETWuser.etl" || name == L"UIForETWheap.etl"; }; tempTraces.erase(std::remove_if(tempTraces.begin(), tempTraces.end(), ifInvalid), tempTraces.end()); for (auto& name : tempTraces) { diff --git a/UIforETW/UIforETWDlg.h b/UIforETW/UIforETWDlg.h index 5329c598..e71bacdf 100644 --- a/UIforETW/UIforETWDlg.h +++ b/UIforETW/UIforETWDlg.h @@ -188,9 +188,9 @@ class CUIforETWDlg : public CDialog // the same result across multiple calls! std::wstring GenerateResultFilename() const; std::wstring GetTempTraceDir() const { return tempTraceDir_; } - std::wstring GetKernelFile() const { return CUIforETWDlg::GetTempTraceDir() + L"kernel.etl"; } - std::wstring GetUserFile() const { return GetTempTraceDir() + L"user.etl"; } - std::wstring GetHeapFile() const { return GetTempTraceDir() + L"heap.etl"; } + std::wstring GetKernelFile() const { return CUIforETWDlg::GetTempTraceDir() + L"UIForETWkernel.etl"; } + std::wstring GetUserFile() const { return GetTempTraceDir() + L"UIForETWuser.etl"; } + std::wstring GetHeapFile() const { return GetTempTraceDir() + L"UIForETWheap.etl"; } // Get session name for kernel logger const std::wstring NTKernelLogger_ = L"\"NT Kernel Logger\"";