Сообщения об ошибках — неизменные спутники жизни пользователей. Как правило, алгоритм обработки такого сообщения прост: прежде всего нужно выяснить, откуда поступило сообщение, а затем уже определять, почему произошла упомянутая в нем ошибка. Но иногда ответить на вопрос о том, откуда взялась ошибка — из диалогового окна с сообщением или из записи в журнале, такой как запись об ошибке в журнале событий, бывает очень непросто. С подобными ситуациями чаще всего сталкиваются системные администраторы, когда обнаруживают ошибки на серверах, функционирующих без вмешательства оператора, и видят, что с момента регистрации ошибки прошло несколько часов, а то и дней. В предлагаемой читателям статье я расскажу о двух инструментах от Windows Sysinternals, которые могут помочь вам в поисках подобных ошибок.

Мы подробно разберем два примера: диалоговое окно с сообщением и запись в журнале событий.

Диалоговые окна сообщений

В нашем первом примере задача состоит в том, чтобы обнаружить владельца диалогового окна с сообщением об ошибке. Здесь мы можем воспользоваться программой Process Explorer, в которой реализован инструмент, позволяющий обнаруживать процесс Windows. На панели инструментов Process Explorer это средство представлено значком «перекрестие».

Чтобы воспользоваться данным инструментом, щелкните на значке левой кнопкой мыши и, удерживая кнопку нажатой, отбуксируйте «перекрестие» на диалоговое сообщение (экран 1а), после чего отпустите кнопку мыши.

Анализ диалогового окна сообщения с помощью средства Find Windows process

При этом процесс, который является владельцем ошибки, будет подсвечен, как показано на экране 1b. Здесь мы рассмотрим очень простой пример: ошибка при попытке открыть несуществующий файл в редакторе Notepad. В данном случае понятно, откуда поступило сообщение об ошибке и почему оно было сгенерировано. Но если бы это диалоговое окно появилось внезапно от имени, скажем, одной из системных служб, мы не смогли бы судить о его источнике на основании текста сообщения.

Более того, во многих случаях пользователь может применять Process Explorer для исследования стека потоков данного экземпляра процесса, с тем чтобы прояснить происхождение сообщения об ошибке, как показано на экране 2.

Просмотр стека вызовов процесса, который отобразил диалоговое окно сообщения

В стеке вызовов потоков могут присутствовать и имена других функций, содержащие полезную для пользователя информацию.

Сообщение об ошибке в журнале регистрации событий

На этот раз мы будем искать программные файлы по произвольной строке, взятой из записи журнала событий. Задачу можно решить весьма примитивным способом с помощью программы Sysinternals strings.exe, но давайте применим один-два специальных приема для оптимизации поиска. В конце концов, поиск во всех файлах на системном накопителе отнимает много времени и связан с использованием большого объема ресурсов, без которых вполне можно обойтись.

В целях оптимизации поиска мы выполним несколько задач с помощью пакетных файлов, показанных на экранах 3a и 3b. Описание синтаксиса пакетных файлов остается за рамками данной статьи, поэтому я ограничусь короткими замечаниями по каждой строке и ее функции.

Представленный на экране 3a файл binstr.bat — это пакетный файл cmd.exe, принимающий два аргумента. Первый аргумент — имя каталога, а второй — искомая строка.

Файл Binstr.bat перечисляет все файлы с расширениями .exe и .dll, расположенные в данном каталоге и во вложенных папках

В файле используется цикл for, обеспечивающий отбор в данном каталоге и его вложенных папках только файлов .exe и .dll. Каждое из имен этих файлов, равно как и критерий поиска — строковое сообщение, данный файл передает второму пакетному файлу.

Файл binstr_func.bat (экран 3b) можно рассматривать как подпрограмму основного пакетного файла.

Файл binstr_func.bat — подпрограмма, вызывает программу strings.exe, применяет фильтр к ее выходным данным и регистрирует результаты в файле

Данный код нужно размещать в отдельном файле из-за ограничений на пакеты в синтаксисе команд. Подпрограмма принимает два аргумента: имя файла, а также искомую строку. Затем файл выполняет три задачи. Во‑первых, он выводит имя файла на консоль, с тем чтобы известить пользователя о ходе выполнения пакетного файла. Во‑вторых, он регистрирует имя файла в текстовом файле binstr_output.txt. Наконец, он вызывает программу strings.exe с применением двух упомянутых параметров и применяет к полученным результатам фильтр find.exe. Выходные данные поступают в текстовый файл.

Давайте на конкретном примере рассмотрим, как используется пакетный файл и каковы его выходные данные. Возьмем запись журнала событий, представленную на экране 4, об источнике которой мы уже имеем представление, ибо он указан в самом сообщении.

Пример записи в журнале событий Application

Мы можем воспользоваться упомянутой записью, дабы убедиться в том, что действительно нашли корректное сообщение с помощью файлов binstr.bat и binstr_output.txt, как показано на экранах 5 и 6.

Работа с файлом binstr.bat

 

Файл binstr_output.txt

Ошибки без покрова тайны

Сообщения об ошибках порой могут быть весьма туманными, а их источники окутаны тайной. Два приема, описанные в данной статье, — отнюдь не единственные варианты отслеживания источников таинственных сообщений об ошибках. Но они, надеюсь, дадут вам некоторое представление о методах, а также об инструментах, которые помогут в анализе первопричин ошибок.

Майкл Моралес (morales@microsoft.com) — старший инженер службы поддержки Microsoft Global Escalation Services. Специализируется на проблемах отладки и производительности Windows  

Программа Find Windows process указывает владельца диалогового окна