Bazel でビルドしたバイナリをgdbでデバッグする

2020/03/11

BAZEL C/C++ Googleサービス Linux RandomGrid Ubuntu 技術

t f B! P L

これまでアップしてきた記事で、Bazelを利用したビルドについては 実行することが出来るようになったかと思います。

そしてファイルがビルドできるようになったら次にやりたいことがありますよね、そう、デバッグです。

というわけで今回はBazelでのデバッグ情報を含んだビルドの行い方、デバッガでのバイナリの呼び出し方を紹介します。

今までと同様Da★Bo謹製独断と偏見の入り混じった翻訳が入ります
ご利用は計画的に

Debug情報付きのビルド方法


デバッガを使用したデバッグを行うためには、プログラムから生成されるバイナリとともに、デバッグ情報を出力する必要があります。ですがBazelでのビルドはデフォルトではデバッグ情報を生成しません。

そこでまずはDebug情報付きでのビルドの方法について解説します。

これは大まかに3種類方法があります。

一つはBUILDファイルに記載するビルドルールのcopt属性に、-gを値を設定してビルドする方法。これについてはこれまでの記事を見ればやり方が書いてあるので、そちらをご参照いただければと思います。

二つ目が bazel コマンドのコマンドオプション --copt で -g を設定する方法。

三つ目が bazel コマンドのコマンドオプション --compilation_mode で dbgを設定する方法です。

個別に解説していきます。

--copt で -g を設定する方法

まずはBazelのマニュアルから読んでいきましょう。

--copt cc-option
このオプションは受け取った引数をそのままコンパイラに引き渡します。
引き渡された引数はプリプロセッサやコンパイラ、アセンブラに処理を任せますが、link時にはこのオプションは渡されません。

このオプションは以下のように使用することが出来ます。
% bazel build --copt="-g0" --copt="-fpic" //foo
これによりfooライブラリはデバッグ情報なしで、 ポジションに影響を受けないコードが生成されます。

--coptに変更が加えられた場合、影響が及ぶ全てのオブジェクトファイルが強制的にリコンパイルされます。
このオプションで指定されたオプションは、BUILDファイルに記載されたcopt属性の設定値よりも先に列挙されます。

C++固有のオプション、たとえば-fno-implicit-templatesなどは、--cxxoptに設定します。
C固有のオプションは--conlyoptに設定します。
リンカに対してだけ影響を与える-lのようなオプションは、--linkoptに設定します。

つまり、
% bazel build --copt="-g" //hoge:huga
としてビルドすることで、デバッグ情報付きのhugaバイナリを得ることが出来ます。

--compilation_mode で dbgを設定する方法

こちらもマニュアルを読んでいきましょう。

このオプションは、fastbuild、dbg、optの設定値を引数に取り、C/C++コード生成時に行われる最適化やデバッグテーブルの生成する場合の完全性などに影響を与えます。

Bazelはそれぞれのコンパイルモードごとにそれぞれ異なる出力ディレクトリを使用します。
これにより切り変え時に全体のリビルドをすることなくモードの切り替えを行うことが出来ます。

引数:
  • fastbuild 可能な限り高速なビルド。デフォルトで設定されています。最低限のデバッグ情報を出力し、最適化は行いません、ただしNDEBUGオプションは設定されません。(コンパイルオプション -gmlt -Wl -S が該当)
  • dbg デバッグ情報を有効にしてビルドを行い、これによりGDBやその他のデバッガを使用したデバッグを行うことが出来ます。(コンパイルオプション -g が該当) 
  • opt 最適化を有効にしてビルドを行います。またassertを無効化し、デバッグ情報も出力されません。(コンパイルオプション -O2 -DNDEBUG が該当)このモードでデバッガを使用したい場合は、--coptに対して-gを設定します。
つまり、
bazel build //main:hello-world --compilation_mode=dbg -s

このようにビルドすることで、デバッグ情報付きのhello-worldバイナリを得ることが出来ます。-sは単純に(確認したときのコマンドそのまんま)実行されているコマンドラインを表示するだけのオプションなので、外してしまっても構いません。

gdbでのバイナリ実行

こうして出来たビルド生成物は、従来通り gdb や gdbtui の引数に取ることでデバッグを行うことが出来ます。

gdbtui bazel-bin/main/hello-world

実行ファイルはこれまでと同じく、bazel-binの参照先に格納されています。



上手に出来ました。

本日はこれまで。

Translate

ページビューの合計

注意書き

基本的にごった煮ブログですので、カテゴリから記事を参照していただけると読みやすいかと存じます。

ADBlocker等を使用していると、Twitterやアクセスカウンタが表示されません。

記事を読むには差し支えませんが、情報を参照したい場合には一時例外にしていただけると全てご参照いただけます。

Featured Post

ボイドラDICEの攻略法

QooQ