У меня возникла странная проблема с профилировщиком выборки в 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
, предложенный Дэном Бартлеттом, похоже, помогает!