/*
* Copyright CC0 Angel Leon <@gubatron>
*/
Update: I believe now it's better to use lldb
, at least on MacOS, here's a LLDB to GDB command map
Here's how to use gdb
to debug issues you might be having hacking bitcoinclassic (or any other C++ program)
If you're in Ubuntu you might want to have the following packages installed
sudo apt install git build-essential pkg-config dh-autoreconf libtool autotools-dev automake libssl-dev libevent-dev bsdmainutils libzmq3-dev libminiupnpc-dev libboost-all-dev
We'll also need to add an apt repo to install berkley db dependencies
sudo add-apt-repository ppa:bitcoinclassic/bitcoinclassic
sudo apt-get update
sudo apt-get install libdb4.8-dev libdb4.8++-dev
Check out the main repo
git clone https://github.com/bitcoinclassic/bitcoinclassic
Make sure to have it forked on github to your account, now let's add your remote clone to our local instance
cd bitcoinclassic
git remote add myusername https://github.com/myusername/bitcoinclassic
Now when you create a branch or have commits to push you push them to your myusername
remote.
./autogen.sh
./configure --enable-debug
make -j 8
make clean; ./configure --enable debug; make -j 8
To compile ongoing code changes
make -j 8
If everything went fine, you should see output similar to...
AR libbitcoin_wallet.a
CXXLD bitcoin-cli
CXXLD bitcoin-tx
CXXLD bitcoind
CXXLD test/test_bitcoin
make[1]: Nothing to be done for `all-am'.
First make sure you're in the folder where our executable bitcoind
is
cd src
On my mac I have to run it with sudo
$ sudo gdb
Password:
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin16.7.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb)
Now let's load the executable we're about to debug, with the file
command.
(gdb) file bitcoind
Reading symbols from bitcoind...warning: dsym file UUID doesn't match the one in /Users/gubatron/workspace.frostwire/bitcoinclassic/src/bitcoind
warning: can't find symbol '_Z10ParseHexUVRK8UniValueRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE' in minsymtab
warning: can't find symbol '_Z21getAllNetMessageTypesv' in minsymtab
warning: can't find symbol '_ZN9Streaming10BufferPool10writeInt32Ej' in minsymtab
done.
You can alternatively start gdb
and pass the executable as an argument
$ gdb bitcoind
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin16.7.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bitcoind...
warning: dsym file UUID doesn't match the one in /Users/gubatron/workspace.frostwire/bitcoinclassic/src/bitcoind
warning: can't find symbol '_Z10ParseHexUVRK8UniValueRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE' in minsymtab
warning: can't find symbol '_Z21getAllNetMessageTypesv' in minsymtab
warning: can't find symbol '_ZN9Streaming10BufferPool10writeInt32Ej' in minsymtab
done.
If you know where you want your program to start before hand you can set breakpoints before you run it.
Now that we have a symbol table loaded, let's set up a few breakpoints. We do that with the b <filename>:<linenumber>
command
(gdb) b main.cpp:3560
Breakpoint 1 at 0x1001c8ac8: file main.cpp, line 3560.
(gdb) b bitcoind.cpp:174
Breakpoint 2 at 0x1000091a2: file bitcoind.cpp, line 174.
(gdb) b init.cpp:164
Breakpoint 3 at 0x1000b22c8: file /usr/local/include/boost/signals2/detail/slot_groups.hpp, line 164.
(gdb) b init.cpp:174
Breakpoint 4 at 0x1000b25c3: file init.cpp, line 174.
Since the file is loaded, we can tell gdb
to "run
", the run
command can receive the arguments we pass to our executable.
If we want to setup a break point at the start and run it, we can do a b main
and then run <my program args
, or we can use the shortcut start <myprogram args>
macOS caveat: If you're doing this tutorial from a Mac and you're getting an error like this:
(gdb) run -server -keypool=1 -rest -discover=0 -testnet -datadir=/Users/gubatron/tmp/bitcoind
Starting program: /Users/gubatron/workspace.frostwire/bitcoinclassic/src/bitcoind -server -keypool=1 -rest -discover=0 -testnet -datadir=/Users/gubatron/tmp/bitcoind
During startup program terminated with signal ?, Unknown signal.
create or edit your ~/.gdbinit
file and add the following line and restart gdb:
set startup-with-shell off
So let's start our program and set a breakpoint at the start (make sure the datadir folder exists beforehand):
(gdb) start -server -keypool=1 -rest -discover=0 -testnet -datadir=/Users/gubatron/tmp/bitcoind
Temporary breakpoint 1 at 0x1000099e4: file bitcoind.cpp, line 187.
Starting program: /Users/gubatron/workspace.frostwire/bitcoinclassic/src/bitcoind -server -keypool=1 -rest -discover=0 -testnet -datadir=/Users/gubatron/tmp/bitcoind
[New Thread 0x1903 of process 30164]
warning: unhandled dyld version (15)
Thread 2 hit Temporary breakpoint 1, main (argc=7, argv=0x7fff5fbff628) at bitcoind.cpp:187
187 SetupEnvironment();
Since this view isn't the friendliest of all, here's a cool trick, press Ctrl-x-s
With Ctrl-x-2
you get multiple windows, so you can see the stack.
MacBook-Pro:src gubatron$ sudo lldb bitcoind
Password:
(lldb) target create "bitcoind"
Current executable set to 'bitcoind' (x86_64).
(lldb) b main
Breakpoint 1: where = bitcoind`main + 36 at bitcoind.cpp:202, address = 0x00000001000097e4
(lldb) run -server -keypool=1 -rest -discover=0 -testnet -datadir=/Users/gubatron/tmp/bitcoind There is a running process, kill it and restart?: [Y/n] Y
Process 85476 exited with status = 9 (0x00000009)
Process 85483 launched: '/Users/gubatron/workspace.frostwire/bitcoin-abc/src/bitcoind' (x86_64)
Process 85483 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00000001000097e4 bitcoind`main(argc=7, argv=0x00007fff5fbff630) at bitcoind.cpp:202
199 }
200
201 int main(int argc, char *argv[]) {
-> 202 SetupEnvironment();
203
204 // Connect bitcoind signal handlers
205 noui_connect();
Target 0: (bitcoind) stopped.
Then type gui
and enjoy the view.
how can i debug any rpc call through lldb ?