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からの代入は検知できない(滅多に使わないからいいかな?