| 255 | } |
| 256 | |
| 257 | void TraceManager::OnEventRecord(PEVENT_RECORD rec) { |
| 258 | if (_handle == 0 || _isPaused) |
| 259 | return; |
| 260 | |
| 261 | auto pid = rec->EventHeader.ProcessId; |
| 262 | auto& eventName = GetKernelEventName(rec); |
| 263 | if (eventName.empty() && _dumpUnnamedEvents) |
| 264 | return; |
| 265 | |
| 266 | // use the separate heap |
| 267 | std::shared_ptr<EventData> data(new EventData(rec, GetProcessImageById(pid), eventName, ++_index)); |
| 268 | |
| 269 | // force copying properties |
| 270 | data->GetProperties(); |
| 271 | |
| 272 | if (rec->EventHeader.ProviderId == StackWalkGuid) { |
| 273 | _index--; |
| 274 | if (_lastEvent) { |
| 275 | if (_lastEvent->GetThreadId() != data->GetProperty(L"StackThread")->GetValue<DWORD>()) |
| 276 | return; |
| 277 | |
| 278 | _lastEvent->SetStackEventData(data); |
| 279 | _lastEvent.reset(); |
| 280 | } |
| 281 | _lastExcluded = nullptr; |
| 282 | return; |
| 283 | } |
| 284 | |
| 285 | bool processEvent = ParseProcessStartStop(data.get()); |
| 286 | |
| 287 | if (!processEvent && data->GetProcessId() == 0 || data->GetProcessId() == (DWORD)-1) { |
| 288 | HandleNoProcessId(data.get()); |
| 289 | } |
| 290 | |
| 291 | if (!_filters.empty()) { |
| 292 | // evaluate filters |
| 293 | FilterContext context = { data.get() }; |
| 294 | auto result = FilterAction::None; |
| 295 | for (auto& filter : _filters) { |
| 296 | if (!filter->IsEnabled()) |
| 297 | continue; |
| 298 | auto action = filter->Eval(context); |
| 299 | if (action == FilterAction::Exclude) { |
| 300 | result = action; |
| 301 | break; |
| 302 | } |
| 303 | |
| 304 | if (action == FilterAction::Include) { |
| 305 | result = action; |
| 306 | break; |
| 307 | } |
| 308 | } |
| 309 | if (result == FilterAction::Exclude) { |
| 310 | _filteredEvents++; |
| 311 | _lastExcluded = data; |
| 312 | return; |
| 313 | } |
| 314 | } |
no test coverage detected