Debugger: Threads and Traces

In general, a thread refers to a unit of concurrent execution within a target. Typically, each thread carries its own execution context, so this window provides a means of navigating those contexts. Furthermore, this window provides a means of navigating and managing open traces, much like the static listing provides a means of navigating open programs. The window also plots a timeline showing thread lifespans, and displays a caret which can be used to navigate the current point in time. This window, the Stack window, and the Dynamic Listing window provide a complete trace navigation system.

Trace Tabs

The trace tab bar is displayed when at least one trace is open. It displays the name of each open trace in a button, where the "current" or "focused" trace is selected. Clicking a tab will select its trace and focus the tool onto it. A trace associated with a live target has a red "recording" icon at its left. If that icon is not present, or has disappeared, the trace is dead or terminated. A "dead" trace can still be manipulated and marked up, but it will not record any new target information.

Close Trace / All / Other / Dead Traces

In most cases, a trace is ephemeral, but occasionally, interesting behavior is observed that is difficult to store as static mark-up. When traces are no longer needed, they can be closed by right-clicking a tab and selecting one of the actions. See Trace Management for details of each action.

Navigating Threads

Selecting a thread in the table will navigate to (or "activate" or "focus") that thread. Windows which are sensitive to the current thread will update. Notably, the Registers window will display the activated thread's register values. Listing windows with configured location tracking will re-compute that location with the thread's context and navigate to it. The thread timeline plots all recorded threads. Threads which are alive will appear to extend "to the end of time." The threads table displays more detailed information in the following columns:

Navigating Time

The user can navigate through time within the current trace by using the caret in the plot column header. There are also actions for "stepping the trace" forward and backward. See the Time window for a way to display and navigate to specific events in the trace's timeline. Note that stepping away from the present will prevent most windows from interacting with the live target. While some components and scripts may interact with the target and record things "into the present," such updates may not appear on screen until the user steps back to the present. Stepping the trace does not affect the target, except that viewing the present requires querying the live target, which can perturb its state.

Step Trace Snap Backward

This action is available when there exists a snapshot previous to the current. It steps the trace backward to the previous snapshot, causing most windows to display the recorded data from the new point in time.

Step Trace Snap Forward

This action is available when there exists a snapshot ahead of the current. It steps the trace forward to the next snapshot, causing most windows to display the recorded data from the new point in time.

Emulate Trace Tick Backward

This action is available when the current point in time includes emulated steps. It steps the trace backward to the previous tick.

Emulate Trace Tick Forward

This action is available when a thread is selected. It steps the current thread forward to the next tick, using emulation. Note that emulation does not affect the target. Furthermore, emulation may halt early if it encounters certain instructions or causes an exception.

Seek Trace to Present

This toggle is always available and is enabled by default. When first enabled, if the current trace is live, it immediately steps the trace to the present. Furthermore, as long as it is enabled and the current trace is live, whenever the recorder steps forward, the tool steps with it. In most cases, this option should remain on, otherwise stepping the target will not cause any windows to update. Toggling it off then on is a quick way to return to the present after browsing the past.

Go To Time

This action is available when a trace is active. It prompts for a Time Schedule expression. This is the same form as the expression in the title bar of the threads window. In many cases, it is simply the snapshot number, e.g., 3, which will go to the snapshot with key 3. It may optionally include an emulation schedule, for example, 3:10 will use snapshot 3 for an emulator's initial state and step 10 machine instructions on snapshot 3's event thread. If the snapshot does not give an event thread, then the thread must be specified in the expression, e.g., 3:t1-10. That expression will start at snapshot 3, get the thread with key 1, and step it 10 machine instructions. The stepping commands can be repeated any number of times, separated by semicolons, to step threads in a specified sequence, e.g., 3:t1-10;t2-5 will do the same as before, then get thread 2 and step it 5 times.

The emulator's state can also be modified by the schedule. Instead of specifying a number of steps, write a Sleigh statement, e.g., 3:t1-{r0=0x1234};10. This will start at snapshot 3, patch thread 1's r0 to 0x1234, then step 10 instructions. Like stepping commands, the thread may be omitted for Sleigh commands. Each command without a thread specified implicitly uses the one from the previous command, or in the case of the first command, the event thread. Only one Sleigh statement is permitted per command.

A second command sequence may be appended, following a dot, to command the emulator at the level of p-code operations as well. This is particularly useful when debugging a processor specification. See also the P-code Stepper window. For example, 3:2.10 will start at snapshot 3 and step the event thread 2 machine instructions, followed by 10 p-code operations. The same thread-by-thread sequencing and state patching commands are allowed in the p-code command sequence. The entire instruction sequence precedes the entire p-code sequence, i.e., only a single dot is allowed. Once the expression enters p-code mode, it cannot re-enter instruction mode.

Other Actions

Synchronize Trace and Target Focus

This toggle is always available and is enabled by default. While enabled, any changes in navigation coordinates are translated, to the extent possible, and sent to the connected debugger. This may, for example, issue thread and/or frame commands to GDB so that commands typed into its CLI will refer to the same thread and frame as is focused in Ghidra. Conversely, any debugger events which indicate a change in focus are translated, to the extent possible, into navigation coordinates and activated in Ghidra. For example, if the user issues a frame command to the CLI of a GDB connection, then Ghidra will navigate to that same frame.