使用 dlv 调试smartraiden

by 白振轩


对于程序运行过程中碰到的莫名其妙的问题,比如不明原因的阻塞,命令行 dlv 调试可能比 ide 调试效果更好

一 正常启动 smartraiden

./smartraiden --datadir=.smartraiden --api-address=0.0.0.0:5001 --listen-address=127.0.0.1:40001  --address="0x292650fee408320D888e06ed89D938294Ea42f99" --keystore-path ~/privnet3/keystore --registry-contract-address 0xf450955d87F23DF5DFc7297ed6DdDF4fb896Eff2  --password-file 123      --verbosity 5    --debug  --conditionquit "{\"QuitEvent\":\"EventSendRevealSecretBeforex\"}" --debugcrash  --eth-rpc-endpoint ws://127.0.0.1:8546

二 dlv 调试

  1. 出了问题,但是没有崩溃,直接 attach 即可
  2. 出了问题,但是崩溃了,可以提前设置断点

三 dlv attach

attach 成功以后,程序会停止运行

goroutines -s 查看所有 goroutine 的栈

解决问题

  1. 如果觉得某个 goroutine 有问题

    goroutine 108 就可以切换到这个 goroutine, 进行调试
  2. bt 查看堆栈
(dlv) goroutine 108
Switched from 0 to 108 (thread 4644478)
(dlv) bt
0 0x000000000402f66a in runtime.gopark
at /usr/local/go/src/runtime/proc.go:292
1 0x000000000403f150 in runtime.selectgo
at /usr/local/go/src/runtime/select.go:392
2 0x0000000004608329 in github.com/SmartMeshFoundation/SmartRaiden/blockchain.(*Events).startListenEvent.func1
at /Volumes/dev/smdev2/src/github.com/SmartMeshFoundation/SmartRaiden/blockchain/events.go:275
3 0x000000000405c3d1 in runtime.goexit
at /usr/local/go/src/runtime/asm_amd64.s:2361
  1. 在栈之间移动up/down
up
up

会显示当前可以控制的栈

Frame 2: /Volumes/dev/smdev2/src/github.com/SmartMeshFoundation/SmartRaiden/blockchain/events.go:275 (PC: 4608329)
270: go func(name string) {
271: ch := be.LogChannelMap[name]
272: sub := be.Subscribes[name]
273: defer rpanic.PanicRecover(fmt.Sprintf("startListenEvent %s", name))
274: for {
=> 275: select {
276: case l, ok := <-ch:
277: if !ok {
278: //channel closed
279: return
280: }
(dlv)
  1. 查看局部变量

    locals 可以显示目前所有的局部变量,也可以通过p 来打印具体的局部变量和全局变量.
(dlv) p ch
chan github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log {
qcount: 0,
dataqsiz: 10,
buf: *[10]struct github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log [
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc420335500),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc4203355a8),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc420335650),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc4203356f8),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc4203357a0),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc420335848),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc4203358f0),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc420335998),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc420335a40),
(*github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log)(0xc420335ae8),
],
elemsize: 168,
closed: 0,
elemtype: *runtime._type {
size: 168,
ptrdata: 56,
hash: 3390961113,
tflag: tflagUncommon|tflagExtraStar|tflagNamed,
align: 8,
fieldalign: 8,
kind: 25,
alg: *(*runtime.typeAlg)(0x5218c40),
gcdata: *72,
str: 56993,
ptrToThis: 1205856,},
sendx: 0,
recvx: 0,
recvq: waitq<github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log> {
first: *(*sudog<github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log>)(0xc4304ae4e0),
last: *(*sudog<github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log>)(0xc4304ae4e0),},
sendq: waitq<github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log> {
first: *sudog<github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log> nil,
last: *sudog<github.com/SmartMeshFoundation/SmartRaiden/vendor/github.com/ethereum/go-ethereum/core/types.Log> nil,},
lock: runtime.mutex {key: 0},}
(dlv)

可以看到 ch 这个 chann 目前没有任何数据,所以阻塞.

5. 也可以查看全局变量.也就是包级别的变量.

(dlv) p "github.com/SmartMeshFoundation/SmartRaiden/params".MobileMode
false
(dlv) p "github.com/SmartMeshFoundation/SmartRaiden/params".ChainID
*math/big.Int {
neg: false,
abs: math/big.nat len: 1, cap: 5, [8888],}
(dlv)

