>步骤1:调用OpenTrace
,指定在调用ProcessTrace
期间将调用的EventCallback
和可选BufferCallback
函数:
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();
>步骤2:Enable kernel events.这是通过调用StartTrace
完成的.在我的情况下,我想跟踪内核interrupts(EVENT_TRACE_FLAG_INTERRUPT
)和deferred procedure calls(EVENT_TRACE_FLAG_DPC
):
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,sessionPropertIEs); if (hr <> ERROR_SUCCESS) then raise EWin32Error.Create(SysErrorMessage(hr));
并且日志成功启动(我可以看到foo.etl开始增长到它的5 MB circuluar限制).
>步骤3:调用ProcessTrace
,阻止它将所有挂起事件传递给步骤1中指定的EventCallback
处理程序:
var res: LongWord;begin res := EventTrace.Processtrace(@currentTrace,1,nil,nil); if (res <> ERROR_SUCCESS) then raise EWin32Error.Create(SysErrorMessage(res));
除了Processtrace立即重复返回,并且没有调用回调 – 即使etl文件存在并且正在增长.
如果我将记录从基于文件更改为实时日志记录:
>第1步 – OpenTrace更改以支持实时:
logfile.ProcesstraceMode := PROCESS_TRACE_MODE_REAL_TIME;
>第2步 – StartTrace更改以支持实时:
sessionPropertIEs.LogfileMode := EVENT_TRACE_REAL_TIME_MODE;
在这种情况下,Processtrace永远不会返回,但是从未调用过EventCallback或BufferCallback.
我究竟做错了什么?
更新:我的回调函数:
function BufferCallback(Logfile: PEVENT_TRACE_LOGfile): LongWord; stdcall;begin ShowMessage('BufferCallback'); Result := 1; //return true to keep processing rowsend;procedure RealtimeEventCallback(pEvent: PEVENT_TRACE); stdcall;begin ShowMessage('EventCallback'); nEvents := nEvents+1;end;解决方法 我发现了这个问题.
我使用的标题不是四字对齐的.
在Delphi的说法中,正在使用关键字packed.
总结以上是内存溢出为你收集整理的delphi – Windows ETW:内核使用者不接收EventCallback或BufferCallback事件全部内容,希望文章能够帮你解决delphi – Windows ETW:内核使用者不接收EventCallback或BufferCallback事件所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)