项目升级64位后,原有的方式不可用,而使用 SymInitialize方法又太耗时,后续参考了 boost/stacktrace.hppbasic_stacktrace,使用 RtlCaptureStackBackTrace解决问题

代码

/*
 * 功能:收集当前堆栈信息
 * 参考自Boost/stacktrace.hpp的`class basic_stacktrace`
 * pBuf: 存堆栈信息的Buf
 * uiBufLen: Buf大小
 * dwMaxDepth: 获取的堆栈最大深度
 */
void StackBackTrace(char* pBuf, const size_t uiBufLen, const DWORD dwMaxDepth)
{
    if ((NULL == pBuf) || (0 == uiBufLen))
    {
        return;
    }

    try
    {
        pBuf[0] = '\0';
        const DWORD dwArrSize = 128;
        void* arrStackPtr[dwArrSize];
        const DWORD dwDepth = dwArrSize < dwMaxDepth ? dwArrSize : dwMaxDepth; // 堆栈深度取入参的dwMaxDepth和数组大小dwArrSize中的最小值
        const WORD iFramesCount = RtlCaptureStackBackTrace(1, dwDepth, arrStackPtr, 0);
        if ((dwArrSize > iFramesCount) || (iFramesCount == dwMaxDepth))
        {
            size_t uiPos = 0;
            // 将堆栈指针按字符串存储
            for (WORD i = 0; i < iFramesCount; ++i)
            {
                // 防止超过Buf大小
                if (uiPos + 128 > uiBufLen)
                {
                    break;
                }

                const int iSprintfLen = sprintf_s(pBuf + uiPos, 128, "(%p:%i) ", arrStackPtr[i], i);
                if (iSprintfLen <= 0)
                {
                    break;
                }

                uiPos += iSprintfLen;
            }

            return;
        }
    }
    catch(...)
    {
        // ignore exception
    }
}

效果

最后修改:2021 年 12 月 16 日