GopherCon 2015: Derek Parker - Delve Into Go

Gopher Academy
28 Jul 201527:20

Summary

TLDRDerrick Parker,一位软件工程师,在视频中介绍了他所参与的项目Delve,这是一个为Go语言设计的调试器。Delve通过解析Go二进制文件中的DWARF调试信息,与操作系统和CPU协作,帮助用户探索和诊断程序问题。Parker通过分享自己在调试Go程序时遇到的挑战,阐述了为何需要Delve这样的工具,并演示了Delve的基本用法。他还讨论了Delve的发展历程、当前状态以及未来的发展方向,包括对Windows的支持和更深入的编辑器集成。

Takeaways

  • 😀 Derrick Parker 是一名软件工程师,他在 Hashrocket 工作,并且开发了一个名为 Delve 的项目。
  • 🔍 Delve 是一个针对 Go 编程语言的调试器,它通过解析 Go 二进制文件中的 DWARF 调试信息来工作。
  • 🤔 Derrick 选择开发 Delve 是因为他认为现有的调试工具(如 gdb)对于 Go 语言来说不够好,Go 语言有其独特的特性,需要专门的调试工具。
  • 🛠️ Delve 的设计目标是简单易用,与 Go 语言的工具链一致,使得调试过程尽可能少地增加开发者的负担。
  • 📖 Derrick 通过一个故事引入了 Delve 的开发背景,这个故事发生在芝加哥的一个冷冬夜晚,他在一个 meetup 上演示 gdb 时遭遇了尴尬的崩溃。
  • 🔄 Go 语言的执行模型与 C 或 C++ 等传统语言不同,例如 Go 中的 defer 语句可以在函数返回后执行代码,这可能会使现有调试工具混淆。
  • 🧵 Go 语言的 goroutine 和线程模型也给调试带来了挑战,因为 goroutine 是在线程之上进行合作调度的,这可能会导致调试时的上下文切换问题。
  • 🔧 Delve 支持多种调试命令,包括设置断点、单步执行、查看变量值等,以帮助开发者更有效地调试程序。
  • 📈 Delve 目前仍在积极开发中,已经获得了社区的贡献,支持 Linux 和 OS X,并且有初步的编辑器集成支持。
  • 🚀 Derrick 对 Delve 的未来展望包括正式发布 1.0 版本、支持 Windows、增强编辑器集成以及增加更多高级调试命令。

Q & A

  • Delve 是什么?

    -Delve 是一个为 Go 编程语言设计的调试器,它通过解析 Go 二进制文件中的 DWARF 调试信息,与操作系统和 CPU 协同工作,以便于用户操纵程序并探索问题所在。

  • 为什么需要一个新的调试器 Delve,而不是使用现有的工具如 gdb?

    -现有的调试器如 gdb 是为 C 或 C++ 等语言设计的,Go 语言有许多独特的特性,使得现有工具难以有效调试。Delve 是专门为 Go 设计的,能够更好地理解 Go 的执行模型和特性。

  • Delve 的设计理念是什么?

    -Delve 的设计理念是简单易用,与 Go 的工具链保持一致,使得即使在程序出现问题时,用户也能轻松地使用调试器来解决问题。

  • Delve 如何处理 Go 中的 defer 语句?

    -Delve 能够理解并跟踪 defer 语句的执行流程,即使 defer 语句中可能改变函数的返回值,Delve 也能够正确地处理。

  • Go 语言的执行模型与 C 或 C++ 有何不同,为何这会影响调试器?

    -Go 语言有独特的执行模型,包括 goroutine 和调度器的概念,这与 C 或 C++ 的线程模型不同。这种差异会导致现有调试器在调试 Go 程序时出现混淆和问题。

  • Delve 是如何支持 Windows 系统的?

    -脚本中提到 Delve 目前还没有 Windows 系统的支持,但作者希望社区能够贡献代码来实现这一点。

  • Delve 的开发状态是怎样的?

    -根据脚本,Delve 目前处于活跃开发状态,虽然功能已经相当完善,但作者还在犹豫是否将其标记为 1.0 版本。

  • Delve 有哪些主要的控制流命令?

    -Delve 提供了设置断点、继续执行、单步执行、切换线程、重启进程等控制流命令,以及打印变量值和 CPU 寄存器状态等信息命令。

  • Delve 如何处理 Go 程序中的编译优化问题?

    -默认情况下,Go 编译器会进行一些优化,如函数内联和寄存器变量,这可能会给调试带来困难。Delve 允许用户通过传递标志给 Go 编译器来禁用这些优化。

  • Delve 的未来发展方向是什么?

    -Delve 的未来发展方向包括正式发布 1.0 版本,增加对 Windows 的支持,完善编辑器集成,以及增加更多高级命令,如改进打印功能和允许调用函数等。

