日曜技術者のメモ

趣味でやった事のメモ書きです。

GDBでsc_int、sc_uintのアンダー/オーバーフロー検出をしてみた

SystemCライブラリのコードにオーバーフロー/アンダーフローを検出する機構を考えてた時に Twitter上でGDBでできると教えてもらったのでやってみた。

始めはGDB+Pythonを使おうかと思ったけどGDBコマンドでそれっぽくできた。

SystemCライブラリ

まずはSystemCライブラリをコンパイルする時にデバックオプションをつける為 configureファイルを修正する。

systemc-2.3.0.tgz内のconfigure

OPT_CXXFLAGS="-O3"
       ↓
OPT_CXXFLAGS="-O0 -g"

修正したら configure→make→make install

GDBコマンド

sc_dt::sc_uint_base::extend_sign()とsc_dt::sc_int_base::extend_sign()
にブレイクポイントを置いてオーバーフロー/アンダーフロー検知してバックトレースを表示する
↓を「under_over_flow_check」という名前で保存

  • under_over_flow_check
set pagination off
set breakpoint pending on

b sc_dt::sc_uint_base::extend_sign()
command 1
silent
if(m_val > (~UINT_ZERO >> m_ulen))
printf "------------------------------\n"
printf "sc_uint<%d> m_val %d\n",m_len,m_val
bt 4
end
continue
end

b sc_dt::sc_int_base::extend_sign()
command 2
silent
if(( m_val < -((int_type) 1 << ( m_len - 1 ))) || ( m_val >= ((int_type) 1 << ( m_len - 1 ))))
printf "------------------------------\n"
printf "sc_int<%d> m_val %d\n",m_len,m_val
bt 4
end
continue
end
r
quit

サンプルコード

適当

#include <systemc.h>

int sc_main(int argc, char *argv[]) {
  sc_int<8>  int8; //127~-128
  sc_int<4>  int4; //7~-8
  sc_uint<8> uint8;//255~0
  sc_uint<4> uint4;//15~0
  sc_uint<8> tmp_ui8;
  
  sc_lv<8>   lv8;
  lv8 = "1111111";
  
  //固定値代入
  int8 = 255;    //over flow
  int8 = -(255); //under flow
  uint8 = 256;   //over flow
  uint8 = -1;    //under flow
  
  //これは検出できない
  uint4 = lv8;
  
  return 0;
}

実行結果

デバッグオプション付きでコンパイル後以下コマンドでGDBを呼び出す。

gdb --command=under_over_flow_check <実行ファイル>

実行結果

             SystemC 2.3.0-ASI --- Mar  9 2014 13:23:24
        Copyright (c) 1996-2012 by all Contributors,
        ALL RIGHTS RESERVED

------------------------------
sc_int<8> m_val 255
#0  sc_dt::sc_int_base::extend_sign (this=0x7fffffffdf40) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_int_base.h:567
#1  0x0000000000403583 in sc_dt::sc_int_base::operator= (this=0x7fffffffdf40, a=255) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_int_base.h:652
#2  0x00000000004038ac in sc_dt::sc_int<8>::operator= (this=0x7fffffffdf40, a=255) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_int.h:244
#3  0x0000000000402fdb in sc_main (argc=1, argv=0x632ab0) at /home/ginnyu-tei/work/SC_GDB_test1/test.cpp:15
------------------------------
sc_int<8> m_val -255
#0  sc_dt::sc_int_base::extend_sign (this=0x7fffffffdf40) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_int_base.h:567
#1  0x0000000000403583 in sc_dt::sc_int_base::operator= (this=0x7fffffffdf40, a=-255) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_int_base.h:652
#2  0x00000000004038ac in sc_dt::sc_int<8>::operator= (this=0x7fffffffdf40, a=-255) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_int.h:244
#3  0x0000000000402fec in sc_main (argc=1, argv=0x632ab0) at /home/ginnyu-tei/work/SC_GDB_test1/test.cpp:16
------------------------------
sc_uint<8> m_val 256
#0  sc_dt::sc_uint_base::extend_sign (this=0x7fffffffdf00) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_uint_base.h:553
#1  0x00000000004033b9 in sc_dt::sc_uint_base::operator= (this=0x7fffffffdf00, a=256) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_uint_base.h:637
#2  0x00000000004038d2 in sc_dt::sc_uint<8>::operator= (this=0x7fffffffdf00, a=256) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_uint.h:244
#3  0x0000000000402ffd in sc_main (argc=1, argv=0x632ab0) at /home/ginnyu-tei/work/SC_GDB_test1/test.cpp:17
------------------------------
sc_uint<8> m_val -1
#0  sc_dt::sc_uint_base::extend_sign (this=0x7fffffffdf00) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_uint_base.h:553
#1  0x00000000004033b9 in sc_dt::sc_uint_base::operator= (this=0x7fffffffdf00, a=-1) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_uint_base.h:637
#2  0x00000000004038d2 in sc_dt::sc_uint<8>::operator= (this=0x7fffffffdf00, a=-1) at /home/ginnyu-tei/lib/SystemC-2.3.0_Debug/include/sysc/datatypes/int/sc_uint.h:244
#3  0x000000000040300e in sc_main (argc=1, argv=0x632ab0) at /home/ginnyu-tei/work/SC_GDB_test1/test.cpp:18
[Inferior 1 (process 34197) exited normally]

課題

・検出できない呼び出しがあるかも? ・sc_biguint、sc_bigintへの対応
・バックトレースログが見にくいので何とかする。
・sc_lv、sc_bvからの代入は検知できない(滅多に使わないからいいかな?