2

我有一个计算密集型模块,我在其中添加了堆栈跟踪,以便能够找到特定的问题。尽管启用此堆栈跟踪时允许应用程序运行得更慢,但它的运行速度不得慢 10 倍。这就是为什么我没有使用 DBGHELP.DLL 中的 StackWalk 例程,而是我自己使用帧指针遍历堆栈(所以我不使用 Frame Pointer Omission 编译器选项)。

在大多数情况下,获取调用堆栈可以正常工作并且非常快,但在某些情况下,我的逻辑会失败,因为其中一个帧指针指向堆栈外部的地址(不多,只是一点点)。

我知道这可能是某个地方的错误,但是为了使我的代码更安全,我需要一种方法来检查帧指针是否指向当前线程堆栈中的内存位置。该应用程序是 64 位的,在 Windows 下运行。

如何在 Windows 上获取线程堆栈信息中的代码?可能解决了这个问题,但是由于这调用了其他函数,它可能会使我的代码运行得更慢(老实说,我没有测试它)。

我还发现了一些应该执行技巧的内联汇编代码(http://nasutechtips.blogspot.com/2011/01/thread-information-block-tib-and-fs.html),但内联汇编不支持Microsoft 的 64 位 C++ 编译器。

此外,内在的 __readfsqword 似乎不适用于 64 位。

关于如何尽可能快地获得 64 位 TIB 的任何其他建议?

4

2 回答 2

3

找到了,下面的代码可以解决问题:

#include <windows.h>
#include <winnt.h>

struct _TEB
   {
   NT_TIB NtTib;
   // Ignore rest of struct
   };

void *startOfStack;
startOfStack = NtCurrentTeb()->NtTib.StackBase;
std::cout << "startOfStack = " << startOfStack << std::endl;

我查看了 winnt.h 中 NtCurrentTeb() 的定义,看起来这是一个非常低级的函数,所以它可能足够快以获得我想要的。

于 2012-05-29T16:07:02.007 回答
3

它应该__readgsqword代替__readfsqword64 位。

于 2013-06-11T09:25:40.907 回答