简体   繁体   English

如何确定调用堆栈结束?

[英]How to determine end of call stack?

So I wrote two simple classes - X86StackFrame and X86CallStack:所以我写了两个简单的类——X86StackFrame 和 X86CallStack:

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_;
};

The key method here is X86CallStack's ctor:这里的关键方法是 X86CallStack 的 ctor:

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);
}

And the problem is... how do I end that loop?问题是……我该如何结束这个循环? I mean, checking frame/return address against 0 sometimes does the trick but not always (at least here on Windows).我的意思是,根据 0 检查帧/返回地址有时可以解决问题,但并非总是如此(至少在 Windows 上如此)。

Any suggestions?有什么建议么?

On Windows, reading the Thread Information Block can give you the top and bottom of the stack so you can stop before reading anything beyond that range.在 Windows 上,读取线程信息块可以为您提供堆栈的顶部和底部,因此您可以在读取超出该范围的任何内容之前停止。 I have no idea how to get similar info on other OSes, though.不过,我不知道如何在其他操作系统上获得类似的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM