delve调试器设计实现

分享:  

研究调试器设计实现有段时间了,前几天在调试一个程序时,发现go调试器go-delve/delve竟然不支持类似gdb的x/FMT格式,于是在之前工作上又优化了一下。CR期间,也学习到一些之前理解不深的地方,也顺便了解了下delve的整体架构设计、大致实现,今天就来说道说道。

delve简介

go-delve/delve是Derekparker发起的一个调试器项目,面向go语言的。为什么针对go语言要创建一个新的调试器呢?为什么不使用GDB呢?这里涉及到go的一些特性。

作为符号级调试器,要能正常实现源码级调试,有这么几个事情必须要做的:

  • 首先,就必须要有调试信息的支持,比如编译器、连接器在构建过程中插入DWARF相关的sections,以供后续调试器提取、解析以重建指令、地址与源码的映射关系,还有在活动记录中跳转等等。
  • 此外,有了调试信息,还需要理解语言内部实现,比如go的类型系统、协程、运行时,这样你才能读写源码级的运行状态信息;
  • 还没完,你还需要一些平台级实现相关的玩意,不同的语言在不同的平台上有不同的实现,调试器要理解这些差异并做针对性处理;

这些工作,在GDB里扩展插件来实现,不一定能很好地实现的,比如GDB支持的DWARF标准版本问题,和go编译器没有对齐之类的,比如GDB里面Target层(对tracee)控制层考虑的大多是进程、线程级别的,没有对goroutine类似的控制能力,诸如此类。

Anyway,我们需要一款更理解go的调试器,delve就这么诞生了。现在大已经是go官方推荐的调试器了,也是GoLand、VSCode、vim-go中使用的调试器。能有幸了解一款调试器的实现、参与贡献还是很爽的一件事情。

delve整体架构

delve大致实现