2014-01-30 5 views
5

Я знаю, что невозможно определить, сколько сообщений находится в очереди потоков в любой момент времени с помощью любых вызовов Win API. У меня есть приложение, которое не работает, потому что PostMessage иногда случается (возможно, из-за роста очереди до 10000, хотя я не вижу, как он может расти настолько большой). Это прерывистая проблема, и у меня есть несколько выемок памяти, сделанных в тот момент, когда это происходит. Очевидно, что очередь должна быть где-то и эта статья объясняет, как получить его http://moyix.blogspot.com/2008_09_01_archive.htmlПоиск количества сообщений в очереди сообщений потока из дампа памяти

Каждый поток в Windows (в лице _ETHREAD strucutre) имеет поле в тему Блок управления (или УТС, который является _KTHREAD) называется Win32Thread. Это поле указывает на структуру данных, _W32THREAD, которая определена в части режима ядра графической подсистемы Windows, win32k.sys. Фактически вы можете проверить структуру _W32THREAD , выпустив в WinDbg «dt win32k! _W32THREAD»; однако, если вы начните обратное проектирование win32k.sys, вы быстро обнаружите, что информация, указанная здесь, далека от завершения. Фактически, _W32THREAD - это гораздо более крупная структура данных, которая включает в себя информацию о текущем рабочем столе, раскладке клавиатуры, установленных оконных крючках, и, самое главное, важная для нас очередь ввода сообщений. В Windows XP SP2, очередь сообщения найдена по смещению 0xD0 из _W32THREAD, и выглядит следующим образом:

typedef struct _MSG_QUEUE { PMSG_QUEUE_ENTRY Head; 
PMSG_QUEUE_ENTRY Tail; unsigned long NumberOfMessages; } MSG_QUEUE; 

В основном я пытаюсь найти указатель MSG_QUEUE (который даст мне NumberOfMessages, плюс я могу перечислите их, начиная с головы). Однако он не выглядит, я могу найти указатели на любой из _ETHREAD, _KTHREAD и _W32THREAD, анализируя дамп памяти. Где именно они хранятся, находятся ли они в памяти процесса? Должен ли я работать в режиме ядра? Нужно ли загружать символы для win32k.sys? Что-нибудь еще мне нужно сделать? Благодарю.

+0

Просто интересно: что скажет GetLastError(), когда сообщение PostMessage Fail? – manuell

+0

Обычно это ERROR_NOT_ENOUGH_QUOTA, но в последнем отчете нет ошибки (ну это 0x12, вероятно, из некоторой более ранней ошибки чего-то еще) –

+2

KTHREAD и связанные структуры находятся в режиме ядра, но дампы памяти захватывают только пользовательский режим. Таким образом, информация не находится в файле дампа. –

ответ

1

Это не полный ответ со всеми командами WinDbg, но, возможно, еще полезно.

Очередь сообщений доступна только в режиме ядра, поэтому вам нужен дамп ядра или использовать SysInternals livekd. Используйте ключ -y для установки пути символа.

livekd -y srv*d:\debug\symbols*http://msdl.microsoft.com/download/symbols 

После того, как вы находитесь в режиме ядра, найти процесс, который вы хотите отладить

!process 0 0 executable.exe 

Затем получить нити процесса

!process <process> 4 

Все нити, которые имеют Win32Thread не равный 0 являются потенциально интересными.

В блоге Jumping the queues описано остальное для Windows 7. Я не мог сразу последовать, и статья на самом деле не описывает, какие команды WinDbg использовать. Я помню, это было намного проще в Windows XP.

Смежные вопросы