だから私は2つの単純なクラスを書いた - X86StackFrameとX86CallStack:ここで重要な方法はX86CallStackのctorのあるコールスタックの終了を判断する方法は?
class X86StackFrame {
public:
X86StackFrame(void *frmAddr, void *retAddr);
inline void *GetFrameAddress() const
{ return frmAddr_; }
inline void *GetReturnAddress() const
{ return retAddr_; }
private:
void *frmAddr_;
void *retAddr_;
};
class X86CallStack {
public:
X86CallStack();
inline std::deque<X86StackFrame> GetFrames() const {
return frames_;
}
private:
std::deque<X86StackFrame> frames_;
};
を:
static inline void *GetReturnAddress(void *frmAddr) {
return *reinterpret_cast<void**>(reinterpret_cast<char*>(frmAddr) + 4);
}
static inline void *GetNextFrame(void *frmAddr) {
return *reinterpret_cast<void**>(frmAddr);
}
X86CallStack::X86CallStack()
: frames_()
{
void *frmAddr;
void *retAddr;
#if defined _MSC_VER
__asm mov dword ptr [frmAddr], ebp
#elif defined __GNUC__
__asm__ __volatile__(
"movl %%ebp, %0;" : "=r"(frmAddr) : :);
#endif
do {
if (frmAddr == 0) {
break;
}
retAddr = GetReturnAddress(frmAddr);
if (retAddr == 0) {
break;
}
frmAddr = GetNextFrame(frmAddr);
frames_.push_back(X86StackFrame(frmAddr, retAddr));
} while (true);
}
そして問題は、私がループすることを終わらんか...でしょうか?つまり、フレーム/リターンアドレスを0と照合することは、時にはトリックですが、必ずしもそうではありません(少なくともここではWindows)。
提案がありますか?
gcc.tgz/gcc/config/ia64/unwind-ia64.cが見つかりました。また、getcontextとpthreadライブラリからの何かがスレッドスタックメモリ領域を与えるでしょう。 –
AFAIKはスタックフレームのみに依存しているため、この標準に準拠していない(標準スタックフレームを作成する)関数があるため、完璧な解決策ではありません。 MSVCデバッガには、コールスタックを完全に回復するためのシンボルも必要です。とにかく、スタックフレームが一貫しているならば、スタックの終わりは実際にゼロリターンアドレスによってマークされます。 – valdo