使用 dlv 调试go 程序的更多相关文章

  1. 在vscode中怎样debug调试go程序

    随着互联网时代的飞速发展,我们编码使用的开发利器也在不断更新换代,古话说工欲善其事必先利其器,对于Java开发者而言,eclipse和idea这两款神器各有千秋,因自己的爱好可以选取不同的IDE,但是 ...

  2. 使用VS+VisualGDB编译调试Linux程序

    Linux程序开发变得越来越多,越来越多的程序.产品需要跨平台,甚至有些开源项目只支持Linux平台,所以掌握Linux开发变得越来越重要. 但是对于习惯了Windows下的开发,使用了VS这个宇宙第 ...

  3. 使用未付费的账号真机调试 iOS 程序,过几天后程序一打开就会闪退

    使用未付费的苹果开发者账号真机调试 iOS 程序,过几天后程序一打开就会闪退.   解决办法: 删除 Provisioning Profile,重新配置一次. 终极解决办法:花钱购买苹果开发者账号. ...

  4. Gdb调试多进程程序

    Gdb调试多进程程序 程序经常使用fork/exec创建多进程程序.多进程程序有自己独立的地址空间,这是多进程调试首要注意的地方.Gdb功能强大,对调试多线程提供很多支持. 方法1:调试多进程最土的办 ...

  5. 利用 PhpStorm、Idea 等 IDE 如何 运行/调试 Go 程序 ?

    以自己常用的 PhpStorm 为例 第一步:下载安装 Go插件 File -> Settings -> Plugins -> 输入关键字:Go 第二步:新建 Go项目 File - ...

  6. PDB调试Python程序

    pdb是python内置的调试工具, 它可以在终端中调试Python程序, 这允许pdb在很多无法安装IDE的服务器上使用. 虽然远程调试使用广泛, 但在必要的时候(比如难以在本地搭建运行环境)pdb ...

  7. VS2010 win7 QT4.8.0,实现VS2010编译调试Qt程序,QtCreator静态发布程序

    下载源代码,注意一定是源码压缩包如qt-everywhere-opensource-src-4.8.0.zip, 不是Qt发布的已编译的不同版本的标准库如qt-win-opensource-4.8.0 ...

  8. 【php】使用gdb调试php程序

    1.简介 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.同时GDB也具有例如d ...

  9. 使用 GDB 调试多进程程序

    使用 GDB 调试多进程程序 GDB 是 linux 系统上常用的调试工具,本文介绍了使用 GDB 调试多进程程序的几种方法,并对各种方法进行比较. 3 评论 田 强 (tianq@cn.ibm.co ...

随机推荐

  1. javaWeb 开发的成长路线

    感觉最近技术到了一个瓶颈,好长时间没有感觉进步了,本着活到老学到老的态度,笔者就去逛了下,看看前辈们写的文章,觉得他们写的非常不错,在这里特别贴出一张特别值得收藏的图片,不是说其他总结的图片不值得收藏 ...

  2. 基于 DirectX11 的 MMDViewer 04-渲染目标视图和多视口

    上篇文章给出了一个简单并且可以运行的渲染框架,接下来将介绍框架中的渲染管线构成. 1.创建渲染管线 在你创建完一个窗口后,接着便要创建渲染管线,使用的函数是 D3D11CreateDeviceAndS ...

  3. Java安全框架 Apache Shiro学习-1-ini 配置

    简单登录流程: 1.  SecurityManager   2.  SecurityUtils.setSecurityManager 3.  SecurityUtils.getSubject     ...

  4. 【297】IDL 过程、函数&关键字参数

    目录: 一.Procedure 1.1 基本说明&定义 1.2 关键字参数 二.Function 2.1 基本说明&定义 2.2 关键字参数 参考:IDL中函数中的带有关键字的参数的使 ...

  5. RouterOS DNS劫持(转)

    什么是DNS劫持 DNS劫持就是通过技术手段,来控制用户解析域名的IP地址.举个例子,正常解析域名www.awolf.net时应该返回IP:64.64.30.60:但现在通过DNS劫持,使域名www. ...

  6. 使用C#通过Oracle.DataAccess连接Oracle,部署时需要注意版本问题

    平时我们开发使用的是32位的PC机,所以安装的也是Oracle32位的客户端.但是一般服务器都是64位的,安装的也是64位的Oracle客户端,如果要部署使用Oracle.DataAccess连接Or ...

  7. 用css实现文本不换行切超出限制时显示省略号(小tips)

    div{ max-width: 500px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;/*文本不换行*/ } 如上 ...

  8. Python shutil 模块学习笔记

    学于https://automatetheboringstuff.com shutil 名字来源于 shell utilities,有学习或了解过Linux的人应该都对 shell 不陌生,可以借此来 ...

  9. 10 华电内部文档搜索系统 search01

    Lucene解决搜索问题.ibatis实现存放问题,就是解决持久化问题.Struts 2做页面显示,就是实现业务层对应的功能. Spring与ibatis结合, 添加Spring支持 右击项目名s2i ...

  10. NSArray 快速求和、平均值、最大值、最小值

    在iOS开发中我们经常遇到一个需求,求一个数组的所有元素的和,最大值,最小值或者平均值,有的开发者可能第一想到的是for循环遍历求解,其实苹果提供了更简便的方式.如下: NSArray *arr = ...