godebug-Go用のクロスプラットフォームデバッガー

Mailgunのメンバーは、 Goの新しいクロスプラットフォームデバッガーを発表しました。これは、標準的なアプローチとは根本的に異なる独自のテクノロジーを使用しています。 将来を見据えて-このデバッガーはGopherjsの助けを借りて、ブラウザーでも動作します。



画像



イントロ



[良いGoデバッガーの]邪魔になるのは、ドキュメント化されていないバグの多いインターフェイスと通信する、移植性のない低レベルのコードをたくさん書くことだけです。



-ロブパイク




Goのサポートはgdbデバッガーで長い間使用されてきましたが、それを完全に使用することを可能にしない多くの小さいが不快な問題がありました。 掘り下げたプロジェクトもありますが、その人気はまだ結論を出すのが難しいです。 いずれにせよ、Goのデバッガーを作成するための「古典的な」アプローチは、特にGoroutineデバッグのようなGo固有のものに関しては、常に実装の困難に陥りました。



完全に異なるアプローチが、MailgunのJeremy Schlatterによって採用されました。GogunはGoを非常に積極的に使用しています。彼は、goカバレッジツール、組み込みのテストシステム、その他の基礎となる同じアイデアを採用しました。 このアプローチは一般に、2つの主要なポイント-巨大なコンパイル速度と単純な言語文法のおかげで実現しました。 stdlibのGo文法を解析するための組み込みツール(go / ast and go / parser)を使用すると、コンパイルされたプログラムのコードをその場で簡単に変更できます。これにより、まったく新しい可能性の層が開かれます。





たとえば、単純なGoプログラムを使用します。

package main import "fmt" func hello(text string) { fmt.Println(text) } func main() { fmt.Printf("Hello,") hello("world") }
      
      





出力コマンドでgodebugを実行して、生成されたコードを確認します。

 package main import ( "fmt" "github.com/mailgun/godebug/lib" ) var main_go_scope = godebug.EnteringNewScope(main_go_contents) func hello(text string) { ctx, ok := godebug.EnterFunc(func() { hello(text) }) if !ok { return } defer godebug.ExitFunc(ctx) scope := main_go_scope.EnteringNewChildScope() scope.Declare("text", &text) godebug.Line(ctx, scope, 6) fmt.Println(text) } func main() { ctx, ok := godebug.EnterFunc(main) if !ok { return } godebug.Line(ctx, main_go_scope, 10) fmt.Printf("Hello,") godebug.Line(ctx, main_go_scope, 11) hello("world") } var main_go_contents = `package main import "fmt" func hello(text string) { fmt.Println(text) } func main() { fmt.Printf("Hello,") hello("world") } `
      
      





これまで各関数の詳細には触れませんでしたが、各行には、文字列、関数の出入り関数、変数宣言などの識別子関数があることは明らかです。 デバッガーランタイムは、これらの追加機能で既に動作し、プログラムに関する完全な情報を持っています。



デモ



もちろん、このアプローチは普遍的ではなく、制限と欠点がありますが、その相対的な単純さと利点は明らかです。 このアプローチの長所の1つのデモンストレーションは、gopherjsを使用してブラウザーで直接デバッグを実行する機能です。focused - sprite -91100.appspot.com/ playground / blog - post-自分で試してください。







ネイティブの行番号付けに違反しているという事実にはいくつかのニュアンスがあります-これは、たとえば、行番号を報告するロガー/トレーサーに影響を与える可能性があります。 しかし、一般的に、ほとんどの場合、このアプローチは非常に効果的です。



設置



デバッガーのインストールは、他のGoプログラムのインストールと同じです。

 go install github.com/mailgun/godebug
      
      





使用する



デバッガーの使用は非常に簡単です。

 $ godebug godebug is a tool for debugging Go programs. Usage: godebug command [arguments] The commands are: run compile, run, and debug a Go program test compile, run, and debug Go package tests output generate debug source code, but do not build or run it Use "godebug help [command]" for more information about a command.
      
      





godebug run * .go-現在のディレクトリのすべてのソースをデバッグサポート付きでコンパイルします。 コードで使用されるすべての追加パッケージ(内部および外部の両方)-デバッグなしでネイティブにコンパイルされます-これは、必要のないコードを遅くしないように特に行われます。 含まれているパッケージのコードをデバッグする必要がある場合は、-instrumentフラグを使用して指定する必要があります。



 godebug run -instrument github.com/go-sql-driver/mysql main.go
      
      





プログラムのブレークポイントは次のように設定されます。

 _ = "breakpoint"
      
      





通常のアセンブリでは、このコードは何も実行せず、godebugはコンパイルする前にそれを認識し、それを停止する命令を挿入します。



ステータス



プロジェクトは既に実用化されていますが、これまでで最も基本的な機能のみがサポートされています。



計画には、ゴルーチンや、コミュニティが必要/有用であると考えるその他のものの停止/検査が含まれます。



参照:






All Articles