スタックトレースを取る。の続き
前回からちょっと発展して
関数名とアドレスを出力したmapファイルを利用するようにしました。
使用イメージ
#include <iostream> #include <sstream> #include <fstream> #include <boost/typeof/typeof.hpp> #include <boost/current_function.hpp> #define PRINT_FUNC() { std::cout << BOOST_CURRENT_FUNCTION << std::endl; } #include "stack_trace/stack_trace.hpp" #include "stack_trace/func_list.hpp" #include "stack_trace/tracer.hpp" int foo() { namespace st = hwm::stack_trace; const char* MAP_NAME = "test.map"; BOOST_AUTO(static p, st::make_shared_func_list(std::fstream( MAP_NAME ) )); PRINT_FUNC(); std::stringstream s; s << "-----------------------------------------" << std::endl; hwm::stack_trace::stack_trace(st::make_tracer(s, p)); s << "-----------------------------------------" << std::endl; std::cout << s.str() << std::endl; return 1; } int bar(int i) { PRINT_FUNC() return foo() + i; } int baz(int i, int j) { PRINT_FUNC(); return bar(i) + j; } int main() { #if defined BOOST_MSVC std::cout << "msvc build" << std::endl; #elif defined BOOST_GCC std::cout << "gcc build" << std::endl; #endif PRINT_FUNC(); return baz( 2, 3 ); }
で、出力イメージ
msvc build int __cdecl main(void) int __cdecl baz(int,int) int __cdecl bar(int) int __cdecl foo(void) ----------------------------------------- esp : 0012fda0, ebp : 0012fdb0, ret_addr : 0040ea50, func : ??$stack_trace@U?$Tracer@V?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@0hwm@@@stack_trace@hwm@@YAXAAU?$Tracer@V?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@01@I@Z(+0x10) esp : 0012fdb0, ebp : 0012fdc0, ret_addr : 004073f9, func : ?foo@@YAHXZ(+0x199) esp : 0012fdc0, ebp : 0012ff54, ret_addr : 00407506, func : ?bar@@YAHH@Z(+0x26) esp : 0012ff54, ebp : 0012ff5c, ret_addr : 0040753a, func : ?baz@@YAHHH@Z(+0x2a) esp : 0012ff5c, ebp : 0012ff68, ret_addr : 00407598, func : _main(+0x48) esp : 0012ff68, ebp : 0012ff78, ret_addr : 004424e7, func : _localeconv(+0x191) esp : 0012ff78, ebp : 0012ffc0, ret_addr : 7c817077, func : _SetEnvironmentVariableA@8(+0x7c3afd81) esp : 0012ffc0, ebp : 0012fff0, ret_addr : 00000000, func : error -----------------------------------------
現状msvcの方のmapファイルにしか対応していない。さらに、フォーマットとかを見たわけではないので動かないmapファイルがあるかも。
そして、gccとmsvcのmapファイルは全然別物だから、そっちも解析できるようにしたい。
sourceのアップロードは明日。できたらお昼。
というわけで、source
やりたい放題。