gpt4 book ai didi

delphi - Windows ETW : Kernel consumer receives no EventCallback or BufferCallback events

转载 作者:行者123 更新时间:2023-12-03 15:35:40 28 4
gpt4 key购买 nike

我正在尝试监听 ETW 内核事件。

  • 第 1 步:调用 OpenTrace ,指定 EventCallback和可选 BufferCallback在我调用 ProcessTrace 期间将调用的函数:

    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, PChar(loggerName), sessionProperties);
    if (hr <> ERROR_SUCCESS) then
    raise EWin32Error.Create(SysErrorMessage(hr));

    日志已成功启动(我可以看到 foo.etl 开始增长到其 5 MB 循环限制)。

  • 第 3 步:调用 ProcessTrace ,它会阻塞,直到将所有待处理事件传递到 EventCallback步骤 1 中指定的处理程序:

    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从不返回,但EventCallbackBufferCallback都没有返回曾经被调用过。

我做错了什么?

<小时/>

更新:我的回调函数:

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

关于delphi - Windows ETW : Kernel consumer receives no EventCallback or BufferCallback events,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9055772/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com