nmコマンドでシンボルのサイズを調べる方法

nmコマンドでシンボルのサイズを調べる方法

Posted at September 1,2017 12:03 AM
Tag:[Linux]

nmコマンドでシンボルのサイズを調べる方法を紹介します。

1.問題点

次のサンプルプログラムを作りました。目的は配列変数a,b,cのサイズ取得です。

test.cc

int main() {
    static int a[1000];
    static int b[10000];
    static int c[100];
    return 0;
}

ビルドして実行ファイルa.outを作成します。

% g++ test.cc
% ls -l
合計 16
-rwxr-xr-x 1 root root 8561  8月 31 00:18 a.out
-rw-r--r-- 1 root root  102  8月 31 00:19 test.cc

nmコマンドで実行ファイル指定すると、次のように表示されます。"--demangle"はシンボルをデマングルするためのオプションですが、今回の問題を解決するための本質ではないので説明は省略します。

% nm --demangle a.out
0000000000600df8 d _DYNAMIC
0000000000601000 d _GLOBAL_OFFSET_TABLE_
0000000000400640 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
000000000060ae40 b main::a
0000000000601200 b main::b
0000000000601060 b main::c
0000000000400778 r __FRAME_END__
0000000000600df0 d __JCR_END__
0000000000600df0 d __JCR_LIST__
0000000000601030 D __TMC_END__
000000000060102c B __bss_start
0000000000601028 D __data_start
0000000000400560 t __do_global_dtors_aux
0000000000600de8 t __do_global_dtors_aux_fini_array_entry
0000000000400648 R __dso_handle
0000000000600de0 t __frame_dummy_init_array_entry
                 w __gmon_start__
0000000000600de8 t __init_array_end
0000000000600de0 t __init_array_start
0000000000400630 T __libc_csu_fini
00000000004005c0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
000000000060102c D _edata
000000000060bde0 B _end
0000000000400634 T _fini
0000000000400468 T _init
00000000004004c0 T _start
0000000000601040 b completed.6337
0000000000601028 W data_start
00000000004004f0 t deregister_tm_clones
0000000000400580 t frame_dummy
00000000004005b0 T main
0000000000400520 t register_tm_clones

サンプルプログラムの中にある各データは、

000000000060ae40 b main::a
0000000000601200 b main::b
0000000000601060 b main::c

で、それぞれのサイズを知るには、次のシンボル開始アドレスから自分の開始アドレスを引けばいいはずです。

が、より簡単に調べたい方法が分かりません。

ということで、nmコマンドでシンボルのサイズを調べる方法を紹介します。

2.シンボルのサイズを調べる

シンボルのサイズを調べるには、"--size-sort"オプションを利用します。

% nm --demangle --size-sort a.out
0000000000000001 b completed.6337
0000000000000002 T __libc_csu_fini
0000000000000004 R _IO_stdin_used
000000000000000b T main
0000000000000065 T __libc_csu_init
0000000000000190 b main::c
0000000000000fa0 b main::a
0000000000009c40 b main::b

"--size-sort"はシンボルをサイズの順にソートするオプションです。

表示されている値はシンボルの値ではなくサイズで、シンボルの値を次に現われる シンボルの値から引いたものです。

これで配列変数a,b,cのサイズがそれぞれ"fa0","9c40","190"であることが分かります。

さらに"--reverse-sort"オプションを付与すると、サイズの大きい順にソートしてくれます。

% nm --demangle --size-sort --reverse-sort a.out
0000000000009c40 b main::b
0000000000000fa0 b main::a
0000000000000190 b main::c
0000000000000065 T __libc_csu_init
000000000000000b T main
0000000000000004 R _IO_stdin_used
0000000000000002 T __libc_csu_fini
0000000000000001 b completed.6337

これで配列変数a,b,cのサイズが、b>a>cであることが一発でわかります。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)