find_call_path
Trace how one C/C++ function reaches another via BFS in the libclang call graph, following function-pointer, ISR, dispatch, and constructor edges to reveal the call chain.
Instructions
Find call paths between two C/C++ functions via BFS in the libclang call graph, including function-pointer edges, ISR vector registrations, implicit constructors, and synthetic dispatch edges (event loops, thread starts). libclang-powered: follows function-pointer edges and ISR vector registrations that text-based search cannot resolve.
Use to answer "how does A reach B?" — e.g. tracing how a high-level
event handler eventually calls a low-level driver. Returns up to 5
distinct paths in BFS order (short paths first), each with depth
(edge count) and chain
(e.g. "main → app_run → modem_init").
Edge types traversed: The BFS includes call, indirect
(function pointers / ISRs), implicit_construct (global/static
object constructors), and dispatch (synthetic edges through event
loops like EventQueue::dispatch_forever and thread starts like
Thread::start).
Limitations:
Dispatch bridges: callbacks registered through
EventQueue::call_every,k_work_submit, orxTimerStartreach their dispatch entry point (dispatch_forever,z_work_q_main) through a built-in map for mbed-os, Zephyr, and FreeRTOS. Add other RTOS patterns in[call_graph.dispatch_bridges](.fw-context/config.toml); a bridge whose entry symbol is not in the index is skipped silently.Ambiguous fallback names: for a call that libclang cannot resolve (template-obscured
_timeout.attach(...)), a source-line regex matches the method name. When several methods share that unqualified name and neither the receiver field type nor the caller class disambiguates, fw-context creates NO edge — conservative, to avoid false paths.Global constructors: file-scope
implicit_constructedges hang off a synthetic<global ctors>node betweenmainand every global constructor. Any query that can reachmainuses it, not only a query that starts atmain.
On an empty result that you expected to hold a path: look for async
dispatch (search_bodies("call_every"), search_bodies("attach")),
trace the intermediate symbols with find_callers, raise
max_depth, and check the function-pointer wiring with
find_indirect_call_sites / find_indirect_targets.
For one-sided exploration use find_all_callers_recursive (who reaches
this?) or find_callees_recursive (what does this reach?).
For exact call-graph verification use find_callers or
find_references.
Read-only. No side effects. Requires both symbols to be in the index
and refs enabled (fw-context index — refs on by default).
Args:
from_name: Starting symbol for path search.
to_name: Target symbol to find path to.
project_root: Project root. Auto-detected if omitted.
project: Project name or project_id — call list_projects to get them. Use
it to ask about a project that is not the project of the current
directory. It is an alternative to project_root, which takes a root
path. Give one of the two, not both.
max_depth: Maximum BFS depth for path search (default 10). The
search runs from both ends, and each end goes up to
max_depth hops, thus a path can hold up to 2 × max_depth
edges. No clamp holds this number. What bounds a deep search is
the node budget of the walk — 5000 expansions — thus a large
depth gives up on that budget and not on the depth.
variant: Variant of the build (a board, or a PlatformIO
environment). On a project of more than one build, give the
arguments of one build as the refusal lists them: the
variant, the image, or the two. fw-context does not select a
build. One query answers for ONE build.
image: Image of the build: a separate program, such as the
application or the bootloader. Give it when the build has an
image name.
Returns:
At most 5 paths, each a dict with: depth (edge count, int), chain (str —
e.g. "main → app_run → modem_init"), target_usr (str — the USR
of the symbol the path ends at, which tells two overloads apart).
When no path exists within the depth limit, the list holds one
info dict.
The number of paths cannot be counted, thus this tool has no page
notice and no ``offset``. A trailing ``info`` dict says when paths
can be left out: the search found 5 paths and stopped, it spent
its budget of node expansions, or a direct call answered and the
longer paths were not searched. After a spent budget an empty
answer says that a path can still exist, and NOT "no path". The
paths come in a fixed order: the same query gives the same paths.
When *to_name* matches more than one symbol, the search reaches
all of them. A ``warning`` dict then comes first and names the
symbols, and each path carries ``target_qualified_name`` next to
``target_usr``. Give the full qualified name to ask about one
symbol only.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | Image of the build: a separate program, such as the application or the bootloader. On a project of more than one build, give it when that build has an image name, as the refusal lists it. | |
| project | No | Project name or project_id — call list_projects to get them. Use it to ask about a project that is not the project of the current directory. It is an alternative to project_root, which takes a root path. Give one of the two, not both. | |
| to_name | Yes | Target symbol to find path to. | |
| variant | No | Variant of the build (a board, or a PlatformIO environment). On a project of more than one build, give the arguments of one build as the refusal lists them: the variant, the image, or the two. fw-context does not select a build for you. One query answers for ONE build. | |
| from_name | Yes | Starting symbol for path search. | |
| max_depth | No | Maximum BFS depth from each end of the search (default 10). A path can hold up to 2 x max_depth edges. | |
| project_root | No | Project root. Auto-detected if omitted. This field also accepts a project name or a project_id, but project is the clear field for those. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |