Go语言编译原理之源码调试

目录
  • 前言
  • Goland的debug调试Go源码
  • dlv工具调试Go源码
    • 安装
    • 常用命令
  • dlv调试抽象语法树构建

前言

在前边几篇文章中分享了Go编译过程中的源码实现,本文主要是想分享一下我是怎么调试Go的源代码的(如果你很熟悉的话,可以跳过本文)。本文主要是分享两种Go源码的调试方法

  • Goland的debug
  • dlv工具

本文我还会以抽象语法树为例,来通过dlv对它的构建过程进行调试

Goland的debug调试Go源码

下边以调试Go编译的入口文件为例

编辑debug配置

填写配置信息

打断点,并开始执行

调试

这些调试按钮的功能其实跟其他的IDEA是一样的,之前整理过,这里不重复整理了,不清楚的小伙伴可以看这里

dlv工具调试Go源码

安装

这里以mac为例

brew install dlv

启动

$ dlv debug 待调试文件

常用命令

可以通过下边的方式查看一些常用的命令

$ gc dlv debug /usr/local/go/src/cmd/compile/main.go
Type 'help' for list of commands.
(dlv) help
The following commands are available:
Running the program:
    call ------------------------ (EXPERIMENTAL!!!)恢复进程,注入函数调用(实验的)
    continue (alias: c) --------- 运行到断点或程序终止
    next (alias: n) ------------- 执行下一行.
    rebuild --------------------- 重新生成目标可执行文件并重新启动它. 如果可执行文件不是由dlv构建,它就不能工作.
    restart (alias: r) ---------- 重新启动一个进程.
    step (alias: s) ------------- 单步调试.
    step-instruction (alias: si)  Single step a single cpu instruction.
    stepout (alias: so) --------- Step out of the current function.
Manipulating breakpoints:
    break (alias: b) ------- 设置一个端点.
    breakpoints (alias: bp)  打印所有的端点信息.
    clear ------------------ 清除端点.
    clearall --------------- 删除多个端点.
    condition (alias: cond)  设置断点条件.
    on --------------------- 在命中断点时执行命令.
    toggle ----------------- 打开或关闭断点.
    trace (alias: t) ------- Set tracepoint.
    watch ------------------ Set watchpoint.
Viewing program variables and memory:
    args ----------------- 打印函数参数.
    display -------------- 每次程序停止时打印表达式的值.
    examinemem (alias: x)  检查给定地址的原始内存.
    locals --------------- 打印局部变量.
    print (alias: p) ----- 打印变量值.
    regs ----------------- 打印CPU寄存器的内容.
    set ------------------ 更改变量的值.
    vars ----------------- 打印包变量.
    whatis --------------- 打印表达式的类型.
Listing and switching between threads and goroutines:
    goroutine (alias: gr) -- 显示或更改当前goroutine
    goroutines (alias: grs)  列出程序goroutines.
    thread (alias: tr) ----- 切换到指定的线程.
    threads ---------------- 打印每个跟踪线程的信息.
Viewing the call stack and selecting frames:
    deferred --------- 在延迟调用的上下文中执行命令.
    down ------------- 向下移动当前帧.
    frame ------------ 设置当前帧,或在其他帧上执行命令.
    stack (alias: bt)  打印堆栈信息.
    up --------------- 向上移动当前帧
Other commands:
    config --------------------- 更改配置参数.
    disassemble (alias: disass)  Disassembler.
    dump ----------------------- 从当前进程状态创建核心转储
    edit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITOR
    exit (alias: quit | q) ----- 退出调试.
    funcs ---------------------- 打印函数列表.
    help (alias: h) ------------ 打印帮助信息.
    libraries ------------------ 列出加载的动态库
    list (alias: ls | l) ------- 展示源代码.
    source --------------------- 执行包含delve命令列表的文件
    sources -------------------- 打印源文件列表
    types ---------------------- 打印类型列表
Type help followed by a command for full documentation.
(dlv)

dlv调试抽象语法树构建

下边利用dlv来调试Go编译过程中的抽象语法树构建。我这里没有粘代码,你可以打开源代码对着下边看

  • 启动dlv,并调试Go编译的入口文件

  • 设置断点、continue的使用、n的使用(r 设置编译器编译目标文件)

  • 在指定文件的指定位置设置断点

  • 打印抽象语法树构建出来的结果(xtop)

