Função TraceConfigureLastBranchRecord (evntrace.h)

Configura uma sessão ETW (Rastreamento de Eventos para Windows) para gerar eventos de rastreamento de Registro de Última Ramificação (LBR) em resposta aos eventos de gatilho especificados.

Sintaxe

ULONG TraceConfigureLastBranchRecord(
  CONTROLTRACE_ID         TraceId,
  TRACE_LBR_CONFIGURATION LbrConfiguration,
  CLASSIC_EVENT_ID const  *Events,
  ULONG                   EventCount
);

Parameters

TraceId

Um CONTROLTRACE_ID que representa um identificador para a sessão ETW a ser configurada. Esse é o identificador de sessão retornado por StartTrace.

LbrConfiguration

Um ou mais sinalizadores TRACE_LBR_CONFIGURATION que controlam como os registros LBR são coletados. Esses sinalizadores normalmente são opcionais e podem ser usados para filtrar os branches registrados (por exemplo, kernel vs. branches de usuário ou tipos de branch específicos). Em algumas arquiteturas, um sinalizador pode ser necessário para que a configuração seja bem-sucedida (por exemplo, EVNTRACE_LBR_SAMPLED em dispositivos ARM64 que dão suporte apenas ao SPE e não ao BRBE).

typedef enum EVNTRACE_LBR_FLAGS
{
  EVNTRACE_LBR_FILTER_NONE        = 0x0,
  EVNTRACE_LBR_FILTER_KERNEL        = 0x1,
  EVNTRACE_LBR_FILTER_USER          = 0x2,
  EVNTRACE_LBR_FILTER_JCC           = 0x4,
  EVNTRACE_LBR_FILTER_NEAR_REL_CALL = 0x8,
  EVNTRACE_LBR_FILTER_NEAR_IND_CALL = 0x10,
  EVNTRACE_LBR_FILTER_NEAR_RET      = 0x20,
  EVNTRACE_LBR_FILTER_NEAR_IND_JMP  = 0x40,
  EVNTRACE_LBR_FILTER_NEAR_REL_JMP  = 0x80,
  EVNTRACE_LBR_FILTER_FAR_BRANCH    = 0x100,
  EVNTRACE_LBR_CALLSTACK_ENABLE     = 0x200,
  EVNTRACE_LBR_SAMPLED              = 0x400 // ARM64 only
} TRACE_LBR_CONFIGURATION;

Events

Ponteiro para uma matriz de estruturas de CLASSIC_EVENT_ID que identificam os eventos que disparam a coleção LBR. Cada elemento especifica um GUID do provedor de eventos e um tipo de evento clássico. Os eventos de gatilho especificados também devem ser habilitados para a sessão (por exemplo, por meio de sinalizadores do agente do sistema StartTrace ou EnableTraceEx2); caso contrário, os eventos LBR correspondentes não serão gerados.

EventCount

Número de elementos na matriz Eventos. Se EventCount for zero, a função limpará a lista de eventos de gatilho e desabilitará a coleção LBR para a sessão. Se EventCount for maior que zero, a função habilitará a coleção LBR para a sessão e configurará até EVNTRACE_MAX_LBR_EVENTS disparando eventos.

Valor retornado

Retorna ERROR_SUCCESS se a função for bem-sucedida. Caso contrário, retorna um código de erro Win32.

Remarks

Quando a coleção LBR está habilitada, o ETW emite um evento LBR correlacionado sempre que um dos eventos de gatilho configurados é registrado na sessão. O evento LBR é emitido pelo provedor LBR (GUID 99134383-5248-43fc-834b-529454e75df3) com opcode 0x20. O conteúdo do evento LBR é uma estrutura LBR_TRACE_EVENT_DATA e o carimbo de data/hora do evento LBR corresponde ao carimbo de data/hora do evento de gatilho.

Por exemplo, para coletar LBR em interrupções de PMC do provedor de rastreamento do sistema PerfInfo, especifique um CLASSIC_EVENT_ID com o provedor GUID ce1dbfb4-137e-4da6-87b0-3f59aa102cbc e digite 0x2f (PERFINFO_LOG_TYPE_PMC_INTERRUPT). Durante a reprodução de rastreamento (por exemplo, usando ProcessTrace), o evento de gatilho e seu evento LBR correlacionado têm carimbos de data/hora idênticos.

Os eventos de gatilho devem ser habilitados para a sessão e não mais do que EVNTRACE_MAX_LBR_EVENTS gatilhos podem ser configurados por vez. Ao usar LBR com criação de perfil pmc ou o agente do sistema, o chamador normalmente deve executar elevado e manter o SeSystemProfilePrivilege (SE_SYSTEM_PROFILE_NAME).

Para enriquecer o rastreamento resultante com metadados adicionais, você pode pós-processar a saída usando CreateMergedTraceFile para adicionar dados estendidos, como EVENT_TRACE_MERGE_EXTENDED_DATA_IMAGEID. Isso requer KernelTraceControl.dll do Windows Performance Toolkit (WPT). Como alternativa, você pode usar xperf -merge, que também é fornecido pelo WPT.

Dados de evento LBR

