Short link: http://bit.ly/2H2rKjp
- Learn to use GDB/LLDB when you need it
- Practice basic commands
- Drills / Wax on, wax off.
- We stay high level
- What is a debugger?
- App to debug other apps
- Breakpoints
- Stepping
- Expression/Variable evaluation
- Backtrace inspection
- App to debug other apps
- Growing up with
pry
andpdb
- My primary use cases
- Getting confused from reading the code
- Getting different results than expected
- I like CLI
- Portability
- I did not find "the" great alternative
- You can explore
gui
mode
./configure --enable-debug
which is the same as-O0 -ggdb3
Command | LLDB | GDB |
---|---|---|
Loading a program | $ lldb /path/to/foo.app |
$ gdb /path/to/foo.app |
Listing breakpoints | breakpoint list |
info break |
Setting a breakpoint with file/line | breakpoint set -f foo.c -l 12 |
break test.c:12 |
Setting a breakpoint on a name | breakpoint set -n foo |
break main |
Delete breakpoints | breakpoint delete 1 |
delete 1 |
Setting watchpoints | watch set var global |
watch global_var |
Running the program (with arg) | run -txindex |
run -txindex |
Attach to program by pid | process attach --pid 123 |
attach 123 |
Attach to program by name (wait for it) | process attach --name bitcoind --waitfor |
attach -waitfor bitcoind |
Continue from breakpoint | thread continue |
continue |
Step into function | thread step-in or step |
step |
Step over function | thread step-over or next |
next |
Step out of function | thread step-out or finish |
finish |
List all threads | thread list |
info threads |
List stack frame variables | frame variable |
info args and info locals |
Print stack frame variable | frame variable foo or p foo |
p foo |
Print global variable | target variable baz |
p foo |
Set environment variables | settings set target.env-vars DEBUG=1 or env DEBUG=1 |
set env DEBUG 1 |
Evaluate an expression | expr foo() |
call foo() |
Lookup symbol information | image lookup -v -s gFoo |
info symbol 0x1ec4 |
- Shortest unique string match on command names works too, i.e.
br s -n foo
- Setting a
/.gdbinit
or/.lldbinit
- How to get out of a long loop
- Usually "standard way" of starting your debugger
- Load
bitcoind
intolldb
- Set your breakpoints
run
with arguments- Use
bitcoin-cli
if you need to, to hit the breakpoint
- Load
Where does the RPC getblockchaininfo
get values for bestblockhash
, difficulty
and mediantime
from? Find their sources.
Set a breakpoint in init.cpp
that only gets hit when -txindex
is set.
- Similar to "standard way" with some adjustments:
- Load
src/test/test_bitcoin
instead ofbitcoind
- Probably
run
with args--log_level=all --run_test=*/lthash_tests
- Load
Change one of the (or more) scripts in the test src/test/multisig_tests.cpp
during text execution to make the test fail!
- Change funtional test timeout in
test/functional/test_framework/test_framework.py
L99self.rpc_timeout = 60
to avoid timeouts while debugging. - Insert
import pdb; pdb.set_trace()
at any point in the (python) functional test before the breakpoint you would like to set is going to be hit. - Run the functional test
./test/functional/example_test.py
, it should be stopped at the inserted line. - Get the pid of the node you wnat to set the breakpoint in
self.nodes[0].process.pid
. - Start
lldb
, attaching to the pidlldb -p 12345
(which causes it to be stopped bylldb
) - Set your breakpoints and let the process
continue
from withinlldb
- Let the process
continue
from withinpdb
- The node should now run into the breakpoint in
lldb
Watch the removal of tx from the mempool in TrimToSize
using test/functional/mempool_limit.py
.
Use test/functional/wallet_avoidreuse.py
to see where the avoid reuse setting is making a difference when getting your balance.
Watch messages as they come in to a syncing node in test/functional/p2p_node_network_limited.py
(hint: ProcessMessage
).
Explore TxIndex
and BaseIndex
inheritance relationship.