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的帮助文档了:

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

1.2.4 钱包启动

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

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

区块#2. 调试实践

2.1 vim单步调试小demo

2.1.1 准备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;
}  

编译&执行:

$ 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 单步调试实践

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

$ vimg main.cpp

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

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

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

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

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

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

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

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

可见demo停在断点出

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

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

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

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

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

2.1.4 更多指令

执行: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单步调试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设置断点

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

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

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

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

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

(6)进一步探索

区块#3. 结语

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容

  • 1、文件和目录: # cd /home 进入 '/home' 目录 # cd .. ...
    XDgbh阅读 1,980评论 0 1
  • 程序调试的基本思想是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环过程,根据现象如何假设错误原...
    Manfred_Zone阅读 16,481评论 0 26
  • 要让语文课堂“活”起来,必须要学生动起来。课前要布置明确的预习任务,这是学生充分参与课堂的基础。课堂上,学生参与到...
    陕县2283阴秀丽阅读 161评论 0 1
  • 依稀过客 有些人不可抗拒的出现在我们的生命中,然后又不可抗拒的走了,我把他们称之为过客。 你很搞笑啊 信息被她看到...
    南焱阅读 371评论 0 0
  • 每一个生命赠予的宝贝,都在暗中标明了保质期,而我希望是你最珍贵也最久用的唯一…… 01 蔚小枫正啃着最爱的巨型鸡腿...
    若水忆风阅读 510评论 10 4