Delve란
Delve는 Go 언어용 디버거입니다. dlv
명령어를 사용하여 go 언어를 디버깅할 수 있습니다.
Delve 설치 방법
Delve를 컴파일 하려면 Go 1.10 이상이 설치되어 있어야 합니다.
1. go get
명령어를 사용하여 delve를 설치합니다.
$ go get github.com/go-delve/delve/cmd/dlv
2. 설치가 되었는지 확인해 봅니다.
$ dlv version
Delve Debugger
Version: 1.5.0
version 정보가 나온다면 설치가 완료된 것입니다.
Delve 사용 방법
dlv attach
- 실행중인 프로세스에 연결하여 디버깅합니다.
Usage:
dlv attach pid [executable] [flags]
Flags:
--continue Continue the debugged process on start.
dlv debug
- 현재 디렉터리에 있는 main 패키지를 컴파일하고 디버깅합니다.
Usage:
dlv debug [package] [flags]
Flags:
--continue Continue the debugged process on start.
--output string Output path for the binary. (default "./__debug_bin")
--tty string TTY to use for the target program
dlv exec
- 컴파일된 바이너리를 실행하여 디버깅합니다.
Usage:
dlv exec <path/to/binary> [flags]
Flags:
--continue Continue the debugged process on start.
--tty string TTY to use for the target program
이 외에 커맨드를 알고 싶다면 dlv help
명령어로 확인할 수 있습니다.
아래 파일을 가지고 디버깅을 해보겠습니다.
$ ls
hello.go
package main
import (
"fmt"
"os"
)
const (
defaultName="yoon"
)
func disPlayHello(str string) {
fmt.Println("Hello", str)
}
func main() {
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
displayHello(name)
}
위 코드는 인자 값이 없다면 Hello yoon
을 출력하고 인자값이 있다면 Hello 인자값
을 출력하는 코드입니다.
yoongrammer
라는 인자 값을 추가하여 dlv를 실행해 보겠습니다.
인자를 전달하고 싶다면 --
를 사용하면 됩니다.
ex) dlv debug ./hello -- -arg1 value.
$ dlv debug ./hello.go -- yoongrammer
b (break)
명령어를 사용하여 main함수에 브레이크 포인터를 설정합니다.
(dlv) b main.main
Breakpoint 1 set at 0x10d10b3 for main.main() ./hello.go:17
c (continue)
명령으로 프로그램을 실행합니다.
(dlv) c
> main.main() ./hello.go:17 (hits goroutine(1):1 total:1) (PC: 0x10d10b3)
12: func displayHello(str string) {
13: fmt.Println("Hello", str)
14: }
15:
16:
=> 17: func main() {
18:
19: name := defaultName
20:
21: if len(os.Args) > 1 {
22: name = os.Args[1]
n (next)
명령으로 다음 라인으로 넘어갈 수 있습니다.
(dlv) n
> main.main() ./hello.go:19 (PC: 0x10d10c1)
14: }
15:
16:
17: func main() {
18:
=> 19: name := defaultName
20:
21: if len(os.Args) > 1 {
22: name = os.Args[1]
23: }
24:
s(step)
명령으로 함수 내부로 들어갈 수 있습니다.
아래 예제를 보시면 25라인에서 s 명령어로 displayHello() 함수 내부로 들어가는 것을 확인할 수 있습니다.
(dlv)
> main.main() ./hello.go:25 (PC: 0x10d1116)
20:
21: if len(os.Args) > 1 {
22: name = os.Args[1]
23: }
24:
=> 25: displayHello(name)
26:
27: }
(dlv) s
> main.displayHello() ./hello.go:12 (PC: 0x10d0fb3)
7:
8: const (
9: defaultName="yoon"
10: )
11:
=> 12: func displayHello(str string) {
13: fmt.Println("Hello", str)
14: }
p(print)
명령으로 변수 값을 확인할 수 있습니다.
(dlv) p str
"yoongrammer"
help 명령어로 다른 커맨드도 확인할 수 있습니다.
(dlv) help
The following commands are available:
Running the program:
call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
continue (alias: c) --------- Run until breakpoint or program termination.
next (alias: n) ------------- Step over to next source line.
rebuild --------------------- Rebuild the target executable and restarts it. It does not work if the executable was not built by delve.
restart (alias: r) ---------- Restart process.
step (alias: s) ------------- Single step through program.
step-instruction (alias: si) Single step a single cpu instruction.
stepout (alias: so) --------- Step out of the current function.
Manipulating breakpoints:
break (alias: b) ------- Sets a breakpoint.
breakpoints (alias: bp) Print out info for active breakpoints.
clear ------------------ Deletes breakpoint.
clearall --------------- Deletes multiple breakpoints.
condition (alias: cond) Set breakpoint condition.
on --------------------- Executes a command when a breakpoint is hit.
trace (alias: t) ------- Set tracepoint.
...