你也可以打印xtop下边元素的值,比如查看xtop第一个元素的左节点

以上就是Go语言编译原理之源码调试的详细内容,更多关于Go编译原理源码调试的资料请关注我们其它相关文章!

(0)

相关推荐

  • Goland 断点调试Debug的操作

    第一步:进入编辑模式 第二步:开始进行编辑 第三步:就可以进行调式了 补充:goland断点调试报错 一.运行报错 runnerw.exe: CreateProcess failed with error 216 \(no message available\) 解决办法: 查看package是不是main,同时必须有个main函数,作为程序运行的主入口 查看GOOS是不是本系统的,比如windows,得设置为同一个,cmd中使用set GOOS=windows,goland中设置方法如下: 二

  • 使用goland调试远程代码的操作步骤

    前言 很多时候我们都在window上使用goland,并直接使用goland调试go代码. 但是很多时候我们的程序运行在Linux服务器上,虽然可以通过dlv命令行进行手动打断点调试,但是太麻烦了. 因此我查阅资料发现,goland是支持远程调试的,因此写篇文章记录一下. 操作步骤 1.安装dlv 在Linux服务器上执行:go install github.com/go-delve/delve/cmd/dlv,安装dlv调试工具,因为是go编译的可执行程序,可以随意复制,其他环境甚至都可以不安

  • Golang命令行进行debug调试操作

    GoLang调试工具Delve 1.先获取呗: go get -u github.com/derekparker/delve/cmd/dlv 2.编写测试代码呗: func main(){ http.HandleFunc("/test",func(writer http.ResponseWriter,req *http.Request){ //TODO }) log.Fatal(http.ListenAndServe("127.0.0.1:8080",nil)) }

  • go-spew调试利器详解

    目录 go-spew Dump系列函数 自定义配置 小结 References 对于应用的调试,我们经常会使用 fmt.Println来输出关键变量的数据.或者使用 log 库,将数据以 log 的形式输出.对于基础数据类型,上面两种方法都可以比较方便地满足需求.对于一些结构体类型数据,通常我们可以先将其序列化后再输出. 如果结构体中包含不可序列化的字段,比如 func 类型,那么序列化就会抛出错误,阻碍调试. go-spew 上面的需求,go-spew 可以完美地帮我们实现.go-spew 可

  • VSCode Golang dlv调试数据截断问题及处理方法

    使用VSCode对Golang程序进行调试时会遇到数据截断问题,string只显示前64个字符,array只显示前64个数据.经查dlv是支持以参数方式来控制的. 发现VSCode的Golang插件里面有个叫做go.delveConfig的配置,是可以设置dlv参数的.分享一下我的整个Golang配置: "go.buildOnSave": "off", "go.formatTool": "goimports", "g

  • Go语言编译原理之源码调试

    目录 前言 Goland的debug调试Go源码 dlv工具调试Go源码 安装 常用命令 dlv调试抽象语法树构建 前言 在前边几篇文章中分享了Go编译过程中的源码实现,本文主要是想分享一下我是怎么调试Go的源代码的(如果你很熟悉的话,可以跳过本文).本文主要是分享两种Go源码的调试方法 Goland的debug dlv工具 本文我还会以抽象语法树为例,来通过dlv对它的构建过程进行调试 Goland的debug调试Go源码 下边以调试Go编译的入口文件为例 编辑debug配置 填写配置信息 打

  • OpenJDK源码调试图文教程

    前言      随着Java生态愈发庞大,各种各样的新技术层出不穷,这也给大家的学习带来了很多困惑,这么多技术我该学什么,盲目的在各种新技术间穿梭,并不能取得很好的效果.      作为Java核心技术的JDK相信很多同学都看过源码,了解过Java的内存模型,但是很多时候debug到最后都是 native,这是让人很沮丧的事情,于是乎了解JDK底层的实现变得极为重要.     编译OpenJDK源码的文章很多,但是很少有从头到尾搭建环境的文章,于是我这里就写了这篇文章,这里涉及的主要步骤: 虚拟

  • spring framework源码调试技巧

    目录 1. 获取spring-framework源码 2. 导入到IDEA 2.1 预编译spring-oxm 2.2 导入到Idea 3 添加用于测试的SpringMVC项目Module 3.1 创建Module 3.2 添加对spring-webmvc的依赖 3.3 添加MVC相关文件 3.4 设置Artifacts 3.5 配置Tomcat服务 3.6 添加json解析: 4. 遇到的问题 4.1 gradle进行build的时候,中文出现乱码: 4.2 gradle项目,用了lombok

  • React 源码调试方式

    目录 正文 断点调试 搜索定位 Chrome Devtools 调试 sourcemap npm 下载react包 插件注释 调试 React 最初源码 关联 react 源码项目 总结 正文 什么?调试 React 源码还有优雅和不优雅之分? 别着急,我们先来听个故事: 东东是一名前端工程师,主要用 React 技术栈,用了多年之后想深入一下,所以最近开始看 React 源码. 断点调试 他把 react 和 react-dom 包下载了下来,在项目里引入,开发服务跑起来后,打开 Chrome

  • VSCode 搭建 x264 源码调试环境的详细步骤

    目录 1.下载 x264 2. 使用上一节介绍的方法为 x264 生成支持 debug 的 x264.exe 3. 在 VSCode 中打开 x264 源码文件夹 4. 创建并配置 launch.json 4.1 创建 launch.json 4.2 配置 launch.json 的 gdb.exe 路径 4.3 配置 launch.json 的 x264.exe 路径 5. 创建并配置 tasks.json 5.1 创建 tasks.json 5.2 配置 tasks.json 的 gcc.e

  • Node.js高级编程cluster环境及源码调试详解

    目录 前言 准备调试环境 编译 Node.js 准备 IDE 环境 Cluster 源码调试 SharedHandle RoundRobinHandle 为什么端口不冲突 SO_REUSEADDR 补充 SharedHandle 和 RoundRobinHandle 两种模式的对比 前言 日常工作中,对 Node.js 的使用都比较粗浅,趁未羊之际,来学点稍微高级的,那就先从 cluster 开始吧. 尼古拉斯张三说过,“带着问题去学习是一个比较好的方法”,所以我们也来试一试. 当初使用 clu

  • 深入理解Python虚拟机中复数(complex)的实现原理及源码剖析

    目录 复数数据结构 复数的操作 复数加法 复数取反 Repr 函数 总结 复数数据结构 在 cpython 当中对于复数的数据结构实现如下所示: typedef struct { double real; double imag; } Py_complex; #define PyObject_HEAD PyObject ob_base; typedef struct { PyObject_HEAD Py_complex cval; } PyComplexObject; typedef struc

  • OpenMP task construct 实现原理及源码示例解析

    目录 前言 从编译器角度看 task construct Task Construct 源码分析 总结 前言 在本篇文章当中主要给大家介绍在 OpenMP 当中 task 的实现原理,以及他调用的相关的库函数的具体实现. 在本篇文章当中最重要的就是理解整个 OpenMP 的运行机制. 从编译器角度看 task construct 在本小节当中主要给大家分析一下编译器将 openmp 的 task construct 编译成什么样子,下面是一个 OpenMP 的 task 程序例子: #inclu

  • android apk反编译到java源码的实现方法

    Android由于其代码是放在dalvik虚拟机上的托管代码,所以能够很容易的将其反编译为我们可以识别的代码. 之前我写过一篇文章反编译Android的apk包到smali文件 然后再重新编译签名后打包实现篡改apk的功能. 最近又有一种新的方法来实现直接从Android apk包里的classes.dex文件,把dex码反编译到java的.class二进制码,然后从.class二进制码反编译到java源码想必就不用我来多说了吧. 首先我们需要的工具是dex2jar和jd-gui 其中第一个工具

  • java并发容器CopyOnWriteArrayList实现原理及源码分析

    CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略,我们也可以称这种容器为"写时复制器",Java并发包中类似的容器还有CopyOnWriteSet.本文会对CopyOnWriteArrayList的实现原理及源码进行分析. 实现原理 我们都知道,集合框架中的ArrayList是非线程安全的,Vector虽是线程安全的,但由于简单粗暴的锁同步机制,

随机推荐