Outlines

00:00

😀 欢迎与Delve项目介绍

Derrick Parker,一名软件工程师,对组织者表示感谢,并介绍了他正在工作的项目Delve。Delve是一个为Go语言设计的调试器,它通过解析Go二进制文件中的DWARF调试信息与操作系统和CPU协同工作,帮助用户探索和发现程序中的问题。尽管存在像gdb这样的工具,Delve的创建是出于对现有工具无法满足Go语言特性的考虑,以及对更易用工具的需求。Derrick通过一个关于gdb在演示中崩溃的尴尬经历,引出了对Delve的需求和动机。

05:01

🤔 Go语言特性与现有调试工具的局限性

Derrick讨论了Go语言的特性,如defer语句和goroutines,以及它们如何使现有的调试工具如gdb和LDB变得不适用。他解释了Go的执行模型、栈管理和编译优化等问题,这些问题在传统调试器中可能导致混淆和程序崩溃。Delve旨在克服这些问题,提供对Go语言特性的深入理解和支持。

10:02

🛠️ Delve的设计理念与使用方法

Delve的设计理念是简单易用,与Go工具链的简洁性保持一致。Derrick介绍了如何开始使用Delve进行调试,包括编译、启动程序、附加到进程并进入调试提示符。他还提到了Delve支持的命令,如设置断点、跟踪点、单步执行、线程切换等,以及如何通过runtime breakpoint函数在代码中设置断点。

15:03

📚 Delve的发展历程和贡献者

Delve从最初的个人项目发展成为一个拥有22位贡献者的开源项目。Derrick回顾了Delve的历史,从最初的提交到在GopherCon上的讨论,再到现在的活跃开发状态。他感谢所有贡献者,并强调了开源社区的重要性。

20:03

🔍 Delve的当前状态与未来展望

Delve目前处于1.0版本之前的活跃开发阶段,已经实现了多种调试命令和编辑器集成。Derrick介绍了Delve的当前功能,包括控制流命令和信息命令,并展望了未来的发展方向,如Windows支持、更深入的编辑器集成和更高级的调试命令。

25:09

🎬 实际演示Delve的使用

Derrick通过一个实际的演示,展示了如何使用Delve设置断点、单步执行、检查变量和查看线程信息。他强调了Delve在处理Go语言特性时的优势,如正确处理defer语句和goroutines。演示旨在直观地展示Delve的易用性和强大功能。

Mindmap

Keywords

💡Delve

Delve 是一个为 Go 编程语言设计的调试器。它通过解析 Go 二进制文件中的 DWARF 调试信息来工作,与操作系统和 CPU 协同工作,帮助用户操纵程序以便探索和找出问题所在。在视频中,Delve 被介绍为一个简单易用的工具,旨在改善 Go 语言的调试体验。

💡调试器(Debugger)

调试器是一种工具,它允许开发者检查和控制程序的执行过程,以便发现和修复代码中的错误。在视频中,调试器是主题的核心,特别是 Delve 调试器,它被设计来解决 Go 语言特有的调试挑战。

💡Go 编程语言

Go 编程语言是一种静态类型、编译型的编程语言,由 Google 开发,以其简洁、高效和并发支持而闻名。视频中讨论了 Go 语言的调试问题,以及 Delve 调试器如何为 Go 语言提供更好的调试支持。

💡DWARF 调试信息

DWARF(Debug With Arbitrary Record Formats)是一种用于存储程序调试信息的标准格式。在视频中,Delve 调试器通过解析 Go 二进制文件中的 DWARF 调试信息来提供调试功能。

💡GDB

GDB(GNU Debugger)是一个流行的开源调试器,支持多种编程语言。视频中提到 GDB,讨论了其在调试 Go 程序时的局限性,并以此作为开发 Delve 调试器的动机之一。

💡执行模型(Execution Model)

执行模型指的是程序执行的方式,包括程序如何被调度和执行。Go 语言的执行模型与其他语言不同,例如其对延迟(defer)语句和 Go 协程(goroutines)的处理。视频中解释了这些特性如何影响调试器的设计。

💡Go 协程(Goroutines)

Go 协程是 Go 语言中实现并发的一种轻量级线程,由 Go 运行时管理。视频中提到,Go 协程的调度和执行方式对调试器提出了新的挑战,Delve 调试器需要能够理解和处理这些协程。

💡堆栈管理(Stack Management)

堆栈管理涉及到程序如何在内存中分配和使用堆栈空间。Go 语言的堆栈管理机制,特别是在函数调用和 Go 协程中,对调试器的功能有重要影响。视频中讨论了堆栈管理如何影响调试过程。

💡编译器优化(Compiler Optimizations)

编译器优化是指编译器在编译代码时采取的措施,以提高程序的运行效率。然而,过度的优化可能会使调试变得更加困难。视频中提到,Delve 调试器如何处理 Go 编译器的默认优化设置,以提供更好的调试体验。

💡编辑器集成(Editor Integration)

编辑器集成是指将调试器功能集成到代码编辑器或 IDE 中,以提供无缝的调试体验。视频中提到 Delve 调试器支持通过 JSON RPC 与编辑器集成,允许开发者在他们喜欢的编辑环境中直接使用 Delve。

Highlights

Delve是一个为Go语言设计的调试器,通过解析DWARF调试信息与操作系统和CPU协作,帮助用户探索和理解程序错误。

Delve与gdb类似,但专为Go设计,考虑到Go语言的特殊性,如defer语句和goroutine的调度。

Delve的创建源于作者在芝加哥的一次技术分享中gdb的崩溃经历,激发了开发一个更稳定、适合Go的调试器的想法。

Go语言的执行模型与C或C++不同,例如defer语句可能会改变函数的返回值,这可能使现有调试工具无法正确追踪程序流程。

Go的goroutine和线程模型给调试带来挑战,因为goroutine可以在任何调度点被挂起并由其他线程继续执行。

Delve支持设置断点、跟踪点、单步执行、跳过函数、切换线程等控制流程命令,提供丰富的调试功能。

Delve能够正确处理Go的defer语句,确保调试时不会错过任何可能引入bug的代码执行。

Delve支持编译优化的代码调试,尽管优化可能会给调试带来额外的复杂性。

Delve提供了简单的命令行接口,使得开始调试Go程序变得非常容易,只需一个命令即可启动。

Delve支持对现有二进制文件的调试以及对运行中进程的附加调试。

Delve的开发始于一个个人项目,经过几个月的独立开发后,逐渐吸引了社区的贡献者参与。

Delve目前处于活跃开发阶段,虽然还未达到1.0版本,但已经具备了相当程度的稳定性和功能完备性。

Delve的代码基础是Go和C的混合,其中C用于处理一些底层系统调用。

Delve支持Linux和OS X操作系统,但作者表示对Windows的支持需要社区的贡献。

Delve提供了对编辑器集成的初步支持,通过JSON RPC协议允许在IDE中进行调试。

Delve的未来发展计划包括正式发布1.0版本、增加对Windows的支持、完善编辑器集成以及增加更多高级调试命令。

作者通过现场演示展示了Delve的基本使用,包括设置断点、单步执行、变量检查等调试操作。

Delve的作者Derek Parker鼓励社区成员参与项目,共同推动Delve的发展和完善。

Transcripts

play00:00

like Kelsey said my name is Derrick

play00:01

Parker I'm a software engineer at hash

play00:03

rocket and today I'm gonna be talking

play00:08

about a project that I've been working

play00:09

on called delve so right off the bat I'd

play00:12

like to say a huge thanks to the

play00:14

organizers not only for bringing this

play00:16

all together which is phenomenal but for

play00:18

giving me the opportunity to talk about

play00:21

my project in front of everybody I

play00:23

really appreciate this this opportunity

play00:25

so the project I've been working on like

play00:29

I said it's called delve so just just so

play00:32

I can get a temperature how many people

play00:35

have heard of delft before today oh that

play00:38

is awesome very cool so for those of you

play00:43

who haven't heard of delve I'll explain

play00:47

a little bit about it delve is a

play00:51

debugger for the go programming language

play00:53

it works by parsing various information

play00:58

out of a go binary collectively known as

play01:01

the dwarf debugging information it

play01:03

coordinates with the operating system

play01:04

and the CPU to facilitate manipulating

play01:08

your program so that you can explore it

play01:13

and try to figure out what's going wrong

play01:16

it does not do any kind of sorcery

play01:18

writing it's more in line with a tool

play01:23

like gdb speaking of gdb why a new

play01:29

debugger why reinvent the wheel

play01:33

especially such a large wheel right this

play01:36

project I've been working on it for

play01:38

quite some time and it's it's a it's a

play01:41

relatively big undertaking so why go

play01:44

through that hassle why why do that

play01:47

aside from the fact that it's an

play01:50

incredibly fun project project to work

play01:52

on I'm having a blast working on it

play01:54

there's also some technical reasons and

play01:57

mumbo-jumbo that I'll get into later but

play02:00

like Peter I'd like to begin with a

play02:03

little story story time so it all began

play02:09

a couple years back on a cold wintry

play02:13

evening and

play02:13

cago just slightly redundant it's pretty

play02:17

much always cold in Chicago and I was

play02:22

giving a talk at a local NGO meetup

play02:23

aptly named Chicago Lange and I had

play02:29

given several talks there before so I

play02:31

was feeling pretty comfortable and this

play02:34

time I happened to be giving a talk

play02:35

about gdb now as I said there's a couple

play02:39

years ago so I was young and naive I

play02:41

didn't know what I was doing I knew gdb

play02:46

had some faults but a lot of the folks

play02:47

who go to this Meetup come from like a

play02:48

ruby background where they're really

play02:50

into pry and they have these this

play02:51

powerful tool called pry that they can

play02:53

use to debug and inspect their program a

play02:55

lot of them haven't even heard of gdb so

play02:58

I figured I'd go ahead and introduce it

play03:00

so things are going well I'm going

play03:03

through the slides presenting all of

play03:06

this knowledge to these folks and it's

play03:08

going really great then it comes time

play03:11

for a live demo so this is an artist

play03:17

rendering of me giving like them so it's

play03:23

going good so I'm open I switch to my

play03:26

terminal I got my shell going I'm about

play03:29

to do some like hardcore computering in

play03:31

front of all these folks you know I'm

play03:33

about to fire up gdb start inspecting a

play03:37

program maybe dump some registers just

play03:39

for the wow factor for some of these

play03:40

people and it's going pretty good

play03:44

it starts off really well I'm able to do

play03:46

some basic things but once I start to

play03:49

get a little bit braver and try to get a

play03:52

little bit creative

play03:55

gdb decides to crash and it crashes

play03:59

pretty hard so there was looking like a

play04:09

fool in front of literally tens of

play04:11

people right so it's just a nightmare

play04:13

just absolutely not the position that

play04:18

you want to be in and as I was up there

play04:22

you know red-faced and embarrassed

play04:24

the only thing I could think of was

play04:27

gdb must be destroyed

play04:36

wrong way again gdb must be destroyed

play04:39

it's worth saying twice but with fire so

play04:45

what we really need is an alternative

play04:47

tool the existing tools out there don't

play04:51

work they they were created a very very

play04:54

long time ago

play04:56

where you know the programming language

play04:59

of choice would be C or C++ which still

play05:01

kind of is today but we've grown a lot

play05:02

as far as languages and the things that

play05:04

we want to do and the types of languages

play05:06

that we want to debug and existing tools

play05:08

they're not one size fit all there's

play05:10

problems we really need something that's

play05:12

go central something that really

play05:14

understands go and is built specifically

play05:17

for Go Go has a lot of interesting

play05:20

nuances which a lot of those are some of

play05:21

the same features that have brought us

play05:23

all to be go developers but as I'll

play05:25

explain later they make it really tough

play05:27

for existing tools to debug and lastly

play05:32

and I think this is one of the most

play05:33

important things at least to me we need

play05:37

a tool that that should be easy to use

play05:38

so the entire quote go tool train is

play05:43

tool chain is extremely extremely simple

play05:46

to use go build you've built a binary

play05:48

with optimizations already everything is

play05:50

good to go go test you can start running

play05:53

your tests you don't have to do anything

play05:54

special to get up and running with the

play05:56

go tool chain and in my opinion the

play05:59

debugging story shouldn't be any

play06:00

different because let's face it if

play06:05

you're using a debugger odds are things

play06:09

already are not going your way right

play06:11

like your programs not working something

play06:13

is going wrong you're already frustrated

play06:15

so why introduce more steps into finding

play06:19

the solution why introduce more

play06:21

frustration so so what happened why why

play06:26

did gdb crash put simply it got confused

play06:33

existing debuggers and existing tools go

play06:36

is different enough that it can confuse

play06:38

these these pieces of software

play06:41

and I'll explain that a little bit more

play06:45

so why what what parts about go confuse

play06:49

existing debuggers and and existing

play06:52

tools I'll touch on a couple things

play07:00

first off is goes execution model it's

play07:06

it's very different from from from

play07:08

existing programming languages something

play07:11

like C or C++ we'll also talk a little

play07:16

bit about how go to stack management and

play07:18

how that can affect certain debuggers

play07:20

and lastly we'll talk about as I

play07:24

mentioned earlier go build will just do

play07:27

everything for you but sometimes that's

play07:28

not what you want especially if you're

play07:30

trying to figure out what's going wrong

play07:33

so let's begin talking a little bit

play07:36

about the execution model one of the

play07:41

first things that that I'd like to bring

play07:43

up is the defer statement now a lot of

play07:48

times the first statement is going to be

play07:51

used for something relatively

play07:53

inconsequential right cleaning out file

play07:55

descriptors closing up like connection

play08:00

to a socket or something like that

play08:02

but sometimes you do something in a

play08:04

defer statement that might change the

play08:06

value the return value of your function

play08:08

and the code that gets executed in that

play08:13

defer statement can have an impact and

play08:15

can introduce bugs in your code if

play08:17

you're using an existing tool something

play08:20

like gdb or LDB or something those tools

play08:25

don't know about defer statements

play08:26

they're not gonna follow the flow of

play08:29

execution to the defer statement so I'm

play08:32

sure everybody is familiar with with the

play08:34

Furze but just a quick overview it defer

play08:37

is a function that is guaranteed to run

play08:39

after your function returns so when an

play08:43

existing tool starts to think it's

play08:46

getting to the end of a function it's

play08:47

going to figure out the return address

play08:49

set a breakpoint there and continue

play08:51

happily there

play08:52

that doesn't work although always

play08:54

especially with go because there's other

play08:56

things that happen in the mean time and

play08:58

if you're usually using an existing tool

play09:01

this type thing this type thing is never

play09:04

going to be exposed you're never going

play09:05

to be you'll never enter in the defer

play09:08

statement and you could overlook a bug

play09:10

completely secondly I'd like to talk a

play09:16

little bit about threads versus go

play09:18

routines now not that they're on the

play09:25

same same plane and as each other but if

play09:28

we think about existing tools if you

play09:29

think about something like gdb it's it's

play09:32

planning to deal with a relatively

play09:36

standard process so your standard

play09:39

process is going to be depending on

play09:42

operating operating system nuances a

play09:44

process composed of potentially many

play09:47

threads and in it in the case of an

play09:50

existing tool that's going to be the

play09:52

smallest unit of execution is a thread

play09:54

and go that's simply not true go has

play09:58

threads obviously it's a regular process

play10:00

with threads but it also has an added

play10:02

layer of of these these go routines

play10:07

which are cooperatively scheduled on top

play10:09

of the threads that are being scheduled

play10:10

by the kernel so let's talk a little bit

play10:16

about the ghost scheduler real quick for

play10:19

some of the folks that that may not be

play10:21

explicitly familiar may be familiar that

play10:23

it exists but take a little bit of time

play10:27

to introduce some of the cast of

play10:29

characters that make up the go scheduler

play10:38

so the first element that we have is the

play10:40

pea known in the scheduler so that's the

play10:43

processor so when you're setting go max

play10:46

procs the environment variable we're

play10:47

doing an urban run time this is actually

play10:49

what you're modifying a processor is

play10:52

needed to actually execute go code on

play10:55

top of that we have what's known as an M

play10:57

which is which represents an actual

play10:59

operating system thread and M needs to

play11:04

have have obtained a P to be executing

play11:07

go code so you can have more threads and

play11:09

you have go max procs go max procs as I

play11:12

said actually only affects how many

play11:15

threads can actually be running Dell

play11:16

code in a given time and then we have

play11:20

what we're all familiar with right one

play11:21

of the things that probably brought a

play11:24

lot of us to go in the first place

play11:26

is the go routine so the processor is

play11:31

the execution context it also holds the

play11:34

runnable go routine q how does all that

play11:40

affect debuggers it kind of goes back to

play11:46

go having a non-traditional execution

play11:49

model so it brings into in delight

play11:55

things like context switches so what do

play11:58

I mean by context switch there are

play12:01

various various points in your program

play12:05

where they're called scheduling points

play12:07

where a go routine could be paused put

play12:10

back on the run queue and potentially

play12:11

picked up by another thread during

play12:13

normal execution of your program that's

play12:15

not a problem goes go scheduler is

play12:19

really great at multiplexing these go

play12:21

routines onto different threads and it

play12:22

aids in a lot of the great parallelism

play12:25

and concurrency but free a debugger it

play12:28

can be kind of painful

play12:30

it's the code that you're trying to

play12:32

debug all of a sudden switches over to

play12:34

another thread that can be very

play12:35

confusing if you're not expecting it it

play12:38

can also cause gdb to hang when a

play12:43

context switch that it doesn't

play12:45

that's not expecting happens and the

play12:48

code switches GDB not knowing about the

play12:52

scheduler at all could cause the program

play12:54

to just hang when one of these context

play12:57

switches is about to occur so what

play13:02

points in your program could one of

play13:03

these context switches happened so you

play13:06

can apply one manually by calling the

play13:11

runtime ghost good it can happen during

play13:14

a blocking assist call a wait or a sleep

play13:19

or something like that channel

play13:21

operations could could trigger a go

play13:26

routine to be paused and put back on the

play13:28

run queue

play13:29

garbage collection potentially cause it

play13:31

as well and a ghost statement I believe

play13:37

it's possible for I believe it's the the

play13:40

go routine that invokes the go statement

play13:42

to be paused and put back on the run

play13:44

queue so that the other one can start

play13:46

immediately so let's move on to the next

play13:52

point stack management

play14:04

so any peer go function is gonna do a

play14:08

little bit of runtime stack inspection

play14:11

and this is very very important for a

play14:13

couple reasons but it can have effects

play14:16

that can prevent certain things from

play14:18

being able to happen in in a traditional

play14:19

traditional debugger so any peer go

play14:25

function is going to have a function

play14:28

prologue stack check and that's

play14:30

important because one of the great

play14:32

things about going go routines is

play14:33

they're very very cheap so they're

play14:35

initialize with a small stack so when

play14:37

you jump into a function checks to see

play14:39

if it needs to grow the stack and if it

play14:41

does it'll allocate a new stack copy

play14:43

everything over and switch to it but

play14:46

this can confuse debuggers if you want

play14:48

to do something like call a go call one

play14:51

of your call a function in your program

play14:53

from within gdb what gdb will try to do

play14:55

is set up a dummy stack frame and jump

play14:58

into that function when gdb tries to

play15:00

tries to do this it'll actually crash

play15:02

the go program that you're trying to

play15:04

debug because as soon as it jumps into

play15:07

that function it's gonna start looking

play15:08

up the stack and to find something it

play15:11

doesn't like and it's just gonna panic

play15:12

and blow up so that can be very

play15:14

frustrating especially for a lot of

play15:15

folks who come from dynamic languages

play15:17

and are able to just just willy-nilly

play15:19

invoke functions call methods and do

play15:21

anything that they want to inspect their

play15:23

program

play15:26

lastly touch a little bit about on

play15:29

compiler optimizations so by default the

play15:32

go compiler is going to provide a couple

play15:33

optimizations it's gonna do function

play15:35

inlining and it's gonna register as

play15:37

variables function inlining is

play15:40

particularly a problem with debugging

play15:42

because what the debugger is gonna try

play15:44

to do is take a look at where you are

play15:46

where the where the program counter says

play15:48

you are and relate that via the symbol

play15:49

table to where it came from in the

play15:53

source code so that you can actually see

play15:54

where you are in your program with

play15:57

function inlining this can be a problem

play15:59

also registering the variables depending

play16:01

on how the door for information is

play16:03

written out if it's written out

play16:04

expecting everything to be on the stack

play16:05

you can attempt to read a variable and

play16:08

just get garbage back because the value

play16:12

of the variable is actually in a

play16:13

register it's not being stored on the

play16:14

stack

play16:18

so these optimizations these default

play16:21

optimizations are great for production

play16:23

but they're not great for trying to

play16:24

debug a program so the solution is to

play16:29

pass some flags to the go compiler but

play16:31

again the whole goal toolchain is very

play16:34

simple and easy to use why go through an

play16:35

extra step so let's introduce delve a

play16:39

little bit this is all you have to do to

play16:41

get up and running to start debugging

play16:42

your program with delve extremely simple

play16:46

that single command is going to compile

play16:48

your code with optimizations it's

play16:50

disabled for you it's going to start

play16:52

your program it's going to attach to the

play16:54

process and it's going to land you at a

play16:55

prompt ready to start debugging your

play16:57

program if you have a standalone package

play17:02

that doesn't have a main you can use

play17:03

delve test hopefully your pending test

play17:06

for your library that you're hoping

play17:07

people use so this will do something

play17:10

similar compile and test binary start

play17:12

the program attach to the process and

play17:14

Linda you had to prompt ready to start

play17:16

eradicating bugs additionally you can

play17:20

debug existing binaries and you can

play17:24

attach to a running process these these

play17:26

are come with the same caveat as I

play17:29

introduced earlier where you could be

play17:30

dealing with an optimized binary and you

play17:33

can run into some of the same exact

play17:34

