MSYS2 MinGW GCC環境をつくる (その4)
  Windows, Linux, C/C++

MinGW GCC環境をつくる(その4)です。今回は、Eclipse CDTからアプリケーションをデバッグ実行する方法を説明します。

MSYS2環境を構築してMinGW gccコンパイラをインストールする方法、Eclipse CDTをインストールしてMinGW gccコンパイラを使用する方法については、(その1)、(その2)の記事を参照してください。

サンプルコード

MSYS2 MinGW GCC環境をつくる (その2)を参考にして、簡単なサンプルコードを用意してください。

sample1.cpp
#include <iostream> int main(int argc, char* argv[]) { std::cout << "Hello, World!!" << std::endl; std::string name = "taro"; std::cout << "Hello, " << name << std::endl; return 0; }
Makefile
TARGET=sample1 SRC_DIR=./src OBJ_DIR=./obj BIN_DIR=./bin CC = gcc CXX = g++ CPPFLAGS = CXXFLAGS = LDFLAGS = LOADLIBES = LDLIBS = -lstdc++ EXTENSION:=.cpp SRC:=$(wildcard $(SRC_DIR)/**/*$(EXTENSION)) $(wildcard $(SRC_DIR)/*$(EXTENSION)) SRC_WITHOUT_PREFIX:=$(patsubst $(SRC_DIR)%,%,$(SRC)) OBJ:=$(addprefix $(OBJ_DIR),$(SRC_WITHOUT_PREFIX:$(EXTENSION)=.o)) $(BIN_DIR)/$(TARGET) : $(OBJ) @if [ ! -d $(BIN_DIR) ]; then mkdir $(BIN_DIR); fi $(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(OBJ_DIR)/%.o : $(SRC_DIR)/%$(EXTENSION) @if [ ! -d $(OBJ_DIR) ]; then mkdir $(OBJ_DIR); fi $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< .PHONY: all clean all: $(BIN_DIR)/$(TARGET) clean: @if [ -d $(OBJ_DIR) ]; then rm -fr $(OBJ_DIR); fi @if [ -d $(BIN_DIR) ]; then rm -fr $(BIN_DIR); fi

デバッグ実行 (1回目)

まだ何も準備をしていませんが、デバッグ実行をするとどうなるのか試してみましょう。

Project Explorerでsample1プロジェクトを選択して、右クリック、Debug AsLocal C/C++ Applicationをクリックします。

Error with command: gdb --versionというエラーが表示されてしまいました。

gdbがインストールされていないと、このようなエラーが表示されてアプリケーションの起動に失敗してしまいます。

gdbをインストールする

プログラムのデバッグ実行にはgdbが必要になります。いつものようにMSYS2のパッケージマネージャーpacmanを使ってgdbをインストールしていきます。

C:\msys64\mingw64.exeを起動して、gdbを含むパッケージを検索します。

gdbを含むパッケージを検索するコマンド
$ pacman -Ssq gdb

MinGW (64ビット版)パッケージであるmingw-w64-x86_64-gdbをインストールします。

mingw-w64-x86_64-gdbパッケージをインストールするコマンド
$ pacman -S mingw-w64-x86_64-gdb

“インストールを行いますか?”と確認メッセージが表示されるので、Yを入力してからEnterを押します。

デバッグ実行 (2回目)

gdbのインストールが完了したら、Eclipse CDTに戻って再びデバッグ実行をしてみます。

先程とはエラーメッセージの内容が変わりましたが、またしても起動に失敗してしまいました。

Problem Occurred
Error in final launch sequence Failed to execute MI command: -exec-run

このようなエラーメッセージが出てしまう場合には、Eclipseを管理者権限で起動すると問題が解決するようです。Eclipseを管理者権限で起動し直してみましょう。

デバッグ実行 (3回目)

Eclipseを管理者権限で起動したら、もう一度、デバッグ実行に挑戦です。

何やら長い英語のメッセージが表示されました。

This kind of launch is configured to open the Debug perspective when it suspends.

This Debug perspective is designed to support application debugging. It incorporates view for displaying the debug stack, variables and breakpoint management.

Do you want to open this perspective now ?"

日本語に翻訳すると以下のような意味になります。

この種類の起動はデバッグ・パースペクティブを開くように構成されています。

デバッグ・パースペクティブはアプリケーションのデバッグをサポートするために設計されています。スタック、変数、ブレークポイント管理を表示するビューが組み込まれています。

このパースペクティブを開きますか?

Yesをクリックして、デバッグ・パースペクティブに切り替えましょう! 次回以降、このダイアログを表示しないようにする場合はRemember my decisionにチェックを入れます。

ようやくデバッグ実行を開始することができました。

しかし、よく見ると No source available for "main() at 0x40156e (main関数のソースコードが見つからない) というメッセージが出ていますね。

実はデバッグ実行するためには、ビルド時にデバッグ用のオプションを指定してデバッグ用の実行ファイルを作成しておく必要があるんです。(これをデバッグ・ビルドと呼びます。)

停止ボタンをクリックして、一旦、デバッグを終了してください。元のC/C++パースペクティブに戻すにはEclipseのメニュー右上に表示されているCと書かれているアイコンをクリックします。

Makefileを変更してデバッグビルド構成にする

アプリケーションをデバッグ用にビルドするには、コンパイル時のオプションに -g3 (ジースリー) と -O0 (オーゼロ)を指定します。

  • -g3 (ジースリー) 最大限のデバッグ情報を付加します。
  • -O0 (オーゼロ) コンパイル時の最適化を無効にします。

MakefileCXXFLAGS=に上記オプションを指定します。

デバッグ用のオプション
CXXFLAGS = -g3 -O0

Makefileにオプションを追加して保存したら、EclipseのメニューバーからProjectClean…を実行します。(これでmake cleanが実行され実行ファイルが削除されます。)

続いて、EclipseのメニューバーからProjectBuild Projectを実行してアプリケーションをビルドします。これで、デバッグ情報の付いた実行ファイルが出来ます。

デバッグ実行 (4回目)

4回目のデバッグ実行です。Project Explorerからsample1プロジェクトを選択して、右クリック、Debug AsLocal C/C++ Applicationをクリックします。

今度こそデバッグ実行成功です!

main関数が実行されて最初の行でプログラムが停止状態になっています。

  • F6で1行ずつステップ実行できます。
  • F8でブレークポイントで停止するまで一気に実行できます。

詳しくはEclipseのメニューバーにマウスカーソルを当ててツールチップを確認してみてください。機能名とショートカットキーを確認することができます。

Variablesビューでは変数の値を確認することができます。

いろいろと触っていれば次第に分かってくると思います。

Makefileを改善する

Makefileを編集してCXXFLAGS = -g3 -O0としましたが、これでは常にデバッグ情報が付加された実行ファイルが出来てしまいます。

Makefileを改善して、デバッグ・ビルドとリリース・ビルドを切り替えられるようにしたいと思います。makeには変数の値によって条件分岐する機能があります。以下の例では環境変数CONFIG_NAMEDebugが設定されている場合はCXXFLAGS-g3 -O0を追加します。そうでなければCXXFLAGS-O2を追加します。(-O2はリリース用の標準的な最適化オプションです。)

環境変数CONFIG_NAMEにDebugが設定されているときはデバッグ情報を付加する
ifeq ($(CONFIG_NAME), Debug) CXXFLAGS += -g3 -O0 else CXXFLAGS += -O2 endif

先程までのCXXFLAGS = -g3 -O0は元のCXXFLAGS =に戻しておきます。

Makefile全体は以下のようになります。

Makefile
TARGET=sample1 SRC_DIR=./src OBJ_DIR=./obj BIN_DIR=./bin CC = gcc CXX = g++ CPPFLAGS = CXXFLAGS = LDFLAGS = LOADLIBES = LDLIBS = -lstdc++ ifeq ($(CONFIG_NAME), Debug) CXXFLAGS += -g3 -O0 else CXXFLAGS += -O2 endif EXTENSION:=.cpp SRC:=$(wildcard $(SRC_DIR)/**/*$(EXTENSION)) $(wildcard $(SRC_DIR)/*$(EXTENSION)) SRC_WITHOUT_PREFIX:=$(patsubst $(SRC_DIR)%,%,$(SRC)) OBJ:=$(addprefix $(OBJ_DIR),$(SRC_WITHOUT_PREFIX:$(EXTENSION)=.o)) $(BIN_DIR)/$(TARGET) : $(OBJ) @if [ ! -d $(BIN_DIR) ]; then mkdir $(BIN_DIR); fi $(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(OBJ_DIR)/%.o : $(SRC_DIR)/%$(EXTENSION) @if [ ! -d $(OBJ_DIR) ]; then mkdir $(OBJ_DIR); fi $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< .PHONY: all clean all: $(BIN_DIR)/$(TARGET) clean: @if [ -d $(OBJ_DIR) ]; then rm -fr $(OBJ_DIR); fi @if [ -d $(BIN_DIR) ]; then rm -fr $(BIN_DIR); fi

環境変数CONFIG_NAMEを設定する

sample1プロジェクトに環境変数を設定するために以下の手順を実施します。

Project Explorerからsample1プロジェクトを選択して、右クリック、Propertiesをクリックします。プロパティが表示されたら、C/C++ BuildEnvironment を開きます。

Add…ボタンをクリックします。

新しい環境変数を設定するダイアログが表示されるので、 NameにCONFIG_NAME、ValueにDebugと入力してOKをクリックします。

Apply and Closeをクリックしてプロパティを閉じます。

これで、環境変数CONFIG_NAMEの値がDebugに設定されたので、ビルドを実行するとデバッグ情報付きの実行ファイルが出来上がります。リリース用の実行ファイルを出力したい場合は環境変数CONFIG_NAMEの値をDebug以外の値(たとえばRelease)に変更します。

構成(Configuration)と連動させることもできる

環境変数CONFIG_NAMEの値を書き換えるのではなく、Eclipse CDTの構成(Configuration)切替と連動させることもできます。

環境変数CONFIG_NAMEを選択した状態でEdit…をクリックします。

環境変数の値を編集するダイアログが表示されるので、Valueの値を${ConfigName}に変更してOKをクリックします。

環境変数CONFIG_NAMEの値が${ConfigName}に変わりました。${ConfigName}は構成名が設定されるEclipse CDTのビルトイン変数です。構成を追加するためにManage Configurations…をクリックします。

構成を管理するダイアログが表示されるので、New…をクリックします。

新しい構成を作成するダイアログが表示されます。 NameにDebugと入力してOKをクリックします。

新しい構成Debugが作成されました。Debug行を選択した状態でSet ActiveをクリックしてDebug構成をアクティブにしておきましょう。OKをクリックしてダイアログを閉じます。

構成としてDebugを選択できるようになりました。

ビルトイン変数${ConfigName}にはアクティブになっている構成の名前が設定されます。そして環境変数CONFIG_NAMEにはビルトイン変数${ConfigName}の値が設定されます。

つまり、Debug構成をアクティブにすると環境変数CONFIG_NAMEDebugが設定され、Makefileの分岐条件で-g3 -O0オプションが指定されるようになったわけです。

デバッグ実行がエントリーポイントで停止しないようにする

デフォルトではブレークポイントの有無に関わらず、エントリーポイント(通常はmain関数)でデバッガが停止するようになっています。

F8を1回押せば済む話ですが、それでもなんとなく面倒です。デバッグ構成を変更して、エントリーポイントでデバッガが停止しないように変更してみましょう。

Project Explorerでsample1プロジェクトを選択して、右クリック、 Debug AsDebug Configurations…をクリックします。

Debuggerタブに切り替えて、Stop on start up at: mainのチェックを外します。Applyをクリックします。これで、エントリーポイントでデバッガが停止しないようになります。

Eclipse CDT + gdb でのデバッグ実行手順の説明は以上になります。