bitcoin源码研读(1)——用vim单步调试bitcoin

用vim单步调试bitcoin

区块#0. 前言

参加了区块链研习社的源码研读班,准备研读下比特币核心(Bitcoin Core)的源码,为了更好的掌握其脉络,单步调试是必不可少的,那么就先来准备下环境吧~

这里通过vim+vimgdb插件,来构造一个gdb的调试环境。

区块#1. 环境搭建

1.1 vim环境

安装vim+vimgdb插件,该插件以补丁方式提供,需要重新编译安装vim,有些遗憾该插件很久没有更新了,目前仅支持vim7.4版本。

1.1.1 源码下载

  • vim7.4及对应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)执行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

核心参数是:--enable-gdb,根据需要开启其他属性

参数说明:

  • --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:设定编译安装路径

(2)修改Makefile文件

设置--prefix并未修改src/Makefile中的配置,将以下三行注释掉,以便vim可以安装到我们指定的目录

# BINDIR   = /opt/bin                        
# MANDIR   = /opt/share/man
# DATADIR  = /opt/share

(3)编译&安装

-j:是make命令执行线程数,可根据机器性能调大一点,缩短编译等待时间

CFLAGS="-O2 -D_FORTIFY_SOURCE=1":不加该参数,安装后启动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 环境配置

(1)设置环境变量

之所以要安装到/home/rzexin/Software/ALL/vimgdb目录,还是因为vimgdb插件支持的vim版本过低,会导致不少基于高版本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调试的vim:vimgvim命令还是对应系统自带vim

alias vimg='/home/rzexin/Software/ALL/vimgdb/bin/vim' 

(2)拷贝运行环境配置

$ cp -r vimgdb-for-vim7.4/vimgdb_runtime/* ~/.vim

(3)激活命令帮助

$ cd ~/.vim/doc/
$ vimg

执行命令:helptags .,而后就能使用:help vimgdb打开vimgdb的帮助文档了:

bitcoin源码研读(1)——用vim单步调试bitcoin_第1张图片

1.2 bitcoin环境

安装好vim及vimgdb插件后,我们下面来获取bitcoin-core源码了。

1.2.1 源码下载

下载当前最新版本

$ 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参数:--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
  • 可执行文件说明
程序名 说明
bitcoind 比特币运行的核心程序俗称bitcoin core
bitcoin-cli Bitcoind的一个功能完备的RPC客户端,包括查询区块,交易信息等等
bitcoin-qt 比特币钱包
bitcoin-tx 比特币交易处理模块,支持交易的查询和创建
test_bitcoin 运行各个模块的测试代码
test_bitcoin-qt 运行钱包的模块测试代码

1.2.3 环境配置

(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
bitcoin源码研读(1)——用vim单步调试bitcoin_第2张图片

1.2.4 钱包启动

很好奇当前(2018.08.14)比特币账本总的大小,故启动看看:)

已经有203GB!好吧,我可怜的256GB本儿,就别指望同步下来了:(

bitcoin源码研读(1)——用vim单步调试bitcoin_第3张图片

区块#2. 调试实践

2.1 vim单步调试小demo

2.1.1 准备demo

一个计算阶乘小demo

// $ cat main.cpp 
#include 

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;
}  

编译&执行:

$ 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  :run macros/gdb_mappings.vim
nmap g :bel 40vsplit gdb-variables 

2.1.3 单步调试实践

(1)使用前面自己编译的vim打开源码

$ vimg main.cpp

(2)按F2键,相当于执行::run macros/gdb_mappings.vim,加载vimgdb补丁的绑定

(3)按F7键,进行gdb keys mapped,开启gdb调试功能

(4)点击空格,下方出现调试交互窗口

bitcoin源码研读(1)——用vim单步调试bitcoin_第4张图片

(5)在交互窗口中,输入file demo,绑定我们前面生成的可执行文件

执行后,将会看到如下提示信息:

(gdb) file demo
  Reading symbols from demo...done.

(6)使用CTRL+B设置断点

bitcoin源码研读(1)——用vim单步调试bitcoin_第5张图片

(7)执行R启动程序,或在控制窗口中执行run命令

可见demo停在断点出

bitcoin源码研读(1)——用vim单步调试bitcoin_第6张图片

(8)使用CTRL+n单步执行,使用C进行continue

bitcoin源码研读(1)——用vim单步调试bitcoin_第7张图片

(9)使用,g打开变量窗口

bitcoin源码研读(1)——用vim单步调试bitcoin_第8张图片

(10)通过CTRL+v选中变量,通过CTRL+p添加变量到变量窗口中,便于观察执行过程中值的变化

(11)在12行通过执行S单步进入factor函数,同样的方法,将*r也添加进变量窗口

bitcoin源码研读(1)——用vim单步调试bitcoin_第9张图片

(12)单机空格进入命令窗口,执行quit,结束gdb调试

2.1.4 更多指令

执行:help gdb-mappings可查看

按键 用途
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单步调试bitcoind

接下来就是激动人心的比特币核心源码的单步调试了

2.2.1 进入安装目录

我们可看到源码和可执行程序都在一个目录

$ cd /home/rzexin/BlockChain/Bitcoin/bitcoin-0.16.2/src
$ ls bitcoind bitcoind.cpp 
bitcoind  bitcoind.cpp

2.2.2 单步调试实践

(1)打开源码文件

$ vimg bitcoind.cpp

(2)执行F2F7开启GDB调试功能

(3)执行CTRL+B设置断点

bitcoin源码研读(1)——用vim单步调试bitcoin_第10张图片

(4)这次由于要指定一些参数,就不再通过执行R启动程序,而是执行空格进入调试终端后,执行如下命令启动

regtest:是一个本地测试环境,可以根据需要实时创建区块

datadir:不指定的话,默认创建在~/.bitcoin

start -server -keypool=1 -rest -discover=0 -regtest -datadir=/home/rzexin/BlockChain/Bitcoin/data

(5)使用CTRL+n单步执行,使用CTRL+s单步进入函数

bitcoin源码研读(1)——用vim单步调试bitcoin_第11张图片

(6)进一步探索

bitcoin源码研读(1)——用vim单步调试bitcoin_第12张图片

区块#3. 结语

好了,单步调试环境已经准备好了,那么接下来就开始愉快的bitcoin探索之旅吧。。。

区块链研习社源码研读班第五期-rzexin

你可能感兴趣的:(bitcoin源码研读(1)——用vim单步调试bitcoin)