issues even though you're using dev so

play17:39

to continue the introduction let's take

play17:41

a little trip down memory lane and go

play17:43

over the history of delve so last year's

play17:47

gopher Khan

play17:49

there was a talk that got cancelled or

play17:51

something and what ended up happening is

play17:53

a panel Q&A panelist on the go core

play17:56

developers which was really great one of

play17:59

the questions I was brought up was

play18:00

what's the go debugging story and I

play18:03

believe was Rob Pike mentioned something

play18:05

about it's something that you know they

play18:08

admit as a problem it's it's it's

play18:09

something that definitely needs to be

play18:11

addressed but you know obviously those

play18:14

folks are very very busy writing this

play18:15

programming language that we're all

play18:17

assembled around so doesn't leave a lot

play18:20

of time for some other projects so I

play18:26

kind of that planted a bug in my ear a

play18:27

little bit and about a month later

play18:30

I put the first committee in on Dell a

play18:38

couple months later I announced it so it

play18:42

was it was a solo effort for about the

play18:43

first five four or five months and when

play18:47

I announced today was still very very

play18:48

alpha only supported Linux and it was

play18:53

mostly to help drive contributions as

play18:55

kind of kept under wraps a little bit it

play18:57

was just a fun project to work on then

play18:59

by the time I started becoming something

play19:00

useful I figured might as well get some

play19:02

other folks in on it and that brings us

play19:07

to today the project has grown a lot and

play19:11

thankfully I have the opportunity to

play19:13

take the time to speak about it and and

play19:15

hopefully get some more people

play19:17

interested in it so the state of the

play19:23

project as it is right now is pretty 1.0

play19:25

so what does that mean the project is

play19:28

still very much an active development

play19:29

you could use it and it could do

play19:31

something weird and frustrate you so

play19:34

I've been hesitant to let to slap a 1.0

play19:38

label on it so far we have 22

play19:43

contributors to the project and I'd like

play19:45

to take this time to say thank you to

play19:46

anybody who's contributed to this

play19:48

project open-source is amazing and I

play19:50

appreciate anybody who takes the time to

play19:52

help me on a project I'm very excited

play19:54

and passionate about the codebase is a

play19:58

mixture of go and see I would like to

play20:01

write it in as much go as I possibly can

play20:03

but to interface with some of the

play20:05

lower-level syscalls on OS X some of the

play20:09

mock stuff I was unfortunately forced

play20:11

down into see it supports Linux in OS X

play20:15

it has initial support for editor

play20:19

integration through JSON RPC so you can

play20:21

run it as just like a debug server and

play20:24

it can be communicated to via your

play20:26

favorite editor of them or whatever IDE

play20:28

you you happen to enjoy using and a lot

play20:32

more commands have been implemented when

play20:35

I first announced it it's very

play20:37

rudimentary break and continue in some

play20:39

other just basic commands

play20:42

so kind of want to go through quickly of

play20:45

how can you use this let's talk about

play20:47

some of the commands that you can use

play20:49

particularly let's talk about some of

play20:51

the control flow commands so you can set

play20:54

a breakpoint right you can set a trace

play20:56

point the difference there being if

play20:58

delve hits a breakpoint it's gonna stop

play21:00

the world stop your program landing back

play21:03

at a prompt so that you can inspect a

play21:04

trace points just gonna say hey I got

play21:06

here and optionally you can provide

play21:08

flags to say give me a stack trace of

play21:10

ndepth

play21:11

whenever you get here and also give me

play21:13

the value of these variables whenever

play21:16

you hit this trace point so prevents you

play21:18

from having to do things like print line

play21:19

debugging you have all the power there

play21:22

so you can continue your program you can

play21:25

single-step it so that's actually going

play21:26

to be one CPU instruction it actually

play21:29

does a real hardware single step one

play21:32

instruction at a time will step into

play21:34

functions next we'll step over to the

play21:36

next source line stepping over functions

play21:39

you can switch to another thread if

play21:42

you're curious about what's happening

play21:43

there and you can kill the current

play21:44

process and restart it so that you can

play21:46

start debugging your program again

play21:48

without having to leave delve it also

play21:53

provides some informational commands so

play21:57

you can use the thread command to print

play21:59

out the status of all threads of the

play22:01

process go routines will print out the

play22:03

status of all of the go routines that

play22:05

are executing in the process breakpoints

play22:08

list all the breakpoints that you've set

play22:10

you can evaluate a variable and there's

play22:14

also some of the gdb folks might be

play22:17

familiar with the syntax an info command

play22:20

with sub commands so it takes an

