2011-01-14 15 views
19

Windows 7のサンプリングプロファイラで奇妙な問題が発生しています(これまでのWindows OSでAFAICTは32または64ビットでした)。Windows 7のSuspendThreadが成功した後にGetThreadContextが失敗する

プロファイラは、スレッドをSuspendThreadに定期的に中断してから、ResumeThreadを呼び出す前にGetThreadContextというコンテキストを調べ、プロセスを再開します。これはマルチメディアタイマーのスレッドのコンテキストから実行されます(精度は約1kHzで、Windows 7以前のOSでは通常は無視されるパフォーマンスペナルティがあります)。非常に高いらしさと

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

、すべてではないものの:SuspendThread(とResumeThread)への呼び出しのすべてが成功にもかかわらず、唯一のWindows 7、およびWindows 7の下で

GetThreadContextへの呼び出しがエラーで失敗します時間。

これは、プロファイリングのいくつかの実行では、他のOSと同様にすべてが機能することを意味します(GetThreadContextの呼び出しはすべて成功します)が、他の実行ではほとんどすべてが失敗します数千分の1)。まったく同じバイナリ、同じパラメータで起こっています。

ぼんやりと似たような見た目の問題については、GetThreadContextコールを繰り返すための提案を試みましたが、これ以上の成功はありません。私はまた、SuspendThreadGetThreadContextの間でSleepを実行しようとしましたが、GetThreadContextがより頻繁に成功しますが、それは劇的な減速をもたらします。

Windows 7 OSがSuspendThreadから復帰していることを示唆していますが、スレッドがまだ停止されていない可能性がありますが、その場合はどうしたら停止するか、スレッドと叩きをGetThreadContextはしません。

編集:ダン・バートレットにより示唆されるようにGetThreadContextためCONTEXT構造体のアドレスを合わせる 16バイトは、トリックをやっているようです!

+0

非常に具体的に見えます。おそらく、問題を見つけるためにWindowsのチェックビルドを見つけるべきでしょうか? MSDN開発者フォーラムでこの問題について説明しましたか?あるいはMSに直接バグを報告することもできます。 – ChristianWimmer

+3

プロセスの作成時にTHREAD_ALL_ACCESSプロパティを使用しましたか? http://msdn.microsoft.com/en-us/library/ms686769(v=vs.85).aspxを参照してください。「Windows Server 2008およびWindows VistaではTHREAD_ALL_ACCESSフラグの値が増加しました」... –

+9

CONTEXTはWinNT.hの "DECLSPEC_ALIGN(16)"で宣言されています。 –

答えて

16

GetThreadContext機能を見ると、それはそう、それはアライメント問題になる可能性が可能です

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が

typedef struct DECLSPEC_ALIGN(16) _CONTEXT { 
... 

と宣言されていることを言及しています。

+0

愚かな面白い事実:あなたはGetThreadContext()をWindows 9xでCONTEXT構造体を16にアライメントして呼び出すことができますが、NTではメモリの位置を合わせてGetThreadContextをうまく動作させる必要があります。 –

関連する問題