Troubleshooting¶
This chapter collects the most common problems encountered when building applications with Zephelin, capturing traces and converting them for Zephelin Trace Viewer, together with their causes and solutions.
Trace capture¶
The capture command produces an empty or truncated file¶
Check the following, in order:
CONFIG_ZPL_TRACEis enabled and one of the trace formats (CONFIG_ZPL_TRACE_FORMAT_CTForCONFIG_ZPL_TRACE_FORMAT_PLAINTEXT) is selected.The backend enabled in Kconfig matches the
west zpl-*-capturecommand used - firmware built withCONFIG_ZPL_TRACE_BACKEND_DEBUGGERwill not produce traces on UART.The capture is running while the traced code executes.
The captured data is incomprehensive¶
Verify you are reading the trace UART, not the console UART. The samples select the trace UART with the
zephyr,tracing-uartchosen property in a board overlay (see samples/common/boards). If application logs are interleaved with the CTF stream, the trace is unparsable.With
CONFIG_ZPL_TRACE_FORMAT_CTF, the file is binary by design - convert it withwest zpl-prepare-traceinto a.teffile and load it into Trace Viewer for inspection. Traces generated withCONFIG_ZPL_TRACE_FORMAT_PLAINTEXTcannot be converted.
Events are missing or seem to never end¶
Events are staged in the Zephyr tracing buffer sized with CONFIG_TRACING_BUFFER_SIZE before the backend sends them out.
How an overflow manifests depends on the tracing mode:
With
CONFIG_TRACING_ASYNC(the Zephyr default), the buffer is a ring buffer and the packets that do not fit are dropped, which shows up as missing or unending events rather than as an error. IncreaseCONFIG_TRACING_BUFFER_SIZE- most samples use4096, and samples/profiling/smp_tvm needs10240- and, with the UART backend, use the highest baud rate supported by the board.With
CONFIG_TRACING_SYNC, which most Zephelin samples enable, the buffer only holds a single formatted packet, so it has to be at leastCONFIG_TRACING_PACKET_MAX_SIZEbytes. Nothing is dropped in this mode, but every event blocks the emitting thread until the backend accepts it.
USB capture does not find the device¶
west zpl-usb-capture fails with Couldn't open USB device with vid=... pid=... when the device is not enumerated yet or the identifiers do not match.
Use
-w/--wait-for-deviceto wait for the board instead of failing immediately, which is useful when the board is reset after the command starts.Make sure the USB requirements described in Trace capture USB interface requirements are met.
Converting traces¶
Zephyr CTF metadata (...) does not exist¶
The conversion merges the Zephyr and Zephelin CTF metadata, and the Zephyr part is looked up relative to the Zephyr repository. By default, the path is deduced from the script location inside the workspace, which fails when Zephelin is used outside of it.
Pass --zephyr-base to west zpl-prepare-trace or export ZEPHYR_BASE.
Function names in the trace are mangled¶
C++ symbols are demangled with c++filt taken from the Zephyr SDK.
If the conversion prints c++filt is missing, point Zephelin at a working binary with the ZPL_DEMANGLE_CMD environment variable.
Instrumentation events show raw addresses instead of function names¶
No symbols found - using callee address ... means the symbols could not be resolved from the ELF file.
The instrumentation trace has to be converted against the very same binary that was flashed on the device, so pass the matching --build-dir or --zephyr-elf-path and re-flash the board if the build directory has been rebuilt in the meantime.
Live tracing¶
Live tracing is driven by the Zephelin server, which can be started either with python server/run_backend.py or with the west zpl-live-server command.
Both accept the same arguments and can be used interchangeably, so the options mentioned below apply to either of them.
The viewer stays empty although the capture command reports incoming bytes¶
The server discards all incoming data until it finds the _zpl_ctf_start__ synchronization tag, which is emitted by the device on startup.
If the capture is started while the application is already running, the tag never arrives.
Reset the board after connecting the capture, or start the Renode simulation with --pause and unpause it once the frontend is connected, as described in Live tracing of events from the board.
CPU load, memory or die temperature samples only appear at the end of the trace¶
The periodic profilers run in their own threads, with a default priority of 5. An application that runs inferences back-to-back in a higher-priority thread without yielding starves them, so their events are only emitted once the busy loop ends, even though the trace pipeline works correctly.
Either add sleeps to the application loop, or raise the priority of the profiling threads, for example:
CONFIG_ZPL_CPU_LOAD_PROFILING_THREAD_PRIORITY=-1
CONFIG_ZPL_MEMORY_PROFILING_THREAD_PRIORITY=-1
The profiling threads sleep between the samples, so making them cooperative does not block the application.
Traces do not reach the server at all¶
--send-to-remote has to point at the TCP socket used for CTF ingestion, that is --tcp-server-port (5000 by default):
west zpl-uart-capture /dev/ttyUSB0 115200 ./trace.ctf --send-to-remote 127.0.0.1:5000
Sending the data to --bt-port (42674 by default) instead bypasses the trace handler - this port is used internally between the server and the libbtrace live plugin.
Layer profiling events are missing or appear to last forever in live mode only¶
Delayed emission makes the trace stream non-chronological, and the live pipeline renders the events as they arrive, dropping the ones older than the newest event already displayed for a given thread. Offline conversion sorts the whole trace, so the same run visualized from a file is complete.
Disable CONFIG_ZPL_TFLM_PROFILER_DELAYED_EMISSION or CONFIG_ZPL_TVM_PROFILER_DELAYED_EMISSION when using live tracing.