【发布时间】: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 调用,但没有更多成功。我还尝试在SuspendThread 和GetThreadContext 之间进行Sleep,然后GetThreadContext 更频繁地成功,尽管它会导致速度急剧下降。
这表明 Windows 7 操作系统正在从 SuspendThread 返回,而线程可能尚未暂停 - 但是,如果是这种情况,我不知道如何或是否正确等待暂停,循环进入线程和冲击GetThreadContext 不会这样做。
编辑: 16 字节对齐 GetThreadContext 的 CONTEXT 结构的地址,正如 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