我正在尝试监听 ETW 内核事件。
-
第 1 步:致电OpenTrace http://msdn.microsoft.com/en-us/library/windows/desktop/aa364089%28v=vs.85%29.aspx,指定EventCallback http://msdn.microsoft.com/en-us/library/windows/desktop/aa363721%28v=vs.85%29.aspx和可选的BufferCallback http://msdn.microsoft.com/en-us/library/windows/desktop/aa363685%28v=vs.85%29.aspx在我调用期间将调用的函数ProcessTrace http://msdn.microsoft.com/en-us/library/windows/desktop/aa364093%28v=vs.85%29.aspx:
var
logFile: EVENT_TRACE_LOGFILE;
currentTrace: TRACEHANDLE;
begin
ZeroMemory(@logFile, sizeof(logFile));
logFile.LoggerName := KERNEL_LOGGER_NAME;
logFile.LogFileName := 'C:\Users\Ian\foo.etl';
logFile.ProcessTraceMode := 0;
logFile.EventCallback := RealtimeEventCallback;
logFile.BufferCallback := BufferCallback; //optional
currentTrace := OpenTrace(@logFile);
if (currentTrace = INVALID_PROCESSTRACE_HANDLE) or (currentTrace = -1) then
RaiseLastWin32Error();
-
Step 2: 启用内核事件 http://msdn.microsoft.com/en-us/library/windows/desktop/aa363691%28v=vs.85%29.aspx。这是通过调用来完成的StartTrace http://msdn.microsoft.com/en-us/library/windows/desktop/aa364117%28v=vs.85%29.aspx。就我而言,我想跟踪内核中断 http://msdn.microsoft.com/en-us/library/windows/desktop/aa964780%28v=vs.85%29.aspx (EVENT_TRACE_FLAG_INTERRUPT http://msdn.microsoft.com/en-us/library/windows/desktop/aa363784%28v=vs.85%29.aspx) and 延迟过程调用 http://msdn.microsoft.com/en-us/library/windows/desktop/aa964748%28v=vs.85%29.aspx (EVENT_TRACE_FLAG_DPC http://msdn.microsoft.com/en-us/library/windows/desktop/aa363784%28v=vs.85%29.aspx):
var
sessionProperties: PEVENT_TRACE_PROPERTIES;
bufferSize: Int64;
th: TRACEHANDLE;
loggerName: string;
logFilePath: string;
begin
loggerName := KERNEL_LOGGER_NAME;
logFilePath := 'C:\Users\Ian\foo.etl';
bufferSize := sizeof(EVENT_TRACE_PROPERTIES)
+ 1024 //maximum session name is 1024 characters
+ 1024; //maximum log file name is 1024 characters
sessionProperties := AllocMem(bufferSize);
ZeroMemory(sessionProperties, bufferSize);
sessionProperties.Wnode.BufferSize := bufferSize;
sessionProperties.Wnode.ClientContext := 1; //QPC clock resolution
sessionProperties.Wnode.Flags := WNODE_FLAG_TRACED_GUID;
sessionProperties.Wnode.Guid := SystemTraceControlGuid;
sessionProperties.EnableFlags := EVENT_TRACE_FLAG_INTERRUPT or EVENT_TRACE_FLAG_DPC;
sessionProperties.LogFileMode := EVENT_TRACE_FILE_MODE_CIRCULAR;
sessionProperties.MaximumFileSize := 5; // 5 MB
sessionProperties.LoggerNameOffset := sizeof(EVENT_TRACE_PROPERTIES);
sessionProperties.LogFileNameOffset := sizeof(EVENT_TRACE_PROPERTIES)+1024;
//Copy LoggerName to the offset address
MoveMemory(Pointer(Cardinal(sessionProperties)+sessionProperties.LoggerNameOffset), PChar(loggerName), Length(loggerName)+1);
//Copy LogFilePath to the offset address
MoveMemory(Pointer(Cardinal(sessionProperties)+sessionProperties.LogFileNameOffset), PChar(logFilePath), Length(logFilePath)+1);
hr := StartTrace({var}th, PChar(loggerName), sessionProperties);
if (hr <> ERROR_SUCCESS) then
raise EWin32Error.Create(SysErrorMessage(hr));
并且日志已成功启动(我可以看到foo.etl
开始增长到 5 MB 循环限制)。
-
第 3 步:致电ProcessTrace http://msdn.microsoft.com/en-us/library/windows/desktop/aa364093%28v=vs.85%29.aspx,它会阻塞,直到将所有待处理事件传递给EventCallback http://msdn.microsoft.com/en-us/library/windows/desktop/aa363721%28v=vs.85%29.aspx步骤 1 中指定的处理程序:
var
res: LongWord;
begin
res := EventTrace.ProcessTrace(@currentTrace, 1, nil, nil);
if (res <> ERROR_SUCCESS) then
raise EWin32Error.Create(SysErrorMessage(res));
除了那个ProcessTrace
重复地立即返回,并且不会调用回调 - 即使 etl 文件存在并且正在增长。
如果我更改日志记录基于文件 to Realtime记录:
-
步骤1 -OpenTrace
支持的变化realtime:
logFile.ProcessTraceMode := PROCESS_TRACE_MODE_REAL_TIME;
-
第2步 -StartTrace
支持的变化realtime:
sessionProperties.LogFileMode := EVENT_TRACE_REAL_TIME_MODE;
在这种情况下ProcessTrace
never返回,但两者都没有EventCallback
or BufferCallback
曾经被召唤过。
我究竟做错了什么?
Update:我的回调函数:
function BufferCallback(Logfile: PEVENT_TRACE_LOGFILE): LongWord; stdcall;
begin
ShowMessage('BufferCallback');
Result := 1; //return true to keep processing rows
end;
procedure RealtimeEventCallback(pEvent: PEVENT_TRACE); stdcall;
begin
ShowMessage('EventCallback');
nEvents := nEvents+1;
end;
我发现了问题。
我使用的标题不是四字对齐的。
用 Delphi 的话说,关键字packed
正在被使用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)