スタックトレースを取る。の続き

前回からちょっと発展して
関数名とアドレスを出力した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
やりたい放題。