dumper-0.1.0

http://shinh.skr.jp/binary/dumper.tgz

C で使える Kernel#p 作りました。マジメにやってみると結構面倒だったです。

http://d.hatena.ne.jp/shinichiro_h/20051207#1133881740

の続きです。

libdwarf が必要なので、なんとなく適当な rpm パッケージも作りました。 Debian はパッケージがあるみたいですね。

http://shinh.skr.jp/binary/libdwarf.spec

http://shinh.skr.jp/binary/libdwarf-20051201-1.i386.rpm

typedef struct TestDump_ {
    short s;
    int i;
    long l;
    size_t st;
    unsigned long long ll;
    char c;
    char* str;
    void* ptr;
    void* const volatile * cvptr;
    struct TestDump_* dump;
    int (*fp) (int, char*[]);
    int (*ifp) (int, char*[]);
    int array[10];
    enum TestEnum { ENUM1, ENUM2 };
    TestEnum en;
    union TestUnion {
        int i;
        char b[4];
    };
    TestUnion un;
    struct {
    } no_name_struct;
} TestDump;

っていう構造体があって、

    dump_open(argv[0]);
    TestDump d;
    /* 適当に値をセット */
    p(d);

の結果が、

d = {
  s = 2 (0x0002) : short int
  i = 3 (0x00000003) : int
  l = 4 (0x00000004) : long int
  st = 5 (0x00000005) : size_t
  ll = 17592186044415 (0x00000fffffffffff) : long long unsigned int
  c = 'c' (63) : char
  str = "hoge-" (0x805c9ce) : char*
  ptr = 0xbfe0d4fc : void*
  cvptr = 0xbfe0d51c : void**
  dump = (nil) (invalid ptr) : TestDump_*
  fp = int main(int, char**) (0x8055726) : func*
  ifp = (nil) (invalid ptr) : func*
  array = { 1 (0x00000001), ... } : int[10]
  en = ENUM2 : TestEnum
  un = {
    i = 6513249 (0x00636261) : int
    b = "abc" : char[4]
  } : TestUnion
  no_name_struct = {
  } : <no name>
} : TestDump

C++も一応。

cpp = {
  <inherit> = {
    selfBase = 0xbfe0d564 : TestCppBase&
  } : TestCppBase
  cppstr = {
    _M_dataplus = {
      <inherit> = { ... } : allocator<char>
      _M_p = "fuga-" (0x81eb05c) : char*
    } : _Alloc_hider
  } : string
  cppvec = {
    <inherit> = {
      _M_impl = { ... } : _Vector_impl
    } : _Vector_base<int,std::allocator<int> >
  } : vector<int,std::allocator<int> >
  cppmap = {
    _M_t = {
      _M_impl = { ... } : _Rb_tree_impl<std::less<int>,false>
    } : _Rb_tree<int,std::pair<const int, int>,std::_Select1st<std::pair<const i
nt, int> >,std::less<int>,std::allocator<std::pair<const int, int> > >
  } : map<int,int,std::less<int>,std::allocator<std::pair<const int, int> > >
  self = 0xbfe0d564 : TestCpp&
} : TestCpp

TODOメモ

  • ポインタにアクセスできるかを確認するために mprotect でメモリ保護を変更してみて確認してるけどもう少し良い方法は無いか。 Linux 限定なら /proc/self/maps 見るけど。
  • ビットフィールド
  • p のインターフェイスはもう少し改善できると思う
  • 汚ないソース
  • C++STL は各個対応すべき
  • パッケージとかもう少しまともに
  • ObjCなど他の言語でチェック
なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h