2つのDockerコンテナー間でGoのプログラムを gdb to gdbserver でリモートデバッグしてみます。
結論としては、この方法はおすすめできないです。
確認に使ったソースコードはこちら
github.comkai-zoa/golang-debug-guest-app
利用するツールと構成
- go
- gdb
- gdbserver
プログラムを実行するコンテナではgdbserverでプログラムを実行し、リモートデバッグの接続を待ち受けます。
リモートデバッグするコンテナ(Dockerfile)
gdbserverからアプリケーションを実行するコンテナ(Dockerfile)
2つのコンテナを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を起動してプロンプトでtarget remote runner: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からプログラムを動かしたときと大分勝手が違うようです。
諦めましょう…
本当にやりたかったこと
普段OSX上から開発用Dockerコンテナでgoのプログラムを動かしているので、ホストOS側からデバッグできないのかなと考えて試してみました。
良いデバッグの方法があったら誰か教えてください。
メリークリスマス!