play22:23

optional regex so let's go over some of

play22:28

the commands args print the name and

play22:33

value of all arguments to the current

play22:34

function funks all of the defined

play22:36

functions in the index are in the binary

play22:39

locals all package locals are all all

play22:43

locals in scope sources all of the

play22:46

actual source code that went into

play22:48

compiling this binary VARs

play22:51

all package variables in that

play22:52

application

play22:54

and reg so you can print out the value

play22:56

of the CPU registers

play23:00

additionally the go standard library has

play23:04

this function run time break point and

play23:06

go will handle it by realizing that it's

play23:08

within this function step out of it and

play23:10

put you on the next line where you want

play23:12

to be so it's a simple way of instead of

play23:15

invoking the debugger and having to set

play23:17

a breakpoint manually you can set this

play23:19

function in your source code wherever

play23:20

you want to stop fire up the debugger

play23:23

hit continue and it'll put you where you

play23:25

want to be so let's talk a little bit

play23:29

about where delve is going so obviously

play23:36

we'd like to get to 1.0 release I want

play23:39

this to be a tool that everybody can use

play23:40

just as part of their daily developer

play23:43

toolkit something that they can reach

play23:45

for a reliable debugger to help solve

play23:46

their problems support for Windows I

play23:51

believe in the go model of hopefully

play23:54

somebody will contribute this because

play23:55

I'm not gonna install Windows on any of

play23:57

them at my machines it's an open source

play23:59

project and I'm not paying for a Windows

play24:01

license full support for editor

play24:06

integration so I'd like to see more

play24:07

integration with VAM or whatever your

play24:08

favorite IDE is or emails and more

play24:12

advanced more advanced commands so I'd

play24:14

like to improve print and allow setting

play24:17

of variables I'd like you to be able to

play24:18

call a function and things like that so

play24:24

I have a little bit of time so let me

play24:27

get into a little bit of how to use it

play24:29

now thankfully I think I'm lucky because

play24:35

Kelsey's here he does live demos all the

play24:38

time so hopefully some of that good live

play24:40

demo viable rub off on me so like I said

play24:44

we can run delft tests and compile a

play24:48

test binary and jump into it continue it

play24:51

and like I said if you have the run time

play24:54

breakpoint function it's going to

play24:55

recognize it it's going to it's going to

play25:00

put you in the next line exactly where

play25:02

you want to be to start inspecting your

play25:03

program

play25:08

so let's run let's run the main process

play25:11

real quick so let's set a breakpoint at

play25:13

main continue and kind of see what's

play25:17

going on a little bit so we have this

play25:19

function convert to the number ten if it

play25:22

equals ten it works if not there's a bug

play25:24

so let's do there's a bug right

play25:29

Oh terrible so let's jump back in and

play25:34

let's let's explore a little bit so I

play25:36

just kind of want to go over a little

play25:37

bit of some of the commands so let's set

play25:40

a breakpoint at convert to the number

play25:42

time there's a red line support which is

play25:45

pretty nice so here we are we can

play25:48

inspect things like take a look at what

play25:51

threads are running it'll give you the

play25:52

source file the line number the function

play25:54

that it's on and also the address you

play25:58

can also take a look at go routines so

play26:02

that'll print out the go routine ID

play26:04

where it's at and how many go routines

play26:07

are currently running in the function we

play26:10

can start next thing through the program

play26:13

so we can kind of see what it's doing

play26:15

and like I said it's gonna properly

play26:18

follow through to defer statements and

play26:20

keep going through flow of execution

play26:22

there and then we can just keep going

play26:26

right we can print out the value of a

play26:32

variable and it'll return us to return

play26:35

it to us obviously it's not ten so so

play26:38

there's a bug yeah so that's just kind

play26:44

of like a brief introduction I think I'm

play26:47

running a little bit low on time of some

play26:49

of the commands that you that you can do

play26:51

if you if you want to see a little bit

play26:53

more of a demo or if you want to use it

play26:55

a little bit more check it out feel free

play26:57

to find me around and I'll be happy to

play26:59

show it off or help somebody hack on it

play27:02

or something so I'm about all the time I

play27:07

just want to say thank you again my name

play27:09

is Derek Parker you can follow me on

play27:11

twitter at Dirk the daring for some

play27:13

updates on delve and probably a lot of

play27:15

pictures of my dogs and that's it thank

play27:18

you

Rate This

5.0 / 5 (0 votes)

Related Tags
Delve调试器Go语言软件工程调试技巧技术分享开源项目性能优化工具使用编程实践开发者工具
Do you need a summary in English?