美文网首页
bitcoin源码研读(1)——用vim单步调试bitcoin

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

作者: rzexin | 来源:发表于2018-08-19 20:31 被阅读0次

    用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

    相关文章

      网友评论

          本文标题:bitcoin源码研读(1)——用vim单步调试bitcoin

          本文链接:https://www.haomeiwen.com/subject/jdhhiftx.html