Os eventos LBR têm uma carga que começa com um cabeçalho LBR_TRACE_EVENT_DATA , seguido por um ou mais registros ETW_LBR_ENTRY . Cada entrada identifica uma borda de branch de FromAddress a ToAddress e LBR_INFO campo Informações. O número de entradas é determinado do tamanho da carga do evento.

#pragma pack(push, 1)

typedef struct ETW_LBR_ENTRY
{
  PVOID FromAddress;
  PVOID ToAddress;
  PVOID Information;
} ETW_LBR_ENTRY, *PETW_LBR_ENTRY;

typedef struct LBR_TRACE_EVENT_DATA
{
  ULONGLONG TimeStamp;
  ULONG ProcessId;
  ULONG ThreadId;
  ULONG Options;
  ULONG Unused;
  ETW_LBR_ENTRY Entries[1]; // variable-length
} LBR_TRACE_EVENT_DATA, *PLBR_TRACE_EVENT_DATA;

#pragma pack(pop)

Exemplos

O exemplo a seguir inicia uma sessão do agente do sistema, configura a coleção LBR em eventos de interrupção do PMC perfInfo usando TraceConfigureLastBranchRecord e habilita a criação de perfil do PMC para a sessão.

#include <windows.h>
#include <evntrace.h>

static const GUID PerfinfoGuid =
{ 0xce1dbfb4, 0x137e, 0x4da6, { 0x87, 0xb0, 0x3f, 0x59, 0xaa, 0x10, 0x2c, 0xbc } };

typedef struct _MyEventTraceProperties_t
{
  EVENT_TRACE_PROPERTIES Properties;
  WCHAR LoggerName[MAX_PATH];
  WCHAR LogFileName[MAX_PATH];
} MyEventTraceProperties_t;

typedef struct _PERFINFO_GROUPMASK
{
  ULONG Masks[8];
} PERFINFO_GROUPMASK;

BOOL EnableSystemProfilePrivilege();

int main()
{
  CONTROLTRACE_ID traceHandle = 0;
  ULONG status = ERROR_SUCCESS;
  MyEventTraceProperties_t props = {};

  wcscpy_s(props.LoggerName, MAX_PATH, L"LbrLogger");
  wcscpy_s(props.LogFileName, MAX_PATH, L"LbrProfile.etl");

  props.Properties.Wnode.BufferSize = sizeof(props);
  props.Properties.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  props.Properties.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_SYSTEM_LOGGER_MODE;
  props.Properties.EnableFlags = EVENT_TRACE_FLAG_PROCESS | EVENT_TRACE_FLAG_THREAD | EVENT_TRACE_FLAG_IMAGE_LOAD;
  props.Properties.LoggerNameOffset = offsetof(MyEventTraceProperties_t, LoggerName);
  props.Properties.LogFileNameOffset = offsetof(MyEventTraceProperties_t, LogFileName);

  if (!EnableSystemProfilePrivilege())
    return 1;

  // Specify the PMC event to profile on and configure its interval.
  // This preferably needs to be done before starting a trace.
  TRACE_PROFILE_INTERVAL profile = {};
  profile.Source = 6;     // ProfileBranchInstructions (see: wpr -pmcsources)
  profile.Interval = 65536;

  status = TraceSetInformation(NULL, TraceProfileSourceConfigInfo, &profile.Source, sizeof(ULONG));
  if (status != ERROR_SUCCESS) return 1;

  status = TraceSetInformation(NULL, TraceSampledProfileIntervalInfo, &profile, sizeof(profile));
  if (status != ERROR_SUCCESS) return 1;

  status = StartTraceW(&traceHandle, props.LoggerName, &props.Properties);
  if (status != ERROR_SUCCESS) return 1;

  // Configure LBR to trigger on PerfInfo PMC interrupt (type 0x2f).
  CLASSIC_EVENT_ID profileEvent = {};
  profileEvent.EventGuid = PerfinfoGuid;
  profileEvent.Type = 0x2f; // PERFINFO_LOG_TYPE_PMC_INTERRUPT

  status = TraceConfigureLastBranchRecord(
    traceHandle,
    TRACE_LBR_CONFIGURATION_NONE, // no filters
    &profileEvent,
    1);
  if (status != ERROR_SUCCESS) goto Stop;

  // Start PMC profiling and associate it with this trace.
  // This is done by setting the second mask to the PMC_PROFILE mask.
  PERFINFO_GROUPMASK pmcMasks = {};
  pmcMasks.Masks[1] = 0x00000400; // Mask of PERF_PMC_PROFILE
  status = TraceSetInformation(traceHandle, TraceSystemTraceEnableFlagsInfo, &pmcMasks, sizeof(pmcMasks));

Stop:
  ControlTraceW(traceHandle, NULL, &props.Properties, EVENT_TRACE_CONTROL_STOP);
  return (status == ERROR_SUCCESS) ? 0 : 1;
}

Requirements

Requirement Valor
Cliente mínimo suportado Windows build 26100.1301
Servidor mínimo compatível Windows build 26100.1301
Header evntrace.h
Library Advapi32.lib
DLL Advapi32.dll

Consulte também