GDB Python スクリプトでビットを表示

マイコンではレジスタでビットフラグが多用されているが、慣れていないと gdb の x コマンドでメモリの値を読み出してもどのビットがセットされているか分かりにくい。

GDB Python スクリプトでなんとかできそうだったが情報が少なかったので残しておく。

Python スクリプトから GDB の機能を実行する方法は以下に記載がある。

Python コード埋め込み

gdbinit ファイルを -x オプションで読み込むと、設定や独自の定義のコマンドが利用できる。

この設定ファイルに Python のコードを埋め込める。python ... end の間に Python のコードを書ける。

python
# Python code
end

Python コード実行

python 命令で Python のコードを実行できる。

python call_func()

定義コマンドの中で実行するなら引数を渡すこともできる。

define xbits
    python bits($arg0)
end

引数は $arg0, $arg1, ... など。

ビット表示

アドレスを引数として受け取るとそのアドレスの値を x コマンドの出力から得て、ビットとして表示する xbits およびそのエイリアス xt を作成した。

python

def _bits_extend(value, max, min):
    vs = []
    vs.append("")
    for i in range(min, max + 1)[::-1]:
        if (value & (1 << i)) > 0:
            vs.append(" 1")
        else:
            vs.append(" 0")
    vs.append("")
    return "|".join(vs)

def bits(arg0):
    addr, tvalue = gdb.execute('x {}'.format(arg0), to_string=True).rstrip().split("\t")
    value = int(tvalue, 16)
    s = []
    s.append("{}\t{}".format(addr, tvalue))
    s.append("|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|")
    s.append(_bits_extend(value, 31, 16))
    #s.append("")
    s.append("|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|")
    s.append(_bits_extend(value, 15, 0))
    print("\n".join(s))

end


define xbits
    python bits($arg0)
end

alias -a xt = xbits

実行結果

(gdb) xt 0x50110000
0x50110000:	0x00000000
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|

このように各ビットがひと目で分かる。

ブラウザでビットフラグを表示

数値をビットに展開して表示するページを作成しました。10進数および0xから始まる16進数を入力できます。