当尝试远程调试通过gdbserver启动的Go程序时会发生什么情况?
让我们尝试在两个Docker容器之间使用gdb to gdbserver进行远程调试Go程序。
总结来说,这种方法不值得推荐。
确认所使用的源代码在这里。
github.comkai-zoa/golang-debug-guest-app
https://github.comkai-zoa/golang-debug-guest-app
使用的工具和配置
-
- go
-
- gdb
- gdbserver
在执行程序的容器中,通过gdbserver运行程序,并等待远程调试连接。
使用Docker容器进行远程调试(Dockerfile)。
使用gdbserver在容器中运行应用程序(Dockerfile)。
使用docker-compose启动并确认两个容器。
# docker-compose.yml
debugger:
container_name: my_debugger
build: debugger
tty: true
volumes:
- ./bin:/go/bin
links:
- runner:runner
runner:
container_name: my_runner
build: runner
tty: true
ports:
- "9091:9091"
volumes:
- .:/go/src/github.com/kai-zoa/golang-debug-guest-app
- ./bin:/go/bin
开始运行。
docker-compose build && docker-compose up -d
使用gdbserver来运行Go程序
以下是大致的内容:当程序启动时,会要求输入名字并打招呼的简单代码。
package main
import (
"os"
"bufio"
"fmt"
)
func main() {
var s string
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("Enter Name: ")
for scanner.Scan() {
s = scanner.Text()
fmt.Printf("Hello %s!!\n", s)
fmt.Print("Enter Name: ")
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
在gdbserver上进行构建和执行。
# デバッグビルド
$ docker exec -it my_runner go install -gcflags "-N -l" github.com/kai-zoa/golang-debug-guest-app
# gdbserverを立ち上げて起動
$ docker exec -it my_runner gdbserver localhost:9091 golang-debug-guest-app
Process golang-debug-guest-app created; pid = 24
Listening on port 9091
这将启动调试连接的等待接受。
试着进行远程调试连接
从用于远程调试的容器启动gdb并在提示符中连接到目标远程运行器的9091端口。
$ docker exec -it my_debugger gdb golang-debug-guest-app
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
...
...
(gdb) target remote runner:9091
Remote debugging using runner:9091
_rt0_amd64_linux () at /usr/local/go/src/runtime/rt0_linux_amd64.s:8
8 LEAQ 8(SP), SI // argv
(gdb)
看起来已经连接了…
先确认一下能否查看源代码。
(gdb) l
3 // license that can be found in the LICENSE file.
4
5 #include "textflag.h"
6
7 TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
8 LEAQ 8(SP), SI // argv
9 MOVQ 0(SP), DI // argc
10 MOVQ $main(SB), AX
11 JMP AX
12
唉?!
我好像看到了汇编代码。
直接从gdb中运行程序时,情况似乎相当不同。
我们放弃吧…
我真正想要做的事情
平時我在macOS上运行开发容器进行go程序开发,所以想知道是否能从主机操作系统端进行调试,于是尝试了一下。
如果有什么好的调试方法,请有人告诉我。
圣诞快乐!