Dependency Walker. Часто задаваемые вопросы (FAQ)

Steve P. Miller, “Dependency Walker Frequently Asked Questions (FAQ)”, public translation into Russian from English More about this translation.

Translate into another language.

Dependency Walker отображает только некоторые зависимости моего приложения. Почему он не показывает их все?

Когда вы впервые открываете модуль в Dependency Walker, он отображает только скрытой, направленной и отложенной зависимости. Множество зависимостей загружается динамически и не отображается в профиле вашего приложения через Dependency Walker. В дополнение, посмотрите Types of Dependencies Handled в Dependency Walker и Using Application Profiling для Detect Dynamic Dependencies.

Почему когда я просматриваю множество приложений, где MPR.DLL отображается вверху красным под SHLWAPI.DLL, так как пропущена функция WNetRestoreConnectionA? Я также получаю сообщение "Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module" ("Предупреждение: Как минимум один модуль содержит некорректный импорт из-за пропущенной функции, которая должна быть экспортирована в отложенном зависимом модуле")

Некоторые версии SHLWAPI.DLL (подобно версии под ХР) содержат delay-load зависимость по функции WNetRestoreConnectionA в MPR.DLL. Пропуск отложенных функций - не проблема когда вызов DLL происходит до возникновения ситуации. Dependency Walker помечает все потенциальные проблемы, поскольку он не может определить следит ли приложение за результатом. При использовании SHLWAPI.DLL это не проблема, поскольку это не требует WNetRestoreConnectionA для выявления всех хэндлов пропущенной функции в процессе выполнения. Это предупреждение может быть проигнорировано. Просмотрите секцию "How to Interpret Warnings and Errors in Dependency Walker" ("Как интерпретировать Предупреждения в Dependency Walker") в справке, если интересуют подробности.

Почему MSJAVA.DLL отображается желтым (пропущен модуль) и я получаю сообщение "Warning: At least one delay-load dependency module was not found"?

Модуль MSHTML.DLL, который появился в Windows XP SP2 и Windows 2003 SP1 имеет отложенную зависимость в MSJAVA.DLL. Пропущенные отложенные зависимости - не проблема, когда вызывающая DLL готова к управлению пропущенным модулем. Dependency Walker помечает все потенциальные проблемы, поскольку не может определись, следит ли приложение за результатом. В частности, MSJAVA.DLL - необязательный модуь и MSHTML.DLL готов управлять им. Это предупреждение может быть проигнорировано. Просмотрите секцию "How to Interpret Warnings and Errors in Dependency Walker" ("Как интерпретировать Предупреждения в Dependency Walker") в справке, если интересуют подробности.

Dependency Walker указывает на то, что я пропустил APPHELP.DLL. Где я могу его взять?

APPHELP.DLL используемтся Windows XP совместимым приложением. Это Windows XP/2003/Vista/+ только DLL. Если вы видите это предупреждение, то у вас вероятнее всего установлен IE6.0 на компьютере с операционной системой до Windows XP (Windows 95/98/ME/2000). IE6.0 устанавливает новый SHWAPI.DLL который отложенно зависим от APPHELP.DLL. Это нормально, поскольку SHWAPI.DLL на версиях Windows до ХР. Это предупреждение может быть проигнорировано. Вам не нужен APPHELP.DLL на Windows 95/98/ME/2000.

Может ли Dependency Walker помочь мне понять, почему мой компонент не зарегистрирован?

[или] Почему REGSVR32.EXE отказывается регистрировать мою DLL, но Dependency Walker не показывает какой-либо ошибки с моей DLL?

Многие модули должны быть зарегистрированы на компьютере до того, как будут работать. Это распространяется на большинство ActiveX controls, OCXs, COM компонентов, ATL компонентов, компонентов Visual Basic и т.д. Эти типы модулей обычно регистрируюются с помощью REGSVR32.EXE или чего-то похожего. В большинстве случаев, REGSVR32.EXE загружает вашу DLL, вызывает GetProcAddress для DLL DllRegisterServer функции, затем вызывает эту функцию. Обычно допускают ошибку в том, что нужная DLL ссылается на другую DLL, которая пропущена или незарегистрирована. Если вы только что открыли вашу библиотеку в Dependency Walker, вы можете видеть или не видеть проблему в зависимости от вида проблемы с регистрацией.

Лучший способ отладить модуль, у которого проблемы с регистрацией - открыть REGSVR32.EXE в Dependency Walker предпочтительнее, чем вашу DLL. Затем выберите start profiling (F7) ("начать профилирование"). В диалоге профилирования введите полный путь к вашей DLL в поле "Program arguments" ("Аргументы программы"). Для "Starting directory" ("Начальный каталог") вы можете захотеть войти в директорию, содержащую DLL. Проверьте настройки, которые желаете использовать и нажмите Ok. Это запустит REGSVR32.EXE и будет попытка зарегистрировать вашу DLL. Фактически с запущенным REGSVR32.EXE вы можете видеть больше типов ошибок runtime.

Мое приложение запускается лучше когда профилируется Dependency Walker, чем когда я просто запускаю его. Почему?

Я получил несколько отчетов о приложениях которые обвчно падают, но работают нормально, когда профилируются под Dependency Walker. Dependency Walker играет роль отладчика, когда вы профилируете свое приложение. Уже это застявляет программу запускаться по-другому.

Во-первых, надстройка Dependency Walker замедляет исполнение вашего приложения. Если ваше приложение падает из-за скорости, этого замедления может быть достаточно для избежания этой проблемы. Если это так, то проблема в "дизайне" приложения и вам еще везет, что оно не падает.

Во-вторых, обычно, когда потоки блокируются на критических участках, событиях, семафорах, объектах-мьютексах и т.д., они разблокируются по принципу очереди (первый вошел - первый вышел). Это не гарантируется ОС, но обычно так положено делать. Когда приложение запущено через отладчик, очереди иногда созадются случайным образом, поэтому потоки могут блокировать и возмобновлять в разном порядке, чем если бы они были запущены под отладчиком. Это может быть облегчено замедлением или альтернативным способом исполнения, достаточным для того, чтобы заставить вещи работать. И опять, приложению всего лишь везет, если оно не падает

И наконец, приложение, запущенное под отладчиком, автоматически получает отладочную кучу системы. Все функции памяти немного отличаются. Размещения дополнены защитными байтами для того, чтобы проверить, записали ли вы что-либо вне области, которая вам предоставлена (перерасход или недобор буффера). Размещения могут также быть вынуты из памяти тогда, когда они не под отладчиком. Таким образом, если вы пишете прошлый конец буффера под отладчиком, вы можете просмотреть лишние защитные байты, высвобожденную память или только не очень критично. Как бы то ни было, когда запущено не под отладчиком, вы можете упустить что-нибудь критическое (например, указатель) и ваше приложение будет падать

Для кучи отладчика, вы можете отключить это в Dependency Walker и просмотреть, падало ли ваше приложение, когда профилировалось. Если да, то вы, возможно, вызвали переполнение буффера, указатель не на своем месте/плохой/высвобожден и т.д. Для того, чтобы сделать это, вызовите командную строку. Наберите "SET _NO_DEBUG_HEAP=1". Затем запустите из командной строки Dependency Walker. Это отключит отладочную кучу для этого экземляра Dependency Walker. Помните, это работает только на Windows XP и выше.

Как мне отобразить параметр и тип значения, возвращаемого функцией?

Для большинства функций эта информация просто представлена в модуле. Формат файла модуля Windows предоставляет одну строку для определения каждой функции. Это не структурный способ отобразить количество параметров, типы параметров или возвращаемый тип. Как бы то ни было, некоторые языки производят действие, называемое "украшением" или "правкой" функции, и это действие является процессом декодирования информации в текстовую строку. Например, функция, подобная int Foo(int, int), кодируемая простым украшением, может быть экспортирована как _Foo@8. 8 означает число байтов, используемое параметрами. Если используется C++ декорация, то функция будет экспортирована как ?Foo@@YGHHH@Z, котрая может быть напрямую декодирована в оригинальный прототип функции int Foo(int, int). Dependency Walker поддерживает С++ операцию, обратную украшению используя Undecorate C++ Functions Command.

Почему имена моих эспортированных функций отличаются от того, как я объявлял их?

Многие компилляторы "украшают" имена функций по умолчанию. К сожалению, вы даете компиллятору специфические инструкции о том как экспортировать функцию, подобно int Foo(int, int), но вместо этого она в конечно итоге будет экспортирована с использованием украшения _Foo@8, или даже ?Foo@@YGHHH@Z если используется украшение C++. С-подобные языки допускают перегрузку функции, т.е. возможность объявить функции с тем же именем, но разными паарметрами). Из-за этого каждая функция должна иметь уникальную строку сигнатуры с момента экспорта для того, чтобы не вызвать конфликт имен. Для того, чтобы отключить украшение C++, вы можете использовать внешнюю нотацию "С", когда объявляете ваши функции в файле исходного кода С++. Для того, чтобы предотвратить украшение совсем, вы можете добавить DEF файл к вашему проекту С/С++ и объявите действительные имена функций, которые вы хотите экспортировать.

Мое приложение, кажется, запускается достаточно хорошо при профилировании, как бы то ни было я вижу ошибки в окне лога и красные или желтые иконки в других окнах. Это нормально?

Довольно нормально видеть ошибки или предупреждения в течение профилирования. Одна из распространенных ошибок - когда один модуль пытается динамически загрузить другой модуль (используя одну из LoadLibrary функций), но модуль не найден. Dependency Walker выдает сообщение об этой ошибке, но если приложение готово к нем, то это не проблема. Другая распространенная ошибка случается, когда модуль пытается динамически определить функцию (используя GetProcAddress) в модуле. Снова, это не будет проблемой, если приложение к этому готово. Вы можете также увидеть исключения первого рода в окне лога. Если приложение удерживает исключения и они не перерастают в исключения второго рода, то это также не проблема. Как бы то ни было, если приложение, которое вы профилируете, падает или нормально не запускается, то ошибки могут проникнуть в сущность, которая вызывает проблему. Подробности смотрите How to Interpret Warnings and Errors (как интерпретировать ошибки) в секции Dependency Walker

Мое приложение зависит от всех тех файлов? Какие мне нужны для перераспределение моего приложения?

Для систем запуска есть несколько обычных модулей, которые вам не следует перераспределять с вашим приложением, это такие как kernel32.dll, user32.dll, и gdi32.dll. Для того, чтобы увидеть, какие файлы отображены для перераспределения, вы можете поискать файл REDIST.TXT на вашем компьютере для разработки. Этот файл включен в наборы для разработки, подобные Microsoft Visual C++ и Visual Basic. Вы также можете взглянуть на "redistributable files" и "redist.txt" через MSDN для поиска информации о файлах, которые надо перераспределить, о том, как перераспределить их, как проверять версии файлов и т.д. Другой сайт, упоминающий это - Microsoft DLL Help Database (http://support.microsoft.com/dllhelp). На этом сайте есть детальная история DLL и список того, какие продукты шли с какой версией.

Что означает "Shared module not hooked" (распределенный модель не подключен) и почему вызовы DllMain некоторых модулей никогда не отмечаются в логе?

Dependency Walker подключает модули в таком порядке, в котором происходят вызовы их функций подобно DllMain, LoadLibrary, и GetProcAddress. Какой-либо модуль загружался около адреса 0x80000000 (обычные системные модули) в Windows 95/98/Me и не может быть подключен. Результатом явилось то, что Dependency Walker не может отмечать информацию в логе о выховах функций в техмодулях. Windows NT/2000/XP/2003/Vista/+ не имеют таких ограничений. Подробнее смотрите Using Application Profiling to Detect Dynamic Dependencies (использование профилирования приложения для определения динамических зависимостей.

Почему некоторые модули отображают более чем один родительский модуль?

Dependency Walker может отображать более одного модуля для того, чтобы сообщить вам, что есть более одной связи. Это возможно для модуля для отображения косвенно связанной зависимости, будущей зависимости и динамической зависимости, все с единичным родительским модулем. Продробнее смотрите Module Dependency Tree View (Отображение деревом модульной зависимости). В действительности, только одна копия модуля размещается в памяти в течение запуска.

Существует ли консольная версия Dependency Walker?

Dependency Walker может быть запущен как графическое или консольное приложение. Когда задействован консольный режим, Dependency Walker может обрабатывать модуль, сохранять результаты, и выходить без какого-либо графического интерфейса и указаний пользователя. Смотрите подробнее Command Line Options (Настройки командной строки).

Будет ли работать Dependency Walker с COM, Visual Basic или .NET модулей?

Да. Dependency Walker будет работать с каким-либо 32- или 64-хбитным Windows модулем, независимо от того, какой язык был использован для его разработки. Как бы то ни было, многие языки имеют свой собственный способ определения зависимостей между модулями. Например, COM-модули могут иметь встроенные библиотеки типов и информацию о регистрации в реестре, и .NET модули могут использовать .NET сборки. Все эти техники определяются как надстройки над ядром Windows API. В конце этим слоям все еще надо вызвать такие функции Windows ядра, как LoadLibrary и GetProcAddress для совершения существующей работы. На этом уровне ядра Dependency Walker понимает, что происходит. Таким образом, пока Dependency Walker не может понять все специфические уровни сложности вашего приложения, он до сих пор будет способен отслеживать всю модульную активность на уровне ядра Windows API.

Будет ли Dependency Walker работать с 64-битными модулями?

Да. Dependency Walker будет работать с каким-либо 32- или 64-хбитным Windows модулем. Существует 32- и 64-хбитная версия Dependency Walker. Все версии способны открывать 32- и 64-хбитные модули. Как бы то ни было, есть несколько преимуществ при использовании 32-хбитного Dependency Walker для обработки 32-хбитных модулей и 64-хбитного Dependency Walker для обработки 64-хбитных модулей. Это особенно правильно, если запускать на 64-хбитной версии Windows, которая допускает исполнение как 32-хбитных, так и 64-хбитных программ. 32-хбитная подсистема на 64-хбитной Windows (известна как "WOW64") имеет свой собстенный частный реестр, "AppPaths", "KnownDlls", системные папки и манифест обработки. Только 32-хбитная версия Dependency Walker может получить доступ к этому 32-хбитному окружению, которое нужно для того, чтобы аккуратно обработать 32-хбитный модуль. таким же образом, только 64-хбитная версия Dependency Walker может получить полный доступ к 64-хбитному окружению, поэтому она должна всегда использоваться для обработки 64-хбитных модулей.

Почему кнопка меню "Start Profiling" (начать профилирование) недоступна?

Опция профилирования работает в действительности в момент исполнения вашего приложения и наблюдает, что это приложение загружает. В порядке следования, чтобы это было возможно, вам нужно открыть исполняемый файл (обычно имеет EXE расширение), что предпочтительнее, чем DLL. Если вы хотите профилировать DLL, вам нужно открыть нескоторый исполняемый файл, который загружает DLL (смотрите FAQ об использовании REGSVR32.EXE для загрузки DLL). Профилирующая способность также требует, чтобы исполняемый файл, который вы загрузили для той же самой CPU архитектуры, что и версия Dependency Walker, которая в настоящий момент запущена вами. Например, вам нужна 32-хбитная х86 версия Dependency Walker для того, чтобы профилировать 32-хбитный х86 исполняемый файл, и 64-хбитная х64 версия Dependency Walker для того, чтобы профилировать 64-хбитный х64 исполняемый файл.

Будет ли Dependency Walker работать с модулями Windows CE?

Да. Windows CE модули используют тот же самый формат (известен, как "Portable Executable" формат), который используется для модулей, написанных для Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000, Windows XP, Windows 2003, Windows Vista и т.д. Нет версии Dependency Walker, которая действительно запускается на Windows CE, но вы можете открыть Windows CE модули через Windows CE на обычном компьютере с Windows. Как бы то ни было, Dependency Walker автоматически пытается определить зависимые модули, используя путь поиска модулей Windows по умолчанию. Для Windows CE модулей это может вызвать ошибки с того момента, как не-СЕ модули могут быть найдены по пути по умолчанию. Для исправления этого вы можете использовать диалог Dependency Walker "Configure Module Search Order" (настроить порядок поиска модулей) для того, чтобы удалить все стандартные пути и затем добавить вашу собственную частную папку, которая содержит только СЕ модули. Если вы неоднократно делаете это, вы можете сохранить собственный порядок поиска в файл и затем позже вставить этот файл в Dependency Walker искользуя командную строку: "/d:ваш_файл.dwp" (подробнее смотрите Command Line Options - опции командной строки).

Будет ли Dependency Walker работать с 16-битными модулями?

Нет. Dependency Walker поддерживает только 32-хбитные и 64-хбитные модули Windows. Он никогда не поддерживал и не будет поддерживать 16-битные.

Что означают все номера версий?

Посмотрите подробнее Overview of Module Version Numbers (обзор номеров версий модулей).

Могу ли я распечатать результаты сессии?

Нет, но вы можете сохранить результаты в несколько разных текстовых форматов, которые могут быть отображены или распечатаны из просмотрщика текстов (например, Блокнот).

Как я могу кому-нибудь отправить результаты сессии?

Dependency Walker поддерживает несколько способов сохранить результаты данных в сессии. Все окна поддерживают простое копирование из них с использованием команды копирования. Dependency Walker также поддерживает несколько методов сохранения полной сессии в файл. Нет разных текстовых форматов, которые могут быть просто распечатаны или отосланы по электронной почте кому-либо для отображения. Вы также можете сохранить результаты в Dependency Walker Image (DWI) файл, который может быть обнаружен Dependency Walker на другом компьютере для того, чтобы увидеть сохраненные результаты с вашего компьютера. Подробнее по сохранению сессии в файл смотрите Save Command и File Save Dialog (команда сохранения и диалог сохранения в файл).

Что все иконки означают?

Каждое окно в Dependency Walker содержит детальную справку, описывающую, что иконки означают для этого окна. Подробнее смотрите Module Session Window (окно модуля сессий) для списка окон.

Могу ли я искать функцию по имени или номеру?

Все окна в списке в Dependency Walker могут быть отсортированы и по ним можно организовать поиск. Пока вы печатаете какой-либо текст в в столбце, по которому в данный момент список отсортирован. Например, если экспортированный список функций отсортирован по именам функций и вы печатаете "Get", первая функция, которая начинается с "Get", будет подсвечена. Это будет работать для любого столбца в каком-либо списке. Подробнее смотрите соответствующий раздел справки.

Диалог открытия в Dependency Walker не показывает тот файл, который я хочу открыть. Как я могу это исправить?

По умолчанию Windows "прячет" стандартные системные файлы (подобно DLL) от пользователя. Для того, чтобы изменить это, откройте "Мой компьютер" и выберите "Опции" из меню. В зависимости от версии Windows, которую вы используете, этот пункт может находиться в меню "Вид" или "Инструменты" и может называться "Свойства папки" или просто "Опции". В диалоговом окне, которое появляется, выберите панель "Вид". Вы должны увидеть опцию, которая звучит "Показать все файлы" или "Показать спрятанные файлы и папки". Убедитесь, что эта опция включена. Вы также увидите флажок, который звучит так: "Hide MS-DOS file extensions for file types that are registered" (Спрятать расширения MS-DOS файлов для незарегистрированных типов файлов). Вы захотите снять этот флажок. Как только это сделано, жмите "Ok" в этом диалоговом окне. Dependency Walker сейчас должен отобразить все системные файлы в своем диалоге открытия.

Как я могу удалить Dependency Walker?

Dependency Walker не имеет программы установки или удаления. Он разработан для того, чтобы вы могли по желанию просто запустить его и удалить, если он вам больше не нужен. Если вы сказали Dependency Walker удерживать некоторые расширения файлов, возможно, вы хотите удалить эти ассоциации с файлами до удаления программы. Это может быть сделано с использованием команды Handled File Extensions. Файлы для удаления, когда Dependency Walker больше не нужен - depends.exe, depends.dll и depends.chm.

Почему некоторые модули ищут функцию с именем "IsTNT" в KERNEL32.DLL?

TNT - 32-хбитная надстройка эмуляции, написанная Phar Lap. Некоторые модули, которые до сих пор используются и которые являются частями кода, который проверяет, если они запущены на TNT вызовом GetProcAddress("IsTNT") для KERNEL32.DLL. Это предупреждение может быть проигнорировано.

Почему некоторые модули пытаются загрузить модуль с именем "AUX"?

Это обычно относится к тем модулям, которые пытаются загрузить аудио-драйвер AUX. С тех пор, как AUX - зарезервированное DOS-имя, загрузка падает. Это предупреждение безобидно и может быть проигнорировано.

MFC42.DLL пытается загрузить MFC42LOC.DLL, но он не находится

[или] COMCTL32.DLL пытается загрузить CMCTLENU.DLL, Но он не находится. Что это?

И MFC42LOC.DLL, и CMCTLENU.DLL - специфические библиотеки ресурсов языка, которые могут быть не нужны на вашей системе. Многие модули на Windows хранят все специфические сообщения своих языков во внешних DLL (одна на язык). При запуске, модуль загружает DLL для текущего языка ОС. Имена модулей обычно оканчиваются на "ENU" для английского США, "ESP" для испанского, "JPN" для японского и т.д. Окончание "LOC" означает, что MFC использует стандарты для "localized". Когда MFC установлена, она копирует правильную языковую DLL на вашу систему и переименовывает ее в MFC42LOC.DLL. Таким образом, почему пропущен модуль? Хорошо, большинство модулей защищаются от падения сохранением одного языка по умолчанию в собственной главной DLL. Если специфическая библиотека ресурсов языка падает при загрузке, то затем модуль по умолчанию использует для себя локальные ресурсы. В большинстве случаев, эти ресурсы по умолчанию - те же ресурсы, что и в ENU версии DLL ресурсов. По этой причине, нет нужды ENU версии DLL ресурсов, и таким образом она не может найти одну при запуске. Это нормально.

Original (English): Dependency Walker Frequently Asked Questions (FAQ)

Translation: © Gargo .

translated.by crowd

Like this translation? Share it or bookmark!