Подтвердить что ты не робот

GetThreadContext завершается с ошибкой после успешного SuspendThread в Windows 7

Я сталкиваюсь с нечетной проблемой профайлера пробоотбора в Windows 7 (таких проблем нет в AFAICT на предыдущих операционных системах Windows, будь то 32 или 64 бит).

Профилировщик работает, периодически приостанавливая поток с SuspendThread, затем просматривает контекст с помощью GetThreadContext, прежде чем вызывать ResumeThread, чтобы перезапустить процесс. Все это делается из контекста потока мультимедийного таймера (для точности около 1 кГц, который на операциях до Windows 7 обычно несет незначительное снижение производительности).

Только в Windows 7 и Windows 7, даже если вызовы SuspendThreadResumeThread) все успешны, вызовы GetThreadContext завершаются с ошибкой:

ERROR_NOACCESS
998 (0x3E6)
Недопустимый доступ к ячейке памяти.

с очень высокой вероятностью, хотя и не всегда.

Под этим я подразумеваю, что для некоторых прогонов профилирования все будет работать так же, как и на других операционных системах (все вызовы GetThreadContext будут успешными), но для других прогонов они почти все терпят неудачу (сэкономьте дюжину, может быть, из десятков тысячных). Это происходит с теми же самыми двоичными файлами, теми же параметрами.

Я пробовал предложения по неопределенно похожим проблемам, чтобы повторить вызов GetThreadContext, без каких-либо успехов. Я также пробовал делать Sleep между SuspendThread и GetThreadContext, тогда GetThreadContext выполняется чаще, хотя это приводит к резкому замедлению.

Предполагается, однако, что ОС Windows 7 возвращается с SuspendThread, пока поток, вероятно, еще не заблокирован, хотя, если это так, я не знаю, как или если вы должным образом ожидаете приостановления, нить и обстрел GetThreadContext не делают этого.

Изменить: 16 байт, выравнивая адрес структуры CONTEXT для GetThreadContext, как это было предложено Кажется, Дэн Бартлетт делает трюк!

4b9b3361

Ответ 1

Глядя на функцию GetThreadContext, он упоминает, что

Структура CONTEXT отличается высокой спецификой для процессора. Обратитесь к заголовочному файлу WinNt.h для определений, специфичных для процессора, для этих структур и любых требований к выравниванию.

И глядя на этот файл, _CONTEXT объявляется с помощью

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
...

Возможно, это может быть проблема выравнивания.