2012年1月15日日曜日

gdb で void* 型の変数をデバッグする

C言語で実装されたライブラリやアプリケーションでは、汎用的な型として随所で void* が使用されますが、これをgdbからデバッグすると、そのままでは型情報が無いためタダのポインタとして扱われてしまいます。これではデバッグ時の都合がよろしくないです。
(gdb) print 0xfee65c0
$1 = 267281856
(gdb) print (void *)0xfee65c0
$2 = (void *) 0xfee65c0
こんなとき、この void* が指し示している先の型がわかりきっている場合は、その型でキャストしてやって:
(gdb) print (struct imap_session_state_data *)0xfee65c0
$4 = (struct imap_session_state_data *) 0xfee65c0
(gdb) print $4
$5 = (struct imap_session_state_data *) 0xfee65c0
参照先にアクセスすればきちんと中身が見えます:
(gdb) print * $4
$6 = {
  imap_session = 0xfee6560,
  imap_mailbox = 0xfee6230 "INBOX",
  imap_flags_store = 0xfee6490,
  imap_ssl_callback = 0,
  imap_ssl_cb_data = 0x0
}
(gdb) print $6->imap_session
$7 = (mailimap *) 0xfee6560
(gdb) print * $7
$8 = {
  imap_response = 0xfee6090 "FETCH completed",
  imap_stream = 0xfeecc90,
  imap_progr_rate = 0,
  imap_progr_fun = 0,
  imap_stream_buffer = 0xfee6a00,
  imap_response_buffer = 0xfee6a20,
  imap_state = 3,
  imap_tag = 4,
  imap_connection_info = 0xfee64d0,
  imap_selection_info = 0xfee6030,
  imap_response_info = 0xfee60e0,
  imap_sasl = {
    sasl_conn = 0x0,
    sasl_server_fqdn = 0x0,
    sasl_login = 0x0,
    sasl_auth_name = 0x0,
    sasl_password = 0x0,
    sasl_realm = 0x0,
    sasl_secret = 0x0
  },
  imap_idle_timestamp = 0,
  imap_idle_maxdelay = 1740,
  imap_body_progress_fun = 0,
  imap_items_progress_fun = 0,
  imap_progress_context = 0x0
}
これでデバッグがはかどりました。