c++ - 如何确定调用堆栈结束?

标签 c++ callstack

所以我写了两个简单的类——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_;
};

这里的关键方法是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);
}

问题是……我该如何结束这个循环?我的意思是,根据 0 检查帧/返回地址有时可以解决问题,但并非总是如此(至少在 Windows 上如此)。

有什么建议吗?

最佳答案

在 Windows 上,读取 Thread Information Block可以给你堆栈的顶部和底部,这样你就可以在阅读超出该范围的任何内容之前停下来。不过,我不知道如何在其他操作系统上获取类似信息。

关于c++ - 如何确定调用堆栈结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10014307/

相关文章:

c - 分配一个新的调用堆栈

c# - VS 2010 调试 - 从哪里调用方法?

c++ - OpenGL通用图像读取器和GLFW(glfwReadImage、glfwLoadTexture2D)支持各种图像格式

c++ - 在原始图像和转换后的图像之间进行插值

c++ - 如何获取 C++20 std::ranges 范围内值的类型?

c++ - 关于 --> 在 C++ 中的混淆?

c - Linux进程堆栈被局部变量溢出(堆栈保护)

c++ - c++ 目标文件应该只通过 g++ 链接吗?

python - 如何从解释器堆栈中获取绑定(bind)方法的类名?

debugging - 带有变量的haskell中调用堆栈的跟踪