【问题标题】:GetThreadContext fails after a successful SuspendThread in Windows 7在 Windows 7 中成功 SuspendThread 后 GetThreadContext 失败
【发布时间】:2011-06-09 10:52:57
【问题描述】:

我在 Windows 7 的采样分析器上遇到了一个奇怪的问题(在以前的 Windows 操作系统上没有此类问题 AFAICT,无论是 32 位还是 64 位)。

分析器通过定期使用SuspendThread 暂停线程,然后使用GetThreadContext 查看上下文,然后调用ResumeThread 重新启动进程。所有这些都是在多媒体计时器线程的上下文中完成的(为了准确,大约为 1kHZ,这在 Windows 7 之前的操作系统上通常会导致可忽略的性能损失)。

在 Windows 7 和仅 Windows 7 下,即使对 SuspendThread(和 ResumeThread)的调用都成功,对 GetThreadContext 的调用也会失败并出现错误:

ERROR_NOACCESS
998 (0x3E6)
对内存位置的访问无效。

可能性非常高,但并非总是如此。

我的意思是,对于某些分析运行,一切都会像在其他操作系统上一样工作(所有GetThreadContext 调用都会成功),但对于其他运行,它们几乎都会失败(可能会保存一打万分之几)。它发生在完全相同的二进制文件、相同的参数上。

我已经尝试了关于看起来有点相似的问题的建议,以重复 GetThreadContext 调用,但没有更多成功。我还尝试在SuspendThreadGetThreadContext 之间进行Sleep,然后GetThreadContext 更频繁地成功,尽管它会导致速度急剧下降。

这表明 Windows 7 操作系统正在从 SuspendThread 返回,而线程可能尚未暂停 - 但是,如果是这种情况,我不知道如何或是否正确等待暂停,循环进入线程和冲击GetThreadContext 不会这样做。

编辑: 16 字节对齐 GetThreadContextCONTEXT 结构的地址,正如 Dan Bartlett 所建议的那样,似乎可以解决问题!

【问题讨论】:

  • 看起来很具体。也许你应该找到一个检查过的 Windows 版本来发现问题?你在 MSDN 开发者论坛中描述过这个问题吗?或者直接向 MS 提交错误。
  • 您在创建进程时是否使用了 THREAD_ALL_ACCESS 属性?请参阅msdn.microsoft.com/en-us/library/ms686769(v=vs.85).aspx,其中指出“THREAD_ALL_ACCESS 标志的值在 Windows Server 2008 和 Windows Vista 上增加”...
  • CONTEXT 在 WinNT.h 中用“DECLSPEC_ALIGN(16)”声明,可能是对齐问题?
  • THREAD_ALL_ACCESS 不是吗(顺便说一句,2008 和 Vista 没有任何问题,只有七个)。然而,对齐似乎在起作用!!!谢谢丹,看起来他们改变了在 Win7 中写入上下文结构的方式!
  • @Dan:您应该将其作为答案提交,以便获得积分。 :)

标签: winapi windows-7 debugging


【解决方案1】:

查看GetThreadContext 函数,它提到了

CONTEXT 结构高度特定于处理器。有关此结构的特定于处理器的定义和任何对齐要求,请参阅 WinNt.h 头文件。

查看这个文件,_CONTEXT 声明为

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
...

所以可能是对齐问题。

【讨论】:

  • 愚蠢的有趣事实:您可以在 Windows 9x 上调用 GetThreadContext(),但 CONTEXT 结构未对齐到 16,但由于 NT,您需要对齐其内存位置才能使 GetThreadContext 正常工作。
猜你喜欢
  • 2011-03-27
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多