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メモ