用vim單步調(diào)試bitcoin
區(qū)塊#0. 前言
參加了區(qū)塊鏈研習(xí)社的源碼研讀班,準(zhǔn)備研讀下比特幣核心(Bitcoin Core)的源碼界赔,為了更好的掌握其脈絡(luò)丢习,單步調(diào)試是必不可少的牵触,那么就先來準(zhǔn)備下環(huán)境吧~
這里通過vim+vimgdb插件,來構(gòu)造一個gdb的調(diào)試環(huán)境咐低。
區(qū)塊#1. 環(huán)境搭建
1.1 vim環(huán)境
安裝vim+vimgdb插件揽思,該插件以補丁方式提供,需要重新編譯安裝vim见擦,有些遺憾該插件很久沒有更新了钉汗,目前僅支持vim7.4版本。
1.1.1 源碼下載
- vim7.4及對應(yīng)vimgdb插件下載
$ wget https://github.com/vim/vim/archive/v7.4.tar.gz
$ git clone https://github.com/cpiger/vimgdb-for-vim7.4.git
1.1.2 打上補丁
- 解壓vim7.4并打上vimgdb補丁
$ tar -zxf v7.4.tar.gz
$ ln -s vim-7.4/ vim74
$ patch -p0 < vimgdb-for-vim7.4/vim74.patch
patching file vim74/src/auto/configure
patching file vim74/src/buffer.c
patching file vim74/src/clewn/gdb.h
patching file vim74/src/clewn/gdb_lvl2.c
patching file vim74/src/clewn/gdb_lvl3.c
patching file vim74/src/clewn/misc.c
patching file vim74/src/clewn/misc.h
patching file vim74/src/clewn/obstack.c
patching file vim74/src/clewn/obstack.h
patching file vim74/src/config.h.in
patching file vim74/src/config.mk.in
patching file vim74/src/configure.in
patching file vim74/src/eval.c
patching file vim74/src/ex_cmds.c
patching file vim74/src/ex_getln.c
patching file vim74/src/feature.h
patching file vim74/src/gdb.c
patching file vim74/src/globals.h
patching file vim74/src/gui.c
patching file vim74/src/gui_gtk_x11.c
patching file vim74/src/gui_x11.c
patching file vim74/src/main.c
patching file vim74/src/Makefile
patching file vim74/src/normal.c
patching file vim74/src/option.c
patching file vim74/src/option.h
patching file vim74/src/os_unix.c
patching file vim74/src/proto/gdb.pro
patching file vim74/src/proto.h
patching file vim74/src/screen.c
patching file vim74/src/structs.h
patching file vim74/src/version.c
patching file vim74/src/window.c
若沒有任何錯誤信息鲤屡,即打補丁成功损痰。
1.1.3 編譯安裝
(1)執(zhí)行configure命令
$ cd vim74/
$ ./configure --with-features=huge --enable-pythoninterp --with-python-config-dir=/usr/lib/python2.7/config-x86_64-linux-gnu/ --enable-perlinterp --enable-cscope --enable-multibyte --enable-xim --enable-gdb --prefix=/home/rzexin/Software/ALL/vimgdb
核心參數(shù)是:--enable-gdb,根據(jù)需要開啟其他屬性
參數(shù)說明:
- --enable-gdb:開啟gdb支持
- --with-features=huge:支持最大特性
- --enable-pythoninterp:啟用Vim對python編寫的插件的支持
- --enable-multibyte和--enable-xim:需要在Vim中輸入中文酒来,開啟這兩個特性
- --enable-cscope:Vim對cscope支持
- --with-python-config-dir=/usr/lib/python2.7/config-x86_64-linux-gnu/ 指定 python 路徑
- --prefix=/home/rzexin/Software/ALL:設(shè)定編譯安裝路徑
(2)修改Makefile文件
設(shè)置--prefix并未修改src/Makefile中的配置卢未,將以下三行注釋掉,以便vim可以安裝到我們指定的目錄
# BINDIR = /opt/bin
# MANDIR = /opt/share/man
# DATADIR = /opt/share
(3)編譯&安裝
-j:是make命令執(zhí)行線程數(shù)堰汉,可根據(jù)機器性能調(diào)大一點尝丐,縮短編譯等待時間
CFLAGS="-O2 -D_FORTIFY_SOURCE=1":不加該參數(shù),安裝后啟動vim會core
$ make -j2 CFLAGS="-O2 -D_FORTIFY_SOURCE=1"
$ make install
$ tree -L 2 ~/Software/ALL/vimgdb/
/home/rzexin/Software/ALL/vimgdb/
├── bin
│ ├── ex -> vim
│ ├── rview -> vim
│ ├── rvim -> vim
│ ├── view -> vim
│ ├── vim
│ ├── vimdiff -> vim
│ ├── vimtutor
│ └── xxd
└── share
├── man
└── vim
1.1.4 環(huán)境配置
(1)設(shè)置環(huán)境變量
之所以要安裝到/home/rzexin/Software/ALL/vimgdb目錄衡奥,還是因為vimgdb插件支持的vim版本過低,會導(dǎo)致不少基于高版本vim的插件使用不了远荠,如:vim-go(v7.4.1689+)矮固、YouCompleteMe(v7.4.1578+)等。
$ vim
vim-go requires Vim 7.4.1689 or Neovim, but you're using an older version.
Please update your Vim for the best vim-go experience.
If you really want to continue you can set this to make the error go away:
let g:go_version_warning = 0
Note that some features may error out or behave incorrectly.
Please do not report bugs unless you're using Vim 7.4.1689 or newer.
YouCompleteMe unavailable: requires Vim 7.4.1578+.
Press ENTER or type command to continue
通過別名方式譬淳,單獨提供一個專門用于gdb調(diào)試的vim:
vimg
档址,vim
命令還是對應(yīng)系統(tǒng)自帶vim
alias vimg='/home/rzexin/Software/ALL/vimgdb/bin/vim'
(2)拷貝運行環(huán)境配置
$ cp -r vimgdb-for-vim7.4/vimgdb_runtime/* ~/.vim
(3)激活命令幫助
$ cd ~/.vim/doc/
$ vimg
執(zhí)行命令:helptags .
,而后就能使用:help vimgdb
打開vimgdb的幫助文檔了:
1.2 bitcoin環(huán)境
安裝好vim及vimgdb插件后,我們下面來獲取bitcoin-core源碼了邻梆。
1.2.1 源碼下載
下載當(dāng)前最新版本
$ wget https://github.com/bitcoin/bitcoin/archive/v0.16.2.tar.gz
$ tar -zxvf v0.16.2.tar.gz
$ tree -L 1 bitcoin-0.16.2/
bitcoin-0.16.2/
├── autogen.sh
├── build-aux
├── configure.ac
├── contrib
├── CONTRIBUTING.md
├── COPYING
├── depends
├── doc
├── INSTALL.md
├── libbitcoinconsensus.pc.in
├── Makefile.am
├── README.md
├── share
├── src
└── test
1.2.2 編譯安裝
注:需開啟debug參數(shù):
--enable-debug
$ cd ~/BlockChain/Bitcoin/bitcoin-0.16.2/
$ ./autogen.sh
$ ./configure --enable-debug --prefix=/home/rzexin/Software/ALL/bitcoin
Options used to compile and link:
with wallet = yes
with gui / qt = yes
qt version = 5
with qr = auto
with zmq = no
with test = yes
with bench = yes
with upnp = auto
use asm = yes
debug enabled = yes
werror = no
target os = linux
build os =
CC = gcc
CFLAGS = -g -O2 -g3 -O0
CPPFLAGS = -DDEBUG -DDEBUG_LOCKORDER -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS
CXX = g++ -std=c++11
CXXFLAGS = -g -O2 -g3 -O0 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wno-unused-parameter -Wno-implicit-fallthrough
LDFLAGS =
ARFLAGS = cr
$ make -j2 && make install
$ tree ~/Software/ALL/bitcoin/
/home/rzexin/Software/ALL/bitcoin/
├── bin
│ ├── bench_bitcoin
│ ├── bitcoin-cli
│ ├── bitcoind
│ ├── bitcoin-qt
│ ├── bitcoin-tx
│ ├── test_bitcoin
│ └── test_bitcoin-qt
├── include
│ └── bitcoinconsensus.h
├── lib
│ ├── libbitcoinconsensus.a
│ ├── libbitcoinconsensus.la
│ ├── libbitcoinconsensus.so -> libbitcoinconsensus.so.0.0.0
│ ├── libbitcoinconsensus.so.0 -> libbitcoinconsensus.so.0.0.0
│ ├── libbitcoinconsensus.so.0.0.0
│ └── pkgconfig
│ └── libbitcoinconsensus.pc
└── share
└── man
└── man1
├── bitcoin-cli.1
├── bitcoind.1
├── bitcoin-qt.1
└── bitcoin-tx.1
- 可執(zhí)行文件說明
程序名 | 說明 |
---|---|
bitcoind | 比特幣運行的核心程序俗稱bitcoin core |
bitcoin-cli | Bitcoind的一個功能完備的RPC客戶端守伸,包括查詢區(qū)塊,交易信息等等 |
bitcoin-qt | 比特幣錢包 |
bitcoin-tx | 比特幣交易處理模塊浦妄,支持交易的查詢和創(chuàng)建 |
test_bitcoin | 運行各個模塊的測試代碼 |
test_bitcoin-qt | 運行錢包的模塊測試代碼 |
1.2.3 環(huán)境配置
(1)配置PATH和LD_IBRARY_PATH
export PATH=/home/rzexin/Software/ALL/bitcoin/bin:$PATH
export LD_LIBRARY_PATH=/home/rzexin/Software/ALL/bitcoin/lib:$LD_LIBRARY_PATH
(2)配置幫助文檔
export MANPATH=/home/rzexin/Software/ALL/bitcoin/share/man:$MANPATH
# man幫助手冊彩色輸出
export LESS_TERMCAP_mb=$'\E[01;31m'
export LESS_TERMCAP_md=$'\E[01;31m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m'
export LESS_TERMCAP_so=$'\E[01;44;33m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;32m'
通過上述配置尼摹,可以使用man命令查看到幫助文檔,且是彩色打印便于查看:
$ man bitcoind
1.2.4 錢包啟動
很好奇當(dāng)前(2018.08.14)比特幣賬本總的大小剂娄,故啟動看看:)
已經(jīng)有
203GB
蠢涝!好吧,我可憐的256GB本兒阅懦,就別指望同步下來了:(
區(qū)塊#2. 調(diào)試實踐
2.1 vim單步調(diào)試小demo
2.1.1 準(zhǔn)備demo
一個計算階乘小demo
// $ cat main.cpp
#include <stdio.h>
extern int factor(int n, int *rt);
int main(int argc, char **argv)
{
int i;
int result = 1;
for (i = 1; i < 6; i++)
{
factor(i, &result);
printf("%d! = %d\n", i, result);
}
return 0;
}
//$ cat factor.cpp
int factor(int n, int *r)
{
if (n <= 1)
{
*r = n;
}
else
{
factor(n - 1, r);
*r *= n;
}
return 0;
}
編譯&執(zhí)行:
$ g++ -g -Wall -o demo main.cpp factor.cpp
$ ./demo
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
2.1.2 vimrc配置
""""""""""""""""""""""""""""""""""
" => vimgdb
""""""""""""""""""""""""""""""""""
let g:vimgdb_debug_file = ""
run macros/gdb_mappings.vim
map <F2> :run macros/gdb_mappings.vim<CR>
nmap <leader>g :bel 40vsplit gdb-variables<cr>
2.1.3 單步調(diào)試實踐
(1)使用前面自己編譯的vim打開源碼
$ vimg main.cpp
(2)按F2
鍵和二,相當(dāng)于執(zhí)行::run macros/gdb_mappings.vim
,加載vimgdb補丁的綁定
(3)按F7
鍵,進(jìn)行gdb keys mapped
耳胎,開啟gdb調(diào)試功能
(4)點擊空格
惯吕,下方出現(xiàn)調(diào)試交互窗口
(5)在交互窗口中惕它,輸入file demo
,綁定我們前面生成的可執(zhí)行文件
執(zhí)行后废登,將會看到如下提示信息:
(gdb) file demo
Reading symbols from demo...done.
(6)使用CTRL+B
設(shè)置斷點
(7)執(zhí)行R
啟動程序淹魄,或在控制窗口中執(zhí)行run
命令
可見demo停在斷點出
(8)使用CTRL+n
單步執(zhí)行,使用C
進(jìn)行continue
(9)使用,g
打開變量窗口
(10)通過CTRL+v
選中變量钳宪,通過CTRL+p
添加變量到變量窗口中揭北,便于觀察執(zhí)行過程中值的變化
(11)在12行通過執(zhí)行S
單步進(jìn)入factor函數(shù),同樣的方法吏颖,將*r
也添加進(jìn)變量窗口
(12)單機空格
進(jìn)入命令窗口搔体,執(zhí)行quit
,結(jié)束gdb調(diào)試
2.1.4 更多指令
執(zhí)行
:help gdb-mappings
可查看
按鍵 | 用途 |
---|---|
<Space> | launch the interactive gdb input-line window |
CTRL-Z | send an interrupt to GDB and the program it is running |
B | info breakpoints |
L | info locals |
A | info args |
S | step |
I | stepi |
CTRL-N | next: next source line, skipping all function calls |
X | nexti |
F | finish |
R | run |
Q | quit |
C | continue |
W | where |
CTRL-U | up: go up one frame |
CTRL-D | down: go down one frame |
CTRL-B | set a breakpoint on the line where the cursor is located |
CTRL-E | clear all breakpoints on the line where the cursor is located |
CTRL-P | Normal mode: print value of word under cursor |
CTRL-X | print value of data referenced by word under cursor |
2.2 vim單步調(diào)試bitcoind
接下來就是激動人心的比特幣核心源碼的單步調(diào)試了
2.2.1 進(jìn)入安裝目錄
我們可看到源碼和可執(zhí)行程序都在一個目錄
$ cd /home/rzexin/BlockChain/Bitcoin/bitcoin-0.16.2/src
$ ls bitcoind bitcoind.cpp
bitcoind bitcoind.cpp
2.2.2 單步調(diào)試實踐
(1)打開源碼文件
$ vimg bitcoind.cpp
(2)執(zhí)行F2
半醉、F7
開啟GDB調(diào)試功能
(3)執(zhí)行CTRL+B
設(shè)置斷點
(4)這次由于要指定一些參數(shù)疚俱,就不再通過執(zhí)行R
啟動程序,而是執(zhí)行空格
進(jìn)入調(diào)試終端后缩多,執(zhí)行如下命令啟動
regtest:是一個本地測試環(huán)境呆奕,可以根據(jù)需要實時創(chuàng)建區(qū)塊
datadir:不指定的話,默認(rèn)創(chuàng)建在~/.bitcoin
start -server -keypool=1 -rest -discover=0 -regtest -datadir=/home/rzexin/BlockChain/Bitcoin/data
(5)使用CTRL+n
單步執(zhí)行衬吆,使用CTRL+s
單步進(jìn)入函數(shù)
(6)進(jìn)一步探索
區(qū)塊#3. 結(jié)語
好了梁钾,單步調(diào)試環(huán)境已經(jīng)準(zhǔn)備好了,那么接下來就開始愉快的bitcoin探索之旅吧逊抡。姆泻。。
區(qū)塊鏈研習(xí)社源碼研讀班第五期-rzexin