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++のマルチスレッド処理のサンプルや概要について

  <目次> (1) C++のマルチスレッド処理のサンプルや概要について  (1-1) C++のマルチスレッドの概要  (1-2) 構文1:関数ポインタ式  (1-3) 構文1(例):関数ポ …

C++の共用体とは?構造体との違いや使用方法について

  <目次> (1) C++の共用体とは?構造体との違いや使用方法について  (1-1) 共用体とは?構造体との違いは?  (1-2) 共用体の定義方法、変数定義方法、初期化方法  (1-3 …

C++のtime関数やtime_t型の使い方について

  <目次> (1) C++のtime関数やtime_t型の使い方について  (1-1) C++のtime関数とtime_t型とは?  (1-2) C++のtime_t関数のサンプル (1) …

GDBの使い方をC++のプログラムのデバッグを例にご紹介

  <目次> (1) GDBの使い方をC++のプログラムのデバッグを例にご紹介  (1-1) GDBのデバッグのシナリオ概要(例)  (1-2) GDBのデバッグ手順(例)  (1-3) そ …

C++のポインタとは?概念や基本的な使い方をご紹介

  <目次> (1) C++のポインタとは?概念や基本的な使い方をご紹介  (1-1) はじめに  (1-2) ポインタとは? (1) C++のポインタとは?概念や基本的な使い方をご紹介 「 …

  • English (United States)
  • 日本語
Top