在64位Windows应用程序中获取TID(线程信息块)的最快方法是什么?

3
我有一个非常计算密集的模块,在其中添加了堆栈跟踪以查找特定问题。虽然在启用此堆栈跟踪时允许应用程序运行更慢,但不能使其运行10倍更慢。这就是为什么我不使用DBGHELP.DLL中的StackWalk例程,而是使用帧指针自己遍历堆栈(因此我不使用帧指针省略编译器选项)。
在大多数情况下,获取调用堆栈可以正常工作并且非常快,但在某些情况下,我的逻辑会失败,因为其中一个帧指针指向堆栈外的地址(不多,只是一点点)。
我知道这可能是某个地方的错误,但为了使我的代码更安全,我需要一种方法来检查帧指针是否指向当前线程堆栈内存位置还是其他位置。该应用程序是64位的,运行在Windows下。 如何在Windows上获取线程堆栈信息?上的代码可能解决了这个问题,但由于它调用其他函数,所以可能会使我的代码运行得更慢(说实话,我没有测试过)。
我还发现了一些内联汇编代码,应该能够完成这个技巧(http://nasutechtips.blogspot.com/2011/01/thread-information-block-tib-and-fs.html),但是 Microsoft 的 64 位 C++ 编译器不支持内联汇编。
此外,__readfsqword 内置函数在 64 位上似乎无法使用。
有没有其他建议可以尽快获取 64 位 TIB?

很有趣,我目前也在为托管代码做同样的事情,我也遇到了完全相同的问题 ;-). - Alois Kraus
2个回答

4

在64位上应该使用__readgsqword而不是__readfsqword


4

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

#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()函数的定义,发现这是一个非常底层的函数,因此它可能足够快地获取我想要的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接