Я сталкиваюсь с нечетной проблемой профайлера пробоотбора в Windows 7 (таких проблем нет в AFAICT на предыдущих операционных системах Windows, будь то 32 или 64 бит).
Профилировщик работает, периодически приостанавливая поток с SuspendThread
, затем просматривает контекст с помощью GetThreadContext
, прежде чем вызывать ResumeThread
, чтобы перезапустить процесс. Все это делается из контекста потока мультимедийного таймера (для точности около 1 кГц, который на операциях до Windows 7 обычно несет незначительное снижение производительности).
Только в Windows 7 и Windows 7, даже если вызовы SuspendThread
(и ResumeThread
) все успешны, вызовы GetThreadContext
завершаются с ошибкой:
ERROR_NOACCESS
998 (0x3E6)
Недопустимый доступ к ячейке памяти.
с очень высокой вероятностью, хотя и не всегда.
Под этим я подразумеваю, что для некоторых прогонов профилирования все будет работать так же, как и на других операционных системах (все вызовы GetThreadContext
будут успешными), но для других прогонов они почти все терпят неудачу (сэкономьте дюжину, может быть, из десятков тысячных). Это происходит с теми же самыми двоичными файлами, теми же параметрами.
Я пробовал предложения по неопределенно похожим проблемам, чтобы повторить вызов GetThreadContext
, без каких-либо успехов. Я также пробовал делать Sleep
между SuspendThread
и GetThreadContext
, тогда GetThreadContext
выполняется чаще, хотя это приводит к резкому замедлению.
Предполагается, однако, что ОС Windows 7 возвращается с SuspendThread
, пока поток, вероятно, еще не заблокирован, хотя, если это так, я не знаю, как или если вы должным образом ожидаете приостановления, нить и обстрел GetThreadContext
не делают этого.
Изменить: 16 байт, выравнивая адрес структуры CONTEXT
для GetThreadContext
, как это было предложено Кажется, Дэн Бартлетт делает трюк!