# The following three lines are from the erl wrapper,
# which is usually called instead of erlexec itself
export ROOTDIR="/home/jay/.local/OTP-23.3.4.8-debug/lib/erlang"
export BINDIR=$ROOTDIR/erts-11.2.2.7/bin
export EMU=beam
cgdb ~/.local/OTP-23.3.4.8-debug/lib/erlang/erts-11.2.2.7/bin/erlexec
We can't set a breakpoint on a NIF which isn't loaded yet. So we first tell GDB to treat unknown breakpoints as pendind, then we set the breakpoint of the NIF we're interested in.
(gdb) set breakpoint pending on
(gdb) break ep_node.c:714 if spot->node == 0
No source file named ep_node.c.
Breakpoint 1 (ep_node.c:714 if spot->node == 0) pending.
Start the Erlang emulator and evaluate some source we know will lead to the NIF we're interested in.
(gdb) run -pa _build/default/checkouts/enif_protobuf/ebin -pa _build/default/lib/*/ebin/ -noshell -eval "enif_protobuf:load_cache(libp2p_peer_pb:get_proto_defs()), init:stop()"
Thread 5 "1_scheduler" hit Breakpoint 1, stack_ensure_all (env=0x7fffb447ed70, cache=0x7fffb60011f8) at /home/jay/he/erlanglibp2p/_build/default/lib/enif_protobuf/c_src/ep_node.c:714
(gdb) info locals
i = 0
j = 1
stack_size = 93824994084036
spot = 0x7fffb6002158
field = 0x7fffb6001788
stack = 0x7fffb6000bb8
state = 0x7fffb6000960
(gdb) p *spot
$1 = {
type = 1,
need_length = 0 '\000',
sentinel_size = 0,
pos = 0,
node = 0x0,
field = 0x0,
array = 0x0,
list = 0,
t_arr = 0x0,
t_size = 0,
t_used = 0,
result = 0,
end_sentinel = 0x0
}