WSL&VScodeでデバッガを使った話(C++)

WSL&VScodeでデバッガを使いました。


目次


結果

結果から言うと、不具合が出てしまいました。STL系のvectorなどを使うとその変数の中身が見れないという事態に陥ってしまいました。.gitinit-exec -enable-pretty-printingも試してみたんですけど、改善できなかったです..。有識者の人がいたら僕のtwitterかなんかにアドバイスをくれるとうれしいです。 デバッガの機能自体は使い勝手が微妙でした。急いでるときにはあまり使えなさそうです。ただ、変数が目に見えてわかるので、丁寧にデバッグしたいときには絶大な効果を発揮すると思います。

追記 無事、改善できました!下の方に追記しておきます。


gdbをインストールしよう!

僕はgdbはなんぞや?ってなったのでそこから話していこうと思います。

実はこちらのサイト↑に載っているんですが、簡単に言うとgccコンパイラgdbがデバッガです。gdbにはいろんな機能があって、例えばステップ実行とか関数の呼び出しがどうなっているかとかいろんなことが分かります。便利ですね。

僕のWSLではfind /* -name *gdb*をしてもめぼしいものが見当たらなかったので、gdbをインストールするところから始めました。

実は2通りの手順があって、

$ sudo apt-get install gdb

とするのと以下に書くmakeコマンドを使ったやり方があります。個人的には上記のやり方のほうがかかる時間が短いのでおすすめです。

makeコマンドを使ったやり方はこちらのサイト↑に載っています。手順だけ書くと

$ sudo -i

これでroot権限になったあとに

$ grep '^deb ' /etc/apt/sources.list | sed 's/^deb/deb-src/g' > /etc/apt/sources.list.d/deb-src.list
$ sudo apt update -y

上記のコマンドでapt sourceでソースコードをインストールする準備ができました。 続いて、以下のコマンド達を実行します。 #以降の文はコメントを表しています。

$ sudo apt-get build-dep gdb
$ sudo apt-get source gdb #rootディレクトリにインストールされてたら好きなディレクトリに移動させましょう
$ cd gdb-9.2 # 適宜、DLされたバージョンに置き換えてください
$ mkdir build
$ cd build
$ ../configure --enable-tui=yes
$ make
# grab a coffee
$ sudo make install

make中とても長い待ち時間だったと思います。 参考になったサイトでもおっしゃってたんですけど、# grab a coffee みたいな遊び心は僕もとても好きです。

ひとまず、長いインストールお疲れ様でした。これでgdbがインストールできていると思います。


VScodeで遊んでみよう!

さて、お手元のVScodeを起動してください。環境はVScodeのWSLでリモート接続してあることを想定しています。 試しに次のようなsample.cppをデバッグしてみます。

#include<iostream>
int main(void){
    std::cout << "Hello";
    std::cout << "World" << std::endl;
}

sample.cppを作り終わったら、tasks.jsonlaunch.jsonを作ります。.vscodeという名前のフォルダが今作業しているディレクトリにあればその中に.vscode/tasks.json.vscode/launch.jsonを作ります。もしすでに作られているようだったら、改めて作らなくても大丈夫です。

一応、僕の設定の tasks.jsonlaunch.json を載せておきます。

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "g++ compile",
      "type": "shell",
      "command": "/usr/bin/g++",
      "args": [
        "-g",
        "-o",
        "${fileDirname}/a.out",
        "${file}"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

tasks.jsonファイルの内訳

  • "tasks" : 実行するコマンド達を表しています。この中にデバッガ起動時に実行するコマンドを書きます。
  • "label" : 実行するコマンド達のラベルです。好きなように変更してください。
  • "type" : どんな言語かを選びます。今回tasks.jsonではg++コマンドを実行するのでshellです。
  • "command" : 実行するコマンド部分です。/usr/bin/g++としていますが、自分のg++へのパスを書いてください。
  • "args" : コマンドに対する引数が入ります。
    • ${fileDirname}は置換される変数で、/home/hogehoge/sample.cppを選んでいるときには${fileDirname}には/home/hogehogeが入ります。${file}だと/home/hogehoge/sample.cppが入ります。僕の設定では、コンパイルしたファイルのあるディレクトリにa.outファイルが出てくるようにしてます。例えば、/home/hogehoge/a.outのようになります。
  • "group" : ビルドタスクとして認識させています。これによりCtrl + Shift + Bでテスト実行することができます。


{
  // IntelliSense を使用して利用可能な属性を学べます。
  // 既存の属性の説明をホバーして表示します。
  // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(gdb) 起動",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/a.out",
      "args": [],
      "stopAtEntry": true,
      "cwd": "${workspaceFolder}",
      "environment": [],
      //"console": "externalTerminal",
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb",
      "setupCommands": [
        {
          "description": "gdb の再フォーマットを有効にする",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "g++ compile"
    }
  ]
}

launch.jsonファイルの内訳

実は僕も全部はわからないので、わかる範囲でだけ書いていこうと思います。

  • "name" : 先ほどのラベルと同様です。好きな名前に変更しましょう。
  • "program" : デバッグをする対象の実行ファイルです。${fileDirname}/a.outデバッグしてくれます。
  • "args" : gdbを使うときの引数です。
  • "stopAtEntry" : main関数に来た時点でデバッグを一旦ストップしてくれます。これでブレークポイントを付けるのを忘れても一手順ごとにステップ実行していけます。
  • "cwd" : CurrentWorkingDirectoryの略です。コマンドを実行する作業ディレクトリを設定します。
  • "environment" : 環境変数を設定します。使いたい環境変数をこの中に入れます。
  • "miDebuggerPath" : デバッガのパスを設定します。dbgの実行ファイルへのパスを設定しましょう。
  • "setupCommands" : デバッグを使用する際に毎回自動的に実行してくれるコマンド達を設定します。
    • "description" : コマンドの説明です。自分なりにわかりやすいコメントを残しましょう。
    • "text" : 実行するコマンドです。今回は-enable-pretty-printingをtrueに設定しています。
    • "ignoreFailures" : コマンドの値を設定します。
    • "preLaunchTask" : 事前に実行するタスクを設定します。これでtasks.jsonにあるラベルがg++ compileとなっているタスクをデバッグ時に実行できるようになります。

F5デバッグできます。

f:id:matumoto_h:20210130131836p:plain
sample.cppのデバッグ1

f:id:matumoto_h:20210130132050p:plain
sample.cppのデバッグ2



追記 STLもうまく表示できるようになりました。

いろいろ調べた結果、pretty-printers を使うことにしました。参考は以下の記事です。

pretty-printers をまず探しましょう。whereis コマンドで探します。

$ whereis pretty-printers

もし、pretty-printers が自分のパソコンに無ければ、SVN(SubVersioN)を使ってインストールします。SVNとは、Gitみたいにソースコードの管理をインターネット上でするものです。Gitが普及した今では、利用率がかなり低くなっているらしいです。

さて、そんなsvnですが、インストールしていこうと思います。

$ sudo apt-get install subversion

インストールしたら、次のコマンドを実行してpythonで書かれたpretty-printersをダウンロードします。

$ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python

次に

$ cd ~/

としてホームディレクトリに移動します。 そこに.gdbinitというファイルを作り、次の内容を記述します。

python
import sys
sys.path.insert(0, '{ここには先ほどsvnからダウンロードしたpythonファイルへのパスを書きます。}/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

これで、設定完了です。おつかれさまでした。


あとがき

はじめてまともな技術系の記事を書いたと思います。急にデバッガを使おうと思った動機は、部活で実演販売されてたので、やってみようと思ってやりました。備忘録としてでも何でもいいからちゃんとつよくなっていきたいです。 STL系をVScodeでちゃんとデバッグできるようにしたいですね。 できました。

目次に戻る