gdb debug peer 程序

在开始我们从 github 上download 下来的源码包,实际上已经包含了可执行的 peer 程序,但是该程序是使用 release 方式编译的,并不支持gdb 直接debug,所以我们需要对源码从新编译peer。

在开始编译前,读者应该了解,由于“神秘的东方力量”,程序试图从golang 库中download 安装包时,需要“科学上网”。

假设 fabric 的源码被download 在 /opt/gopath/src/github.com/hyperledger/fabric,切换到该目录后,对 Makefile 进行修改,加入debug 编译(大约360行),红色部分为修改的内容。

传递参数-ldflags "-s",忽略debug的打印信息;传递-gcflags "-N -l" 参数,这样可以忽略Go内部做的一些优化,聚合变量和函数等优化,这样对于GDB调试来说非常困难,所以在编译的时候加入这两个参数避免这些优化。

release/%/bin/peer: $(PROJECT_FILES)
@echo "Building $@ for $(GOOS)-$(GOARCH)"
mkdir -p $(@D)
$(CGO_FLAGS) GOOS=$(GOOS) GOARCH=$(GOARCH) go build -ldflags "-s" -gcflags "-N -l" -o $(abspath $@) -tags "$(GO_TAGS)" -ldflags "$(GO_LDFLAGS)" $(pkgmap.$(@F))

编译 peer 执行,编译成功后,peer 将在 build/bin/peer

make peer

作者在第一次编译时,还会遇到 protoc-gen-go 命令找不到的问题,错误信息如下

mkdir -p build/image/ccenv/payload
cp build/docker/gotools/bin/protoc-gen-go build/bin/chaintool build/goshim.tar.bz2 build/image/ccenv/payload
cp: cannot stat 'build/docker/gotools/bin/protoc-gen-go': No such file or directory
Makefile:: recipe for target 'build/image/ccenv/payload' failed
make: *** [build/image/ccenv/payload] Error

解决方式是自己安装后拷贝到 build/docker/gotools/bin/ 目录,然后再次执行编译 peer 的命令

cd $GOPATH/src/github.com/golang/
git clone https://git.oschina.net/mellymeng/protobuf.git
go get -u github.com/golang/protobuf/protoc-gen-go
cd $GOPATH
cp bin/protoc-gen-go /opt/gopath/src/github.com/hyperledger/fabric/build/docker/gotools/bin/

编译peer ok 后,按照 hyperledger fabric 1.0.5 分布式部署 (七)介绍的设置环境变量

export CORE_PEER_TLS_ROOTCERT_FILE="/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" ; \
export CORE_PEER_LOCALMSPID="Org1MSP" ; \
export CORE_PEER_TLS_ENABLED=true ; \
export CORE_PEER_TLS_KEY_FILE="/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key" ; \
export CORE_PEER_MSPCONFIGPATH="/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" ; \
export CORE_PEER_ADDRESS="peer0.org1.example.com:7051" ;

使用gdb 启动 peer 程序

gdb build/bin/peer

给 gdb 加入 go 的调试信息,假设 golang 安装在 /opt/go 目录

source /opt/go/src/runtime/runtime-gdb.py

在gdb 中设置peer 的运行参数

set args chaincode query -C mychannel -n mycc --logging-level CRITICAL -c '{"Args":["cert"]}'

在 gdb 中设置断点,例如

b /opt/gopath/src/github.com/hyperledger/fabric/peer/chaincode/common.go:

然后在gdb 执行 run 命令

run

此时gdb 将进入 common.go 程序的99 行,该函数是啥内容呢?peer 处理 chaincodeInvokeOrQuery 的函数。

Breakpoint  at 0xb2cd20: file /opt/gopath/src/github.com/hyperledger/fabric/peer/chaincode/common.go, line .
(gdb) run
Starting program: /opt/gopath/src/github.com/hyperledger/fabric/build/bin/peer chaincode query -C mychannel -n mycc --logging-level CRITICAL -c '{"Args":["cert"]}'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff73e1700 (LWP )]
[New Thread 0x7ffff6be0700 (LWP )]
[New Thread 0x7ffff63df700 (LWP )]
[New Thread 0x7ffff5a7e700 (LWP )]
[New Thread 0x7ffff527d700 (LWP )]
[Switching to Thread 0x7ffff6be0700 (LWP )] Thread "peer" hit Breakpoint , github.com/hyperledger/fabric/peer/chaincode.chaincodeInvokeOrQuery (cmd=0xc420253200, args= []string, invoke=false, cf=0xc4201833b0,
err=...) at /opt/gopath/src/github.com/hyperledger/fabric/peer/chaincode/common.go:
func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool, cf *ChaincodeCmdFactory) (err error) {

参考博客:

https://stackoverflow.com/questions/41040156/cp-cannot-stat-build-docker-gotools-bin-protoc-gen-go-no-such-file-or-direct

http://blog.csdn.net/iflow/article/details/77951610

http://blog.studygolang.com/2012/12/gdb%E8%B0%83%E8%AF%95go%E7%A8%8B%E5%BA%8F/

最新文章

  1. Multiple Contexts have a path of 错误
  2. 一些对新手有用的css技巧
  3. 全球第一本基于Bootstrap V3.x的图书《深入理解Bootstrap》终于上市了,再次免费送书15本【活动结束】
  4. (转)教你实现Winform窗体的四边阴影效果
  5. 输入一个整型数组,数据元素有正数也有负数,求元素组合成连续子数组之和最大的子数组,要求时间复杂度为O(n)。
  6. javaweb学习总结(十六)——JSP指令
  7. C# 数据流操作 Stream 相关
  8. js对象序列化JSON.stringify()与反序列化JSON.parse()
  9. 微信支付WxpayAPI_php_v3(一)sdk简介与错误修改
  10. Nodejs基础:stream模块入门介绍与使用
  11. C# 6.0 $"Hello {csdn}"
  12. python与redis交互
  13. python插入记录后取得主键id的方法(cursor.lastrowid和conn.insert_id())
  14. Chrome浏览器自动填充<input>标签的密码
  15. 查询数据库中含clob,blob的表
  16. CUDA-存储器
  17. AI 概率论
  18. [IOS微信] PList文件解析,boost数据读取
  19. 730. Count Different Palindromic Subsequences
  20. LA 4253 箭术(二分枚举)

热门文章

  1. Machine Learning No.7: Support Vector Machines
  2. 【Leetcode-easy】Remove Duplicates from Sorted Array
  3. .gitignore文件配置:keil工程文件类型【转】
  4. Spring Boot2.0之整合多数据源
  5. UER#7 T2
  6. wordpress,cos-html-cache静态化后,点击数失效问题的解决方案
  7. JavaScript里值比较的方法
  8. 关于STM32中GPIO的8种工作模式
  9. UVA 10559 Blocks——区间dp
  10. bzoj 2159 Crash 的文明世界 & hdu 4625 JZPTREE —— 第二类斯特林数+树形DP