| 2746 | } |
| 2747 | |
| 2748 | void PMTraceConsumer::HandleProcessEvent(EVENT_RECORD* pEventRecord) |
| 2749 | { |
| 2750 | auto const& hdr = pEventRecord->EventHeader; |
| 2751 | |
| 2752 | ProcessEvent event; |
| 2753 | event.QpcTime = hdr.TimeStamp.QuadPart; |
| 2754 | |
| 2755 | if (hdr.ProviderId == Microsoft_Windows_Kernel_Process::GUID) { |
| 2756 | switch (hdr.EventDescriptor.Id) { |
| 2757 | case Microsoft_Windows_Kernel_Process::ProcessStart_Start::Id: |
| 2758 | case Microsoft_Windows_Kernel_Process::ProcessRundown_Info::Id: { |
| 2759 | EventDataDesc desc[] = { |
| 2760 | { L"ProcessID" }, |
| 2761 | { L"ImageName" }, |
| 2762 | }; |
| 2763 | mMetadata.GetEventData(pEventRecord, desc, _countof(desc)); |
| 2764 | event.ProcessId = desc[0].GetData<uint32_t>(); |
| 2765 | auto ImageName = desc[1].GetData<std::wstring>(); |
| 2766 | event.IsStartEvent = true; |
| 2767 | |
| 2768 | // When run as-administrator, ImageName will be a fully-qualified path. |
| 2769 | // e.g.: \Device\HarddiskVolume...\...\Proces.exe. We prune off everything other than |
| 2770 | // the filename here to be consistent. |
| 2771 | size_t start = ImageName.find_last_of(L'\\') + 1; |
| 2772 | event.ImageFileName = ImageName.c_str() + start; |
| 2773 | break; |
| 2774 | } |
| 2775 | case Microsoft_Windows_Kernel_Process::ProcessStop_Stop::Id: { |
| 2776 | EventDataDesc desc[] = { |
| 2777 | { L"ProcessID" }, |
| 2778 | }; |
| 2779 | mMetadata.GetEventData(pEventRecord, desc, _countof(desc)); |
| 2780 | event.ProcessId = desc[0].GetData<uint32_t>(); |
| 2781 | event.IsStartEvent = false; |
| 2782 | |
| 2783 | // Clean up PC Latency tracking data for this process to prevent memory leaks. |
| 2784 | // This is necessary because PCLStatsShutdown events are application-controlled |
| 2785 | // and may not be sent if the app crashes or terminates abnormally. |
| 2786 | if (mTrackPcLatency) { |
| 2787 | std::erase_if(mPclTimingDataByPclFrameId, [&event](const auto& p) { |
| 2788 | return p.first.second == event.ProcessId; |
| 2789 | }); |
| 2790 | mLatestPingTimestampByProcessId.erase(event.ProcessId); |
| 2791 | } |
| 2792 | // Clean up App Timing data as well... |
| 2793 | if (mTrackAppTiming) { |
| 2794 | std::erase_if(mAppTimingDataByAppFrameId, [&event](const auto& p) { |
| 2795 | return p.second.ProcessId == event.ProcessId; |
| 2796 | }); |
| 2797 | std::erase_if(mPresentByAppFrameId, [&event](const auto& p) { |
| 2798 | return p.first.second == event.ProcessId; |
| 2799 | }); |
| 2800 | } |
| 2801 | break; |
| 2802 | } |
| 2803 | default: |
| 2804 | assert(!mFilteredEvents); // Assert that filtering is working if expected |
| 2805 | return; |
no test coverage detected