374 CHAPTER 14 Trace
J-Link / J-Trace (UM08001) ©
2004-2017 SEGGER Microcontroller GmbH & Co. KG
14.1 Introduction
With increasing complexity of embedded systems, demands to debug probes and util-
ities (IDE, ...) increase too. With tracing, it is possible to get an even better idea
about what is happening / has happened on the target system, in case of tracking
down a specific error. A special trace component in the target CPU (e.g. ETM on ARM
targets) registers instruction fetches done by the CPU as well as some additional
actions like execution/skipping of conditional instructions, target addresses of
branch/jump instructions etc. and provides these events to the trace probe. Instruc-
tion trace allows reproducing what instructions have been executed by the CPU in
which order, which conditional instructions have been executed/skipped etc., allowing
to reconstruct a full execution flow of the CPU.
Note: To use any of the trace features mentioned in this chapter, the CPU needs
to implement this specific trace hardware unit. For more information about which tar-
gets support tracing, please refer to
Target devices with trace support on page 380.
14.1.1 What is backtrace?
Makes use of the information got from instruction trace and reconstructs the instruc-
tion flow from a specific point (e.g. when a breakpoint is hit) backwards as far as
possible with the amount of sampled trace data.
Example scenario: A breakpoint is set on a specific error case in the source that the
application occasionally hits. When the breakpoint is hit, the debugger can recreate
the instruction flow, based on the trace data provided by J-Trace, of the last xx
instructions that have been executed before the breakpoint was hit. This for example
allows tracking down very complex problems like interrupts related ones, that are
hard to find with traditional debugging methods (stepping, printf debugging, ...) as
they change the real-time behavior of the application and therefore might make the
problem to disappear.
14.1.2 What is streaming trace?
There are two common approaches how a trace probe collects trace data:
1.
Traditional trace: Collect trace data while the CPU is running and store them in
a buffer on the trace robe. If the buffer is full, writes continues at the start of the
buffer, overwriting the oldest trace data in it. The debugger on the PC side can
request trace data from the probe only when the target CPU is halted. This allows
doing backtrace as described in
What is backtrace? on page 374.
2.
Streaming trace: Trace data is collected while the CPU is running but streamed
to the PC in real-time, while the target CPU continues to execute code. This
increases the trace buffer (and therefore the amount of trace data that can be
stored) to an theorectially unlimited size (on modern systems multiple Ter-
abytes). Streaming trace allows to implement more complex trace features like
code coverage and code profiling as these require a complete instruction flow,
not only the last xx executed instructions, to provide real valuable data.
14.1.3 What is code coverage?
Code coverage metrics are a way to describe the "quality" of code, as "code that is
not tested does not work". A code coverage analyzer measures the execution of code
and shows how much of a source line, block, function or file has been executed. With
this information it is possible to detect code which has not been covered by tests or
may even be unreachable. This enables a fast and efficient way to improve the code
or to create a suitable test suite for uncovered blocks.
Note: This feature also requires a J-Trace that supports streaming trace.