search
LoginSignup
2

More than 5 years have passed since last update.

posted at

updated at

Organization

gdbserverから起動したGoのプログラムをリモートデバッグしてみるとどうなるか

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側からデバッグできないのかなと考えて試してみました。

良いデバッグの方法があったら誰か教えてください。

メリークリスマス!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2