Intel® System Debugger User Guide
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:
Power the target on and let Windows* start.
Launch Intel(R) Debug Extensions for WinDbg*. The
sysdbg64.dll is loaded automatically.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.
Press F5 or type g in the terminal to run the target for a while.
Stop the target by pressing the break button in the toolbar.
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.
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.