在 Windows 7 中成功 SuspendThread 后 GetThreadContext 失败 [英] GetThreadContext fails after a successful SuspendThread in Windows 7

查看:23
本文介绍了在 Windows 7 中成功 SuspendThread 后 GetThreadContext 失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm encountering an odd issue on a sampling profiler in Windows 7 (no such issues AFAICT on previous Windows OSes, be they 32 or 64 bit).

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

The profiler works by periodically suspending a thread with SuspendThread, then looks at the context with GetThreadContext, before invoking ResumeThread to restart the process. All this is done from the context of the thread of a multimedia timer (for accuracy, at about 1kHZ, which on pre-Windows 7 OSes usually incurs a negligible performance penalty).

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

Under Windows 7, and Windows 7 only, even though the calls to SuspendThread (and ResumeThread) all succeed, the calls to GetThreadContext fail with error:

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

ERROR_NOACCESS
998 (0x3E6)
Invalid access to memory location.

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

with a very high likeliness, though not all the time.

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

By that I mean that for some profiling runs, everything will work as it does on other OSes (all the GetThreadContext calls will succeed), but for other runs, they will almost all fail (save a dozen maybe, out of tens of thousandths). It's happening with the exact same binaries, the same parameters.

我已经尝试了关于看起来有点相似的问题的建议,以重复 GetThreadContext 调用,但没有更多成功.我也试过在 SuspendThreadGetThreadContext 之间做一个 Sleep,然后 GetThreadContext 更频繁地成功,虽然它导致急剧放缓.

I've tried suggestions on vaguely similar looking issues to repeat the GetThreadContext call, with no more success. I've also tried doing a Sleep between the SuspendThread and GetThreadContext, then the GetThreadContext succeeds more often, though it results in drastic slowdowns.

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

It suggests however that Windows 7 OS is returning from SuspendThread while the thread has probably not been suspended yet - though, if that's the case, I've no idea how or if to properly wait on the suspension, looping in the thread and pounding GetThreadContext doesn't do it.

16 字节对齐 GetThreadContext 的nofollow noreferrer">CONTEXT 结构似乎可以解决问题!

16 byte aligning the address of the CONTEXT structure for GetThreadContext as suggested by Dan Bartlett seems to be doing the trick!

推荐答案

GetThreadContext 函数,它提到了

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

The CONTEXT structure is highly processor specific. Refer to the WinNt.h header file for processor-specific definitions of this structures and any alignment requirements.

查看这个文件,_CONTEXT 声明为

And looking at this file, _CONTEXT is declared with

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
...

所以可能是对齐问题.

这篇关于在 Windows 7 中成功 SuspendThread 后 GetThreadContext 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