🫠

lldbでgnuplotをデバッグする

2024/10/07に公開

Gnuplotのデバッガー

本来はgdbを使うようだが、僕の使用しているM1Macでは、gdbが使えなかったので、lldbで代用することにした。(普通にgdb使えるのかもしれないが、)

lldbについて

lldbはXcodeなどをインストールしていれば自動的に入っている模様。VScodeで適当にC言語とかのデバッガーの拡張機能を入れると、

こんな感じで虫マークのデバッガーが入る

lldbの使い方

  • 虫ボタンを押して、起動させる(GUI)
  • コマンドラインから起動させる(CLI)

の2通りのやり方があるみたい。GUIで実行する場合は、launch.jsonなどの設定ファイルを書かなければならないので、面倒だったので、今回はCLIから使ってみることにした。

$ lldb src/gnuplot

みたいな感じで、lldb <デバッグしたい実行ファイル>でコマンドを打つとデバッガーが起動する。

よく使うコマンド

  • breakpointを設定する
$ break main # main関数にbreakpointを設定する 

他にも、次のように特定のファイルの特定の行の処理に設定することもできる

$ break plot.c:654 # plot.cファイルの654行目の処理まで進める
  • 次の処理に進む
$ next
  • デバッグ中のプログラムに対して引数を与える
$ run <与えたい引数>
  • 現在のステップでの変数に格納された値を見る
$ print <値を見たい変数>

実行例(この例では*argvという変数の値を出力している)

Process 65986 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100054408 gnuplot`main(argc=1, argv=0x000000016fdfeea0) at plot.c:595:14 [opt]
   592      /* load filenames given as arguments */
   593      while (--argc > 0) {
   594              ++argv;
-> 595              c_token = 0;
   596              if (!strncmp(*argv, "-persist", 2) || !strcmp(*argv, "--persist")
   597  #ifdef _Windows
   598                  || !stricmp(*argv, "-noend") || !stricmp(*argv, "/noend")
Target 0: (gnuplot) stopped.
(lldb) p *argv
(char *) 0x000000016fdff10f "a.gnuplot"
  • 現在のステップでの呼び出し関数の処理に入る(nextは関数の処理には入らず単純に次の処理に移動する)
$ step
  • 現在見ている関数の処理が終了するところまでスキップする
$ finish
  • 配列の列挙(gdblldbで書き方が違うので注意が必要)
    • lldbの場合
      $ (lldb) parray 40 array # parray <表示した要素数> <配列名>
      
    • gdbの場合
      $ (gdb) print array[0]@40 # print <配列の先頭要素>@<表示したい要素数>
      
    gdblldbのコマンドの対応関係については詳しくは次の公式docを参照しました

https://lldb.llvm.org/use/map.html

  • 現在見ている関数の呼び出し元に戻る
$ up

lldbを使ってみた感想

全然gdbと変わらず使えたので、便利だと感じた。しかし、デバッガーは基本的に一ステップずつしか進められないので、うまくfinishとかのスキップコマンドを活用することが重要だと感じた。

Discussion