在 Windows 7 中成功 SuspendThread 后 GetThreadContext 失败

发布于 2024-10-12 02:51:30 字数 1468 浏览 3 评论 0原文

我在 Windows 7 中的采样分析器上遇到了一个奇怪的问题(AFAICT 在以前的 Windows 操作系统上没有此类问题,无论是 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字节对齐

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).

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).

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)
Invalid access to memory location.

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

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.

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.

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泼猴你往哪里跑 2024-10-19 02:51:30

查看 GetThreadContext 函数,它提到

CONTEXT 结构是高度处理器特定的。请参阅 WinNt.h 头文件,了解该结构的处理器特定定义以及任何对齐要求。

查看此文件,_CONTEXT 是用 声明的

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
...

,因此可能是对齐问题。

Looking at the GetThreadContext function, it mentions that

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.

And looking at this file, _CONTEXT is declared with

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
...

So it's possible it could be an alignment issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文