コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2021年3月3日 >>> 2021年3月3日
link もっと後

2021年3月3日

VSCodeを使ってWindowsからLinuxアプリのデバッグ その1

目次: Linux

その1その2

同じことをしている人があまり居なさそうだったので、メモしておきます。

きっかけはGCCのコードをGDBのCUIモードで追っていて辛くなったことです。GCCのコードは超ぐちゃぐちゃの悲惨なコードで非常に追いづらく、GDBをもってしても何が起きているのか把握するのは困難です。せめてデバッガの画面くらいはGUIにして、見やすくできないか、と考えました。


WindowsからLinuxアプリのデバッグ、それぞれの役割

想定する構成は上記のとおりで、Linux側にはGUIがなく(ディスプレイを繋いでいない、など)、Windows側はデバッグのみで、Linux側でその他の全て(ビルドなど)を行う想定です。

Linux側の準備

この記事を読んでいるということは、既に何かデバッグしたいアプリケーションがあると思いますから、基本的なツールであるgccやmakeなどのインストールは省略させてもらいます。gdbserverをインストールするだけで良いはずです。

gdbserverのインストール
# apt-get install gdbserver

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  gdbserver
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/458 kB of archives.
After this operation, 1165 kB of additional disk space will be used.
Selecting previously unselected package gdbserver.
(Reading database ... 99167 files and directories currently installed.)
Preparing to unpack .../gdbserver_8.2.1-2+b3_amd64.deb ...
Unpacking gdbserver (8.2.1-2+b3) ...
Setting up gdbserver (8.2.1-2+b3) ...

デバッグするプログラムは何でも良いですが、下記を使用します。渡した引数を表示するだけのプログラムです。

デバッグ対象のプログラム、ソースコード

#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("argc: %d\n", argc);

	for (int i = 0; i < argc; i++) {
		printf("argv[%d]: %s\n", i, argv[i]);
	}

	return 0;
}
デバッグ対象のプログラム、実行結果
$ gcc -Wall -g -O0 a.c

$ ./a.out a b c

argc: 4
argv[1]: a
argv[2]: b
argv[3]: c

まずは普通にCUIからGDBで追ってみます。図示するとこのような構成です。


GDBでLinuxアプリのデバッグ

あえてやる必要もなさそうですけど、このあとの一貫性のために試します。

GDB CUIデバッグ
$ gdb a.out

...
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...

(gdb) b main

Breakpoint 1 at 0x1144: file a.c, line 5.

(gdb) r a b c d

Starting program: /home/katsuhiro/share/falcon/projects/c/test_argv/a.out a b c d

Breakpoint 1, main (argc=5, argv=0x7fffffffdca8) at a.c:5
5               printf("argc: %d\n", argc);

(gdb) c

Continuing.
argc: 5
argv[1]: a
argv[2]: b
argv[3]: c
argv[4]: d
[Inferior 1 (process 4008866) exited normally]

普通です。次はgdbserverと連携させリモートでGDBで追ってみます。図示するとこのような構成です。


gdbserver + GDBでLinuxアプリのデバッグ

実際にやってみましょう。ターミナルを2つ用意してください。

GDB CUIリモートデバッグ
★★ターミナル1つ目

$ gdbserver --multi localhost:1234 ./a.out a b c d

Process ./a.out created; pid = 4008908
Listening on port 1234
Remote debugging from host ::1, port 32918

★mainでbreakしたあとのcontinueを実行すると下記が出力される

argc: 5
argv[1]: a
argv[2]: b
argv[3]: c
argv[4]: d
 
Child exited with status 0


★★ターミナル2つ目

$ gdb

...
For help, type "help".
Type "apropos word" to search for commands related to "word".

(gdb) target remote :1234

Remote debugging using :1234
Reading test_argv/a.out from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading test_argv/a.out from remote target...
Reading symbols from target:test_argv/a.out...
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/5b/e47e85c990f390b0dccb6ca9dc3e70f410dc6a.debug...
0x00007ffff7fd3090 in _start () from target:/lib64/ld-linux-x86-64.so.2

(gdb) b main

Breakpoint 1 at 0x555555555144: file a.c, line 5.

(gdb) c

Continuing.
Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target...

Breakpoint 1, main (argc=5, argv=0x7fffffffdd18) at a.c:5
5               printf("argc: %d\n", argc);

(gdb) l

1       #include <stdio.h>
2
3       int main(int argc, char *argv[])
4       {
5               printf("argc: %d\n", argc);
6
7               for (int i = 1; i < argc; i++) {
8                       printf("argv[%d]: %s\n", i, argv[i]);
9               }
10

(gdb) c

Continuing.
[Inferior 1 (process 4008908) exited normally]

ブレークもできますし、ソースコードも表示されます。良い感じですね。

使い勝手はGDB単体でデバッグするときとほぼ同じですが、1点だけ注意があります。デバッガとして動作するのはgdbserverであり、プログラムのprintfなどの標準出力は、gdbserverを動かしているターミナル側に出ることに注意してください。この使い方におけるGDBはgdbserverと通信するだけの役です。

Sambaのセットアップについては、ここで解説せずとも、詳しいサイトがたくさんあると思いますので、そちらをご参照ください。

思ったより長くなってきたので、続きは次回に。

編集者:すずき(2023/04/29 21:35)

コメント一覧

  • Shigeさん(2021/06/17 13:28)
    とても参考になりました。
    Good!!!
  • すずきさん(2021/06/17 17:24)
    お役に立てたようで幸いです。
open/close この記事にコメントする



link もっと前
2021年3月3日 >>> 2021年3月3日
link もっと後

管理用メニュー

link 記事を新規作成

<2021>
<<<03>>>
-123456
78910111213
14151617181920
21222324252627
28293031---

最近のコメント5件

  • link 24年4月22日
    hdkさん (04/24 08:36)
    「うちのHHFZ4310は15年突破しまし...」
  • link 24年4月22日
    すずきさん (04/24 00:37)
    「ちゃんと数えてないですけど蛍光管が10年...」
  • link 24年4月22日
    hdkさん (04/23 20:52)
    「おお... うちのHHFZ4310より後...」
  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」

最近の記事3件

  • link 24年4月25日
    すずき (04/29 10:08)
    「[AVIFの変換] AVIFが読めないアプリケーションがたまにあるので、AVIF(AV1 Image File Format)...」
  • link 24年2月7日
    すずき (04/24 02:52)
    「[複数の音声ファイルのラウドネスを統一したい] PCやデジタル音楽プレーヤーで音楽を聞いていると、曲によって音量の大小が激しく...」
  • link 24年4月22日
    すずき (04/23 20:13)
    「[仕事部屋の照明が壊れた] いきなり仕事部屋のシーリングライトが消えました。蛍光管の寿命にしては去年(2022年10月19日の...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 04/29 10:08