When using the bcc
tool funclatency
, there are unknown function names.
It would be helpful if I could track the entry and return values of a number of functions contained in the library ibverbs
(Infiniband).
I use funclatency
to print a histogram of the ibverbs
functions called by perftest
.
https://github.com/iovisor/bcc/tree/master/tools
To send packages between two nodes, I use the perftest
.
https://github.com/linux-rdma/perftest
To compile the perftest application, I used the following compiler flags:
CFLAGS = -g -Wall -D_GNU_SOURCE -O3 -ggdb3 -O2 -fno-omit-frame-pointer
System:
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye
I use funclatency like this:
sudo funclatency-bpfcc ibverbs:ibv_get*
funclatency output:
Tracing 13 functions for "ibverbs:ibv_get*"... Hit Ctrl-C to end.
Function = b'[unknown]' [784402]
nsecs : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 0 | |
64 -> 127 : 0 | |
128 -> 255 : 0 | |
256 -> 511 : 0 | |
512 -> 1023 : 0 | |
1024 -> 2047 : 468 |**************************** |
2048 -> 4095 : 512 |****************************** |
4096 -> 8191 : 664 |****************************************|
8192 -> 16383 : 332 |******************** |
16384 -> 32767 : 14 | |
32768 -> 65535 : 3 | |
65536 -> 131071 : 6 | |
131072 -> 262143 : 0 | |
262144 -> 524287 : 0 | |
524288 -> 1048575 : 0 | |
1048576 -> 2097151 : 0 | |
2097152 -> 4194303 : 0 | |
4194304 -> 8388607 : 0 | |
8388608 -> 16777215 : 1 | |
Here is the source code for the translation of a memory address into a function name:
https://github.com/iovisor/bcc/blob/master/src/python/bcc/init.py
def sym(addr, pid, show_module=False, show_offset=False, demangle=True):
"""sym(addr, pid, show_module=False, show_offset=False)
Translate a memory address into a function name for a pid, which is
returned. When show_module is True, the module name is also included.
When show_offset is True, the instruction offset as a hexadecimal
number is also included in the string.
A pid of less than zero will access the kernel symbol cache.
Example output when both show_module and show_offset are True:
"start_thread+0x202 [libpthread-2.24.so]"
Example output when both show_module and show_offset are False:
"start_thread"
"""
#addr is of type stacktrace_build_id
#so invoke the bsym address resolver
typeofaddr = str(type(addr))
if typeofaddr.find('bpf_stack_build_id') != -1:
sym = bcc_symbol()
b = bcc_stacktrace_build_id()
b.status = addr.status
b.build_id = addr.build_id
b.u.offset = addr.offset
res = lib.bcc_buildsymcache_resolve(BPF._bsymcache,
ct.byref(b),
ct.byref(sym))
if res < 0:
if sym.module and sym.offset:
name,offset,module = (None, sym.offset,
ct.cast(sym.module, ct.c_char_p).value)
else:
name, offset, module = (None, addr, None)
else:
name, offset, module = (sym.name, sym.offset,
ct.cast(sym.module, ct.c_char_p).value)
else:
name, offset, module = BPF._sym_cache(pid).resolve(addr, demangle)
offset = b"+0x%x" % offset if show_offset and name is not None else b""
name = name or b"[unknown]"
name = name + offset
module = b" [%s]" % os.path.basename(module) \
if show_module and module is not None else b""
return name + module
How can I read the function name correctly? It should not just return b'[unknown]'!