スタックトレースを取る。
Windowsでスタックトレースを取ろうと思えば、
.NETを使えばSystem.DiagnosticsにあるStackTraceクラスとかで簡単に取れるらしい。
さて、今のプロジェクトはMFCなのでCLRを使えない?
よく知らないけど、出来たとしても、出来るまでが大変そう。
VC++のインラインアセンブラを使えば、スタックのフレームとリターンアドレスを取るくらいは簡単そう。
#pragma once #include <boost/format.hpp> #include <pstade/oven/foreach.hpp> #include <pstade/oven/counting.hpp> namespace hwm { template<typename Strm> Strm& StackTracer(Strm& s, unsigned int num_of_trace = -1) { int esp_; int ebp_; int addr_; { __asm mov esp_, esp; //get esp __asm mov ebp_, ebp; //get ebp } s << "//==============================================//" << std::endl; try { PSTADE_OVEN_FOREACH(i, pstade::oven::counting(0, num_of_trace)) { { __asm mov ebx, ebp_; __asm mov eax, [ebx]; //get 'prev'ebp __asm push eax; //save __asm mov eax, ebp_; __asm mov esp_, eax; //esp = ebp('prev'esp) __asm pop eax; //restore __asm mov ebp_, eax; //ebp = 'prev'ebp __asm mov ebx, ebp_; __asm add ebx, 4; __asm mov eax, [ebx]; //return address __asm mov addr_, eax; } s << boost::format("esp : %08x, ebp : %08x, ret_addr : %08x") % esp_ % ebp_ % addr_ << "\n"; } } catch(...) { s << "!!Out of stack Access!!" << std::endl; } s << "//==============================================//\n" << std::endl; return s; } }
ここから関数名を割り出したりとかって言うのは、ソース上から出来るもんなのだろうか?
ちなみに、当たり前だけど、VC++のコード生成はSEHの例外を捕捉できるようにしておかないと、落ちる。