Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C++ Valgrind

Valgrindで行番号を表示させる方法

投稿日:2021年11月14日 更新日:

 

<目次>

(1) Valgrindで行番号を表示させる方法
 (1-1) 行番号を表示させる方法
 (1-2) (参考)「-g」オプションについて

(1) Valgrindで行番号を表示させる方法

本記事ではValgrindのメモリチェックにおいて、結果に行番号を表示させる方法をご紹介します。メモリリークがどこで発生したか?を特定するのに役立ちます。

(Before)
==XXXXX==    by 0x40059E: main (in /tmp_rainbow/memorytest)

(After)
==XXXXX==    by 0x40059E: main (memorytest.cpp:5)

(1-1) 行番号を表示させる方法

通常valgrindコマンドでメモリチェックした際に、特に意識しないと問題となった行番号が表示されない事があります。
 
(実行コマンド)メモリチェック
valgrind --tool=memcheck --leak-check=yes ../memorytest
 
これは、C++のプログラムをgccでコンパイルする際に「-g」オプションを指定していないと、チェック時に問題となっている正確な行番号が表示されません。
 
(例:BEFORE)※発生したmainの行番号が分からない
==21696== HEAP SUMMARY:
==21696==     in use at exit: 100 bytes in 1 blocks
==21696==   total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==21696==
==21696== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==21696==    at 0x4C2C866: operator new[](unsigned long) (vg_replace_malloc.c:579)
==21696==    by 0x40059E: main (in /tmp_rainbow/memorytest)
==21696==
==21696== LEAK SUMMARY:
==21696==    definitely lost: 100 bytes in 1 blocks
==21696==    indirectly lost: 0 bytes in 0 blocks
==21696==      possibly lost: 0 bytes in 0 blocks
==21696==    still reachable: 0 bytes in 0 blocks
==21696==         suppressed: 0 bytes in 0 blocks
(図111)行番号が表示されない

しかし、対象のC++プログラムをコンパイルする際に「-g」オプション(デバッグ用情報の生成)を付与すると、行番号が表示されるようになります。
 
(コマンド)コンパイル時に「-g」付与
$ g++ -g -o memorytest memorytest.cpp
この状態で次のコマンドでメモリチェックを実行すると、「by 0x40059E: main (memorytest.cpp:5)」のように問題となった具体的な行数を教えてくれます。
 
(実行コマンド)メモリチェック
valgrind --tool=memcheck --leak-check=yes ../memorytest
(例:AFTER)※行番号の情報「memorytest.cpp:5」がある
==11651== HEAP SUMMARY:
==11651==     in use at exit: 100 bytes in 1 blocks
==11651==   total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==11651==
==11651== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==11651==    at 0x4C2C866: operator new[](unsigned long) (vg_replace_malloc.c:579)
==11651==    by 0x40059E: main (memorytest.cpp:5)
==11651==
==11651== LEAK SUMMARY:
==11651==    definitely lost: 100 bytes in 1 blocks
==11651==    indirectly lost: 0 bytes in 0 blocks
==11651==      possibly lost: 0 bytes in 0 blocks
==11651==    still reachable: 0 bytes in 0 blocks
==11651==         suppressed: 0 bytes in 0 blocks
(図112)

(1-2) (参考)「-g」オプションについて

「-g」を指定してコンパイルすると、実行ファイル自身(拡張子「.out」)の中にGDBデバッガで使えるデバッグ情報を生成・保持します(正確には「シンボルテーブル」(※注1)やデバッグ用のメタデータが作られます)。
 
それらのデバッグ情報は、実行プログラムの領域とは別の領域に書き込みされるので、デバッガ以外(gdb以外)でプログラム実行(例:本番環境での実行など)する場合においては、性能面等での影響はありません。
 
(※注1)
「シンボルテーブル」はコンパイラが使用するデータ構造の事で、ソースコード内の各識別子がその定義に関連する情報とともに格納されています(例:スコープ、型、行番号など)。

Adsense審査用広告コード


Adsense審査用広告コード


-C++, Valgrind

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

C++のtime関数とlocaltime関数の違いについて

  <目次> (1) C++のtime関数とlocaltime関数の違いについて  (1-1) C++のlocaltime関数の概要とサンプル  (1-2) C++のtime関数の概要とサン …

ValgrindのStill Reachableの意味や実際のサンプルをご紹介

  <目次> (1) ValgrindのStill Reachableの意味や実際のサンプルをご紹介  (1-1) Valgrindの「Still Reachable」はどんな状況?  (1 …

C++における「>>」の意味について

  <目次> (1) C++における「>>」の意味について  (1-1) 概要  (1-2) サンプルプログラム  (1-3) どんな時に使われる?⇒データ圧縮  (1-4) 備 …

C++のlocaltime関数がスレッドアンセーフである理由と使用上の注意点

  <目次> (1) C++のlocaltime関数がスレッドアンセーフである理由と使用上の注意点  (1-1) localtime関数がスレッドアンセーフである理由  (1-2) loca …

C++の構造体とは?の作り方や使い方について

  <目次> (1) C++の構造体とは?の作り方や使い方について  (1-1) 構造体とは?  (1-2) サンプルプログラム  (1-3) 構造体の変数を定義する方法  (1-4) 構造 …

  • English (United States)
  • 日本語
Top