Intel® System Debugger User Guide

ID 648476
Date 06/13/2024
Confidential
Document Table of Contents

Reconstructing Program Execution Flow

You can record and reconstruction the flow of your program execution by using the Last Branch Record (LBR) functionality. Follow the steps below:

  1. Power the target on and let Windows* start.

  2. Launch Intel(R) Debug Extensions for WinDbg*. The sysdbg64.dll is loaded automatically.

  3. Enable recording of LBR by executing the command below:

    !enablelbr
    
    Note:

    Once LBR is enabled, Intel(R) Processor Trace (Intel(R) PT) is disabled as these methods are incompatible.

  4. Press F5 or type g in the terminal to run the target for a while.

  5. Stop the target by pressing the break button in the toolbar.

  6. Display reconstructed flow with the following command:

    !showlbrflow
    

    The complete reconstructed flow is displayed in the terminal. The initial instruction corresponds to the first recorded branch and the final instruction corresponds to rip. See an example output below:

    Flow reconstruction from Last Branch Records
    
    fffff807'126621f5 493bc7        cmp   rax,r15
    
    fffff807'126621f8 0f82e0d51700  jb    nt!HalpTimeStallExecutionProcessor+0x17d6ee
    
    (fffff807'127df7de)
    
    fffff807'126621f5 493bc7        mov   rcx,rsi
    
    fffff807'126621f5 493bc7        mov   r15,rax
    
    fffff807'126621f5 493bc7        sub   rcx,qword ptr [rsp+30h]
    
    ...
    

    Alternatively, you can print blocks as follows:

    !showlbr
    

    Example output:

    LBR stack
    
    Address             Function
    
    0xfffff8071264202b  nt!PpmConvertTime+0x3b
    
    0xfffff8071264200a  nt!PpmConvertTime+0x1a
    
    0xfffff807127e9789  nt!PpmUpdateTimeAccumulation+0x16ae6d
    
    0xfffff8071267e98a  nt!PpmUpdateTimeAccumulation+0x6e
    
    ...
    
    Note:

    Flow is reconstructed only if LBRs contain proper data. If Model-specific Registers (MSRs) associated with LBR are 0, the commands above will not return the flow. Use the command below for validation.

  7. To check what LBRs have recorded, execute the following command:

    !showmsr
    

    Example output:

    List of MSR Last Branch Records
    
    Actual branch (TOS):28
    
    TOS MSR_LASTBRANCH_x_FROM_IP MSR_LASTBRANCH_x_TO_IP
    
    0 0xfffff807126621e4 0xfffff8071266238c
    
    1 0xfffff807126623a0 0xfffff807126621e9
    
    2 0xfffff807126621f0 0xfffff807127a63e0
    
    3 0xfffff807127a63f3 0xfffff807127a6411
    
    3 0xfffff807127a63f3 0xfffff807127a6411
    
    ...
    

You can also import LBRs to decode. Execute the following command to import LBR raw data separated by tabs:

!importlbr <LIP> <MSR_LBR_TOS> <LBR_FROM[0] LBR_TO[0] LBR_FROM[1] LBR_TO[1] ... LBR_FROM[31] LBR_TO[31]>

The output contains blocks of addresses and symbols. See more details about this command here.

See an example of the command and its output below:

> !importlbr 0xFFFFF8054D281382   0x0000000000000019   0xFFFFF8054D28878D   0xFFFFF8054D289333

LBR stack
Address               Function
...
0xfffff80543329abc    nt!PpmUpdatePerformanceFeedback+0x16c
0xfffff80543329c11    nt!PpmUpdatePerformanceFeedback+0x2c1
...

Commands

  • Enable or disable recording:

    !enablelbr

    Enable LBR recording. If CPU goes to sleep deeper to C2, the flag is cleared, so you must re-enable it manually. This command disables Intel(R) Processor Trace (Intel(R) PT).

    !disablelbr

    Disable LBR recording.

  • Import LBRs to decode:

    !importlbr <LIP> <MSR_​LBR_​TOS> <LBR_​FROM[0] LBR_​TO[0] LBR_​FROM[1] LBR_​TO[1] ... LBR_​FROM[31] LBR_​TO[31]>

    Import LBR raw data separated by tabs and print blocks of addresses and symbols. To print the flow of a block, click a corresponding link displayed in the output for the !importlbr command. The raw data must correspond to valid addresses in the actual memory space.

  • Display data:

    !showmsr

    Print the value of the MSRs corresponding to LBRs. First it prints the value of Top of Stack (TOS), which is the last branch recorded. Then it prints two columns of MSRs. If the value of MSRs is 0, nothing has been recorded and reconstruction is impossible.

    !showlbr

    Print blocks of addresses and symbols. To print the flow of a block. click a corresponding line link.

    !showlbrflow

    Print the complete reconstructed flow from all LBRs.

  • Select data to record:

    !selectring0lbr

    Enable recording branches when CPU is on ring zero.

    !filterring0lbr

    Disable recording branches when CPU is on ring zero.

    !selectring1to4lbr

    Enables recording branches when CPU is on any of the rings one to four.

    !filterring1to4lbr

    Disable recording branches when CPU is on any of the rings one to four.

    !enablepowerevent [/here]

    Enable power event tracing.

    !disablepowerevent [/here]

    Disable power event tracing.

    where:

    /here

    Option to enable of disable power event tracing on the currently selected processor only.

See also: