SymbolResolverResolve
Description
Resolve a runtime instruction pointer to a symbol.
Parameters
| Name | Direction | Description |
|---|---|---|
self |
in,out | Resolver. The cache may grow on this call. |
runtime_addr |
in | Address to resolve, as captured at runtime. |
out |
out | Populated on success. Untouched on failure. |
Success
Returns true. out->module_path is set; out->symbol_name may still be NULL if the address falls in a module range that lacks symbol coverage there.
Failure
Returns false if no loaded module contains runtime_addr, or if the resolver fails to open the backing ELF file.
Usage example (Cross-references)
Usage examples (Cross-references)
// ---------------------------------------------------------------------------
bool SymbolResolverResolve(SymbolResolver *self, void *runtime_addr, ResolvedSymbol *out) {
if (!self || !out)
return false;- In
Backtrace.c:485:
for (size i = 0; i < count; ++i) {
ResolvedSymbol r;
if (SymbolResolverResolve(resolver, frames[i].ip, &r)) {
emit_resolved_line(out, (u32)i, &r, frames[i].ip);
} else {
static bool resolve_addr(SymbolResolver *res, void *addr, ResolvedSymbol *out) {
return SymbolResolverResolve(res, addr, out);
} ResolvedSymbol r;
// Page-zero-ish address that no module maps.
bool ok = !SymbolResolverResolve(&res, (void *)(u64)0x1000, &r);
SymbolResolverDeinit(&res);
ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&test_symres_resolve_self, &r);
ok = ok && r.module_path && r.module_path[0] != '\0';
// We're a function so a symbol should resolve. Name may or may
// .symtab. libc dladdr would fail to name this; we should not.
ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&symres_marker_helper, &r);
ok = ok && r.symbol_name != NULL && ZstrFindSubstring(r.symbol_name, "symres_marker_helper") != NULL;
ResolvedSymbol ra;
bool ok = SymbolResolverResolve(&res, (void *)&sr1_marker_a, &ra) && ra.module_path;
size live1 = DebugAllocatorLiveCount(&alloc);
ResolvedSymbol rb;
ok = ok && SymbolResolverResolve(&res, (void *)&sr1_marker_b, &rb) && rb.module_path;
size live2 = DebugAllocatorLiveCount(&alloc);
ResolvedSymbol rc;
bool ok = SymbolResolverResolve(&res, (void *)&sr1_marker_a, &rc) && rc.module_path;
size live1 = DebugAllocatorLiveCount(&alloc);
ResolvedSymbol rd;
ok = ok && SymbolResolverResolve(&res, (void *)&sr_cache_data_marker, &rd) && rd.module_path;
size live2 = DebugAllocatorLiveCount(&alloc);
ResolvedSymbol ra;
bool ok = SymbolResolverResolve(&res, (void *)&sr1_marker_a, &ra) && ra.module_path;
u64 other = 0;
ResolvedSymbol ro;
ok = ok && SymbolResolverResolve(&res, (void *)other, &ro) && ro.module_path;
size live2 = DebugAllocatorLiveCount(&alloc);
ResolvedSymbol ra;
bool ok = SymbolResolverResolve(&res, (void *)&sr1_marker_a, &ra) && ra.module_path;
u64 other = 0;
ResolvedSymbol r1;
ok = ok && SymbolResolverResolve(&res, (void *)other, &r1) && r1.module_path;
size live1 = DebugAllocatorLiveCount(&alloc);
ResolvedSymbol r2;
ok = ok && SymbolResolverResolve(&res, (void *)other, &r2) && r2.module_path;
size live2 = DebugAllocatorLiveCount(&alloc); }
ResolvedSymbol r;
bool ok = SymbolResolverResolve(&res, (void *)&sr1_marker_a, &r);
SymbolResolverDeinit(&res); }
ResolvedSymbol r;
if (!SymbolResolverResolve(&res, (void *)func, &r)) {
SymbolResolverDeinit(&res);
DefaultAllocatorDeinit(&alloc);- In
Dwarf.c:54:
ResolvedSymbol r;
if (!SymbolResolverResolve(&res, (void *)&dwarf_marker_helper, &r)) {
SymbolResolverDeinit(&res);
DefaultAllocatorDeinit(&alloc);- In
Dwarf.c:100:
ResolvedSymbol r;
if (!SymbolResolverResolve(&res, (void *)&dwarf_marker_helper, &r)) {
SymbolResolverDeinit(&res);
DefaultAllocatorDeinit(&alloc);- In
Dwarf.c:163:
ResolvedSymbol r;
if (!SymbolResolverResolve(&res, (void *)&dwarf_marker_helper, &r)) {
SymbolResolverDeinit(&res);
DefaultAllocatorDeinit(&alloc);
Last updated on