1. ホーム
  2. c

[解決済み] なぜGDBは予測できない行間ジャンプをしたり、変数を"<value optimized out>"と表示したりするのですか?

2023-04-20 10:38:28

質問

gdbのこの挙動を説明できる人はいますか?

900         memset(&new_ckpt_info,'\0',sizeof(CKPT_INFO));
(gdb)
**903         prev_offset   = cp_node->offset;**
(gdb)
**905         m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_** HDR),i_offset);
(gdb)
**903         prev_offset   = cp_node->offset;**
(gdb)
**905         m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_ HDR),i_offset);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
913         found = cpnd_find_exact_ckptinfo(cb , &ckpt_info , bitmap_offset , &offset , &prev_offset);
(gdb)
916         if(!found)
(gdb) p found
$1 = <value optimized out>
(gdb) set found=0
Left operand of assignment is not an lvalue.

なぜ903行目を実行した後、再び905 908 910で同じように実行されるのでしょうか?

もうひとつは foundbool -型の変数なので、なぜ value optimized out ? の値を設定することができません。 found の値も設定できません。

これはコンパイラの最適化だと思われます(この場合、その -O2 の値を設定することができます。 found ?

どのように解決するのですか?

最適化されたコードをデバッグするには、アセンブリ言語や機械語を学ぶ必要があります。

GDB TUI モードを使用します。私の GDB では、マイナス記号と Enter キーを入力すると TUI モードが有効になります。次に、C-x 2 (つまり、Control を押しながら X を押して、両方を放してから 2 を押す) を入力します。これでソースとディスアセンブリの分割表示になります。次に stepinexti でマシン命令を1つずつ移動します。TUIウィンドウを切り替えるには、C-x oを使用します。

お使いの CPU の機械語と関数の呼び出し規則に関する PDF をダウンロードしてください。関数の引数や戻り値で何が行われているのか、すぐに認識できるようになります。

レジスタの値を表示するには、次のようなGDBコマンドを使用します。 p $eax