SlideShare a Scribd company logo
Enviar pesquisa
Carregar
Entrar
Cadastre-se
C・C++用のコードカバレッジツールを自作してみた話
Denunciar
simotin13 Miyazaki
Seguir
28 de Aug de 2022
•
0 gostou
•
458 visualizações
1
de
38
C・C++用のコードカバレッジツールを自作してみた話
28 de Aug de 2022
•
0 gostou
•
458 visualizações
Baixar agora
Baixar para ler offline
Denunciar
Software
Kernel/VM探検隊online part5 での発表資料です。
simotin13 Miyazaki
Seguir
Recomendados
MySQLとPostgreSQLの基本的なバックアップ比較
Shinya Sugiyama
1.1K visualizações
•
13 slides
テストコードの DRY と DAMP
Yusuke Kagata
1.5K visualizações
•
11 slides
競プロでGo!
鈴木 セシル
1.9K visualizações
•
44 slides
不遇の標準ライブラリ - valarray
Ryosuke839
7.3K visualizações
•
36 slides
Constexpr 中3女子テクニック
Genya Murakami
32.9K visualizações
•
138 slides
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
Y Watanabe
16.9K visualizações
•
78 slides
Mais conteúdo relacionado
Mais procurados
Java ORマッパー選定のポイント #jsug
Masatoshi Tada
88.8K visualizações
•
66 slides
Protocol Buffers 入門
Yuichi Ito
36.3K visualizações
•
40 slides
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
Hiro H.
3.9K visualizações
•
67 slides
ゼロから始める転移学習
Yahoo!デベロッパーネットワーク
12.7K visualizações
•
132 slides
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
NTT DATA Technology & Innovation
326 visualizações
•
81 slides
Slurmのジョブスケジューリングと実装
Ryuichi Sakamoto
1.7K visualizações
•
34 slides
Mais procurados
(20)
Java ORマッパー選定のポイント #jsug
Masatoshi Tada
•
88.8K visualizações
Protocol Buffers 入門
Yuichi Ito
•
36.3K visualizações
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
Hiro H.
•
3.9K visualizações
ゼロから始める転移学習
Yahoo!デベロッパーネットワーク
•
12.7K visualizações
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
NTT DATA Technology & Innovation
•
326 visualizações
Slurmのジョブスケジューリングと実装
Ryuichi Sakamoto
•
1.7K visualizações
TLS, HTTP/2演習
shigeki_ohtsu
•
12.9K visualizações
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Yahoo!デベロッパーネットワーク
•
12.1K visualizações
【BS13】チーム開発がこんなにも快適に!コーディングもデバッグも GitHub 上で。 GitHub Codespaces で叶えられるシームレスな開発
日本マイクロソフト株式会社
•
1.3K visualizações
eBPFは何が嬉しいのか
Yutaro Hayakawa
•
406 visualizações
Cargo makeを使ってみた話
emakryo
•
2K visualizações
Apache Arrow - データ処理ツールの次世代プラットフォーム
Kouhei Sutou
•
7.6K visualizações
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
祐司 伊藤
•
17.3K visualizações
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
•
146.9K visualizações
はじめての Gatling
Naoya Nakazawa
•
10.5K visualizações
Spring Bootの本当の理解ポイント #jjug
Masatoshi Tada
•
39.7K visualizações
Spring Day 2016 - Web API アクセス制御の最適解
都元ダイスケ Miyamoto
•
22.6K visualizações
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
NTT DATA Technology & Innovation
•
2.5K visualizações
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
•
34.7K visualizações
モジュールの凝集度・結合度・インタフェース
Hajime Yanagawa
•
16.6K visualizações
Similar a C・C++用のコードカバレッジツールを自作してみた話
mruby を C# に 組み込んでみる
Ryosuke Akiyama
2.7K visualizações
•
33 slides
トランザクションスクリプトのすすめ
pospome
3K visualizações
•
14 slides
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
Hiroh Satoh
49.2K visualizações
•
91 slides
Code Reading at Security and Programming camp 2011
Hiro Yoshioka
1.1K visualizações
•
52 slides
Cプログラマのためのカッコつけないプログラミングの勧め
MITSUNARI Shigeo
5.8K visualizações
•
20 slides
Programming camp code reading
Hiro Yoshioka
2.3K visualizações
•
52 slides
Similar a C・C++用のコードカバレッジツールを自作してみた話
(20)
mruby を C# に 組み込んでみる
Ryosuke Akiyama
•
2.7K visualizações
トランザクションスクリプトのすすめ
pospome
•
3K visualizações
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
Hiroh Satoh
•
49.2K visualizações
Code Reading at Security and Programming camp 2011
Hiro Yoshioka
•
1.1K visualizações
Cプログラマのためのカッコつけないプログラミングの勧め
MITSUNARI Shigeo
•
5.8K visualizações
Programming camp code reading
Hiro Yoshioka
•
2.3K visualizações
第1回勉強会スライド
koturn 0;
•
2.1K visualizações
Debug Hacks at Security and Programming camp 2011
Hiro Yoshioka
•
1K visualizações
つぶLT20121215
遼一 杉浦
•
242 visualizações
Web技術勉強会 第33回
龍一 田中
•
1.4K visualizações
Programming camp 2008, Codereading
Hiro Yoshioka
•
292 visualizações
Programming camp 2010 debug hacks
Hiro Yoshioka
•
620 visualizações
オープンソースで作るスマホ文字認識アプリ
陽平 山口
•
79.4K visualizações
C#勉強会
hakugakucafe
•
1.6K visualizações
Inside frogc in Dart
Goro Fuji
•
1.5K visualizações
Xbyakの紹介とその周辺
MITSUNARI Shigeo
•
7.8K visualizações
Groovy Bootcamp 2015 by JGGUG
Uehara Junji
•
3.3K visualizações
C#や.NET Frameworkがやっていること
信之 岩永
•
59.9K visualizações
スタート低レイヤー #0
Kiwamu Okabe
•
3.1K visualizações
Flutterを体験してみませんか
cch-robo
•
254 visualizações
C・C++用のコードカバレッジツールを自作してみた話
1.
C/C++用のコードカバレッジツールを 自作してみた話 @simotin13
2.
Who am I? @simotin13 Hiroyuki
Miyazaki ・関西で主に組込系のコード書いてます。 ・組込,Ruby,低レイヤが好きです。
3.
Abstract C/C++のプログラム用に、カバレッジツールを書いてみま した。 ■covme https://github.com/simotin13/covme 今のところ、完成度的にはまだまだな点はありますが、X86_64/Linuxで動く実行モ ジュールとサンプルの実行用スクリプトなどを公開しています。 go言語で書いています。
4.
Abstract # カバレッジを取りたいモジュール (-gビルド必須)を指定して実行。 #
モジュールが終了するとHTMLで結果を出力します。 $gcc main.c calc.c -g $./covme a.out
5.
Why code coverage
tool? ・商用のカバレッジツールや開発環境は高い ・Linuxだとgcov使えるけど、マイコンでは使えない ■問題 組込ソフト開発でも気軽にテストを自動化したり、カバレッジ 取りたい
6.
Inspired by PHPUnit PHPのコードを書いていて、PHPUnitというテストフレームワー クを使う機会がありました。
7.
Inspired by PHPUnit ところで、PHPUnitはどうやってカバレッジをとっている のか?
8.
Inspired by PHPUnit PHPUnitを使うときには、php.iniにXDebugの設定を書く必要 がある。 そうか、デバッガを使ってカバレッジ取っているんだろう な... 何となくPHPUnitがやっていることは察しがついた。
9.
Inspired by PHPUnit 伝統的日本企業ではExcelにソースコードを貼り付け、 デバッガでステップ実行した結果を記録 し、ユニットテストを実施します。
10.
Inspired by PHPUnit PHPがXDebug使ってカバ レッジを取れるなら、 C/C++でもデバッガを使っ て同じことができるので は? linux/gdbで試してみよう。
11.
Automate debug operation
~GDBの自動化~ 4607 11.3 7.1 52927752 284968 ? Sl 12:05 1:21 /usr/share/code/code --type=renderer --disable-color-correct-rendering --field-trial-handle 4624 1.6 3.7 38053352 148960 ? Sl 12:05 0:11 /usr/share/code/code --ms-enable-electron-run-as-node --inspect-port=0 /usr/share/code/reso 4625 0.1 1.6 38035456 65348 ? Sl 12:05 0:00 /usr/share/code/code --ms-enable-electron-run-as-node /usr/share/code/resources/app/out/boo 4696 1.0 0.8 1177412 35284 ? Sl 12:05 0:07 /home/simotin13/.vscode/extensions/ms-vscode.cpptools-1.11.4/bin/cpptools 4729 0.5 2.1 37992972 86564 ? Sl 12:05 0:03 /usr/share/code/code --ms-enable-electron-run-as-node /usr/share/code/resource4696 {9A295B6 5316 6.1 1.5 3525864 61696 ? Sl 12:10 0:24 /home/simotin13/.vscode/extensions/ms-vscode.cpptools-1.11.4/debugAdapters/bin/OpenDebugAD7 5331 0.0 0.0 2616 596 pts/1 S+ 12:10 0:00 /bin/sh /tmp/Microsoft-MIEngine-Cmd-qsxfzbaz.lrg 5333 0.0 1.0 60612 43264 pts/1 S 12:10 0:00 /usr/bin/gdb --interpreter=mi --tty=/dev/pts/1 s/app/extensi 5160 0.1 0.3 4801612 13956 ? Sl 12:09 0:00 /home/simotin13/.vscode/extensions/ms-vscode.cpptools-1.11.4/bin/cpptools-srv 5338 0.0 0.0 2364 644 ? ts 12:10 0:00 /home/simotin13/tmp/main gdbの-i=mi オプションはgdbのコマンド入出力をマシンフレンドリー にしてくれる。EclipseやVSCodeでも使われている。 ■vscodeでデバッグしているときの例
12.
Automate debug operation
~GDBの自動化~ Breakpoint 1, main (argc=21845, argv=0x0) at main.c:7 7 { 通常起動(-i=mi なし) ~"¥n" ~"Breakpoint 1, main (argc=21845, argv=0x0) at main.c:7¥n" ~"7¥t{¥n" *stopped,reason="breakpoint- hit",disp="keep",bkptno="1",frame={addr="0x0000555555555189",func="main",args=[{name="argc",value="21845"},{name ="argv",value="0x0"}],file="main.c",fullname="/home/simotin13/examples/c/function_call/main.c",line="7",arch="i3 86:x86-64"},thread-id="1",stopped-threads="all",core="9" -i=mi あり miオプション有効時のレスポンスについて ブレークポイントで停止したときの例
13.
Automate debug operation
~GDBの自動化~ ~"¥n" ~"Breakpoint 1, main (argc=21845, argv=0x0) at main.c:7¥n" ~"7¥t{¥n" *stopped,reason="breakpoint- hit",disp="keep",bkptno="1",frame={addr="0x0000555555555189",func="main",a rgs=[{name="argc",value="21845"},{name="argv",value="0x0"}],file="main.c", fullname="/home/simotin13/examples/c/function_call/main.c",line="7",arch=" i386:x86-64"},thread-id="1",stopped-threads="all",core="9" レスポンスの特徴 ・先頭1文字で応答の種類(同期・非同期・通知...etc)を表す ・JSONっぽいデータ構造。でも微妙に違う。 ・値は全てダブルクォーテーションで囲まれている。
14.
Automate debug operation
~GDBの自動化~ ・gdbのプロセスをforkして、コマンドの送信とレスポンスの解析 ができればデバッガの操作の自動化は完了
15.
How to measure
a code coverage? そもそもカバレッジってどう測るのか?
16.
How to measure
a code coverage? 関数のカバレッジ率 = 関数内の通過した行数 関数全体の行数 1:int func(int a, int b) 2:{ 3: return a+b; 4:}
17.
How to measure
a code coverage? ~"¥n" ~"Breakpoint 1, main (argc=21845, argv=0x0) at main.c:7¥n" ~"7¥t{¥n" *stopped,reason="breakpoint- hit",disp="keep",bkptno="1",frame={addr="0x0000555555555189",func="main",a rgs=[{name="argc",value="21845"},{name="argv",value="0x0"}],file="main.c", fullname="/home/simotin13/examples/c/function_call/main.c",line="7",arch=" i386:x86-64"},thread-id="1",stopped-threads="all",core="9" gdbのレスポンスから「通過した行やアドレス」は分かる。 関数のカバレッジ率 = 関数内の通過した行数 関数全体の行数
18.
How to measure
a code coverage? よく考えてみたら「関数が何行あるか?」 を数えるのは簡単ではない 1:int func(int a, int b) 2:{ 3:// コメントがあるよ 4:/* ここもコメントだよ */ 5:/* #ifもあるよ。どっちを通るか分かるかな? */ 6:#if HOGE 7: return a+b; 8:#else 9: return 0; 10:#endif 11:}
19.
How to measure
a code coverage? 1:int func(int a, int b) 2:{ 3:// コメントがあるよ 4:/* ここもコメントだよ */ 5:/* #ifもあるよ。どっちを通るか分かるかな? */ 6:#if HOGE 7: return a+b; 8:#else 9: return 0; 10:#endif 11:} 関数のカバレッジ率 = 関数内の通過した行数 関数内の実行可能な行数
20.
How to measure
a code coverage? 「関数内の実行可能な行数」 はどうやって取得することができるのか? もしかして、コンパイラとか書かないとだめ?
21.
How to measure
a code coverage? DWARFというデバッグ情報に 行番号の情報が含まれている という噂だよ
22.
Reading DWARF sections ・DWARFってデバッグに関する情報が入っているあれでしょ(知らんけど…) ・DWARFを読みたくなったときどこから読めばいいのか? ・DWARFの仕様書には「Getting
started」的な説明がない [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 ........................................................................................ ........................................................................................ [28] .debug_aranges PROGBITS 0000000000000000 00303a 000030 00 0 0 1 [29] .debug_info PROGBITS 0000000000000000 00306a 000339 00 0 0 1 [30] .debug_abbrev PROGBITS 0000000000000000 0033a3 0000f2 00 0 0 1 [31] .debug_line PROGBITS 0000000000000000 003495 00011b 00 0 0 1 [32] .debug_str PROGBITS 0000000000000000 0035b0 0002a0 01 MS 0 0 1
23.
Reading DWARF sections ・デバッグ情報の歩き方
@mhiramat https://qiita.com/mhiramat/items/8df17f5113434e93ff0c ・DWARFファイルフォーマット@koinec https://ja.osdn.net/projects/drdeamon64/wiki/DWARF%E3%83%95%E3%82%A1%E3% 82%A4%E3%83%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E 3%83%88 ■日本語の有力な情報
24.
Reading DWARF sections ■独断と偏見によるDWARFの仕様書の読み方解説 ・DWARFの仕様書は読み辛い。最初から読むのは非効率。 ・DWARFの各セクションの構造を理解し、プログラムで読みたいという目的であれば、 「7.5
Format of Debugging Information」から読むのがおすすめ。 ※ DWARF4の場合(https://dwarfstd.org/doc/DWARF4.pdf) .debug_infoセクションのヘッダ部の構造が書いてあるので、 .debug_infoの最初の1byteを読むコードを書き始めることができる。
25.
Reading DWARF sections ■DWARFを読むときにやること ・eu-readelfコマンドでどんな情報が入っているか把握する。 #
.debug_infoを読んでテキストで表示 $eu-readelf a.out –winfo # .debug_lineを読んでテキストで表示 $eu-readelf a.out -wline
26.
Reading DWARF sections ■独断と偏見によるDWARFセクションの概要説明 セクション名
難易度 内容 .debug_arranges .debug_infoで出てくるDIEのサイズに関する情報が入っている。とりあえず は読まなくても何とかなる。 .debug_str ファイル名や関数名など、デバッグ情報で参照される文字列の情報が 0終端文字列で入っている。読むのは簡単。 .debug_abbrev TagとAttributeからなる略語表(abbreviation table)が入っている。 いわばデバッグ情報の「構造体」のテーブル。 Tag=構造体名, Attribute=メンバー変数。 ※実際はTag,Attribute共にID(数値)で表現される。 .debug_line アドレスと行番号に関する情報が入っている。 例). 0x1234→ main.cの5行目 簡易的な状態機械を使って行番号やアドレスを計算するための「命令」が 入っている。計算には意味不明な式が登場する。 .debug_info .debug_abbrevで登場する「構造体」IDが入っており、その「構造体」の定義 に従って読んでいく。読むとプログラムの色んな事が分かる。 可変長のデータ構造なので読み飛ばしができない。 よく分からないDIEが出てくると詰む。
27.
Reading DWARF sections ■独断と偏見によるDWARFの解説
.debug_lineについて ファイルのインデックス 行番号 アドレス ブレークポイントをおけ るか(is_stmt) 0 0 0x00000000 FALSE インデックス ファイル名 1 main.c 2 calc.c 3 hoge.c .debug_lineはファイル名・行番号を表現するための簡易的な状態機械に対 する命令が羅列されている。 ■状態機械 ■ファイル名のテーブル
28.
Reading DWARF sections ■独断と偏見によるDWARFの解説
.debug_lineについて ファイルの インデックス 行番号 アドレス ブレークポイント をおけるか(is_stmt) 0 0 0x00000000 FALSE インデックス ファイル名 1 main.c 2 calc.c 3 hoge.c 命令に従って状態機械の各レジスタの値を更新し、行番号の情報を表現す る ■状態機械 ■ファイル名のテーブル ■命令の例 1.ファイルのインデックスに2をセット 2.行番号に1を加算 3.アドレスに0x1000をセット 4.is_stmtをTRUEにセット 5.行番号情報を確定 6.行番号に5を加算 7.アドレスに4を加算 8.行番号を確定
29.
Reading DWARF sections ■独断と偏見によるDWARFの解説
.debug_lineについて ファイルの インデックス 行番号 アドレス ブレークポイント をおけるか(is_stmt) 2 1 0x00001000 TRUE インデックス ファイル名 1 main.c 2 calc.c 3 hoge.c 命令に従って状態機械の各レジスタの値を更新し、行番号の情報を表現す る ■状態機械 ■ファイル名のテーブル ■命令の例 1.ファイルのインデックスに2をセット 2.行番号に1を加算 3.アドレスに0x1000をセット 4.is_stmtをTRUEにセット 5.行番号情報を確定 ←いまここ 6.行番号に5を加算 7.アドレスに4を加算 8.行番号を確定
30.
Reading DWARF sections .debug_line
を読み終わると、 ・アドレスに対応するソースファイルのパス ・アドレスに対応するソースファイルの行番号 ・ソースファイルの各行が実行可能(is_stmt)かどうか が分かる 1:int func(int a, int b) 2:{ 3: 4: // 足し算を行う関数 5: // aにbを加えた値を返す 6: return a+b; 7:} filepath: calc.c 1:address 0x1000 2:not stmt 3:not stmt 4:not stmt 5:not stmt 6:address 0x1004 7:address 0x1008
31.
Reading DWARF sections 1:int
func(int a, int b) 2:{ 3: 4: // 足し算を行う関数 5: // aにbを加えた値を返す 6: return a+b; 7:} filepath: src/lib/calc.c 1:address 0x1000 2:not stmt 3:not stmt 4:not stmt 5:not stmt 6:address 0x1004 7:address 0x1008 関数のカバレッジ率 = 関数内の通過した行数 関数内の実行可能な行数 この対応表からカバレッジ率の算出に必要な「関数内の実行可能な 行数」が分かる
32.
Demonstration 実際に動かしてみる (デモ)
33.
Appply to Embedded
software gdb command/response JTAG/SWD Remote Serial Protocol gdb server gdb client covme target board vender protocol gdbを使うので組込ソフトの開発とも親和性が高い →商用開発環境でもデバッガはgdbとDWARFが使われていることが多い。 gdbが使えるならターゲットのCPUやOSを問わずにカバレッジがとれる(はず) JTAG/ICE debugger
34.
Appply to Embedded
software gdb のリモートデバッグ機能を使うことで同じ仕組み を使ってカバレッジが取れる。 gdbクライアント:gdb-multiarch gdbサーバ:jlinkのGDBサーバ ARMマイコン(nucleo F446RE)のターゲットボード上 で動くプログラムのカバレッジを取れるよう修正してみた。 ■ARMで試してみた
35.
Appply to Embedded
software ・プログラムによってはDWARFを読むところでバグがいっぱい出た →想定していなかったDIEが登場する ・カバレッジを取る仕組み自体には問題なさそう ・バグを直さないと ←いまここ ■ARMで試してみた結果
36.
Summary~まとめ~ ・デバッガを自動化できると便利 ・DWARFは難解。でも読めると色々面白いことができそう。 →デバッガを使役せよ
37.
References ~参考文献~ ■GDB ・Rubyist Magazine
mruby 用デバッガ 「nomitory」の作り方 https://magazine.rubyist.net/articles/0050/0050-nomitory.html ・GDB/MI インターフェイスについて https://www.asahi-net.or.jp/~wg5k-ickw/html/online/gdb-5.0/gdb-ja_20.html ■DWARF ・The DWARF Debugging Standard https://dwarfstd.org/ ・デバッグ情報の歩き方 @mhiramat https://qiita.com/mhiramat/items/8df17f5113434e93ff0c ・DWARFファイルフォーマット@koinec https://ja.osdn.net/projects/drdeamon64/wiki/DWARF%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83 %83%E3%83%88
38.
ご清聴どうもありがとうございました。