مقدمه

نسخه ۲.۰ از Dependency Walker یه قابلیت جدید به اسم application profiling اضافه کرده. این یعنی می‌تونه یه برنامه در حال اجرا رو زیر نظر بگیره و ببینه چه ماژول‌هایی (modules) رو موقع اجرا لود می‌کنه.
این خیلی خوبه چون بعضی از ماژول‌ها هستن که به صورت دینامیک لود می‌شن و توی جدول import‌ ماژول‌های دیگه مشخص نیستن. با این قابلیت، Dependency Walker می‌تونه اون ماژول‌های پنهون رو هم پیدا کنه.

یه خوبی دیگه‌ی profiling اینه که می‌تونه متوجه بشه اگه یه ماژول نتونه درست initialize بشه (یعنی موقع لود مشکل داشته باشه)، که معمولاً باعث ارور معروفِ “The application failed to initialize properly” می‌شه.

معرفی

وقتی یه ماژول (مثلاً یه فایل exe یا dll) رو توی Dependency Walker باز می‌کنی، بلافاصله شروع می‌کنه به اسکن کردن وابستگی‌هاش؛
چه اونایی که مستقیم هستن (implicit)،
چه اونایی که با تأخیر لود می‌شن (delay-load)،
و چه اونایی که به ماژول دیگه پاس داده شدن (forwarded).
(برای اطلاعات بیشتر راجع‌به این نوع وابستگی‌ها، می‌تونی قسمت Types of Dependencies Handled By Dependency Walker رو بخونی.

وقتی اسکن تموم شد، نتایج رو نشون می‌ده. ولی خب بعضی ماژول‌ها هستن که موقع اجرا (runtime) لود می‌شن بدون اینکه از قبل توی سیستم اعلام شده باشن. به اینا می‌گن dynamic یا explicit dependencies.
این نوع وابستگی‌ها رو نمی‌شه فهمید، مگه اینکه برنامه رو اجرا کنیم و ببینیم واقعاً چه چیزی موقع اجرا لود می‌شه.
دقیقاً همین کاریه که application profiling انجام می‌ده.

پیش‌نیاز

حالا برای اینکه profiling کار کنه، باید ماژولی که باز می‌کنی یه فایل اجرایی باشه (معمولاً .exe) که برای همین سیستم طراحی شده.
اگه این شرط برقرار نباشه، دکمه یا منوی Start Profiling فعال نمی‌شه.
وقتی profiling رو شروع می‌کنی، برنامه اجرا می‌شه و Dependency Walker شروع می‌کنه به ثبت اطلاعات توی بخش Log View و همچنین آپدیت کردن بخش‌های دیگه.

نحوه اجرا

تو به‌عنوان کاربر باید سعی کنی برنامه رو کامل “به کار بندازی” تا همه وابستگی‌های دینامیکش مشخص بشن.
چون معمولاً این وابستگی‌ها فقط وقتی لود می‌شن که واقعاً لازم باشن. مثلاً ماژول‌های مربوط به پرینت فقط وقتی لود می‌شن که برنامه بخواد پرینت بگیره.
اگه توی حین profiling، برنامه هیچ پرینتی نگیره، اون ماژول‌های پرینت اصلاً شناسایی نمی‌شن.
یه سری ماژول هم فقط وقتی لود می‌شن که یه خطا توی برنامه پیش بیاد، که خب باز تولید این شرایط سخت‌تره.

برای همین، هیچ تضمینی نیست که همه‌ی وابستگی‌های دینامیک پیدا بشن، ولی هرچی بیشتر با برنامه کار کنی موقع profiling، احتمال پیدا شدنشون بیشتر می‌شه.

نحوه کار Profiler

در واقع Profiler دنبال همه ماژول‌هایی می‌گرده که لود شدن و سعی می‌کنه بفهمه کدوم ماژول درخواست لود اون یکی رو داده.
با این روش، Dependency Walker می‌تونه ماژول‌هایی که به صورت دینامیک لود شدن رو به‌عنوان “فرزند” اون ماژولی که اون‌ها رو لود کرده، توی Module Dependency Tree View نشون بده.

این profiler با استفاده از hook کردن بعضی تابع‌ها توی پروسه‌ی در حال اجرا کار می‌کنه.
روی ویندوز ۹۵، ۹۸ و Me فقط می‌تونه ماژول‌های غیرسیستمی رو hook کنه.
پس اگه یه ماژول سیستمی یه ماژول دیگه رو لود کنه، profiler نمی‌تونه بفهمه اون از طرف کی لود شده و توی درخت وابستگی، اون ماژول بدون پدر (!) توی ریشه اضافه می‌شه.

ماژول‌هایی که با hook سیستم-wide لود می‌شن هم همینطور؛ اون‌ها هم مستقیم توسط سیستم عامل لود می‌شن و parent ندارن.
با این حال، حتی اگه profiler نتونه parent ماژول رو بفهمه، با این حال تضمین می‌ده که همه‌ی ماژول‌هایی که لود می‌شن، شناسایی بشن.

آخرین مزیت profiler اینه که می‌تونه مسیر (path) واقعی ماژول‌ها رو اصلاح کنه، اگه توی اسکن اولیه مسیر اشتباهی برای ماژولی در نظر گرفته شده باشه.

وقتی یه ماژول رو باز می‌کنی، Dependency Walker از روی جدول import و export، ساختار اولیه‌ی ماژول‌ها رو می‌سازه.
چون توی این جدول‌ها فقط اسم فایل هست، از تنظیمات شما توی Module Search Order Dialog استفاده می‌کنه تا مسیر کامل هر ماژول رو حدس بزنه.

اما توی حین profiling، مسیر واقعی ماژول‌ها رو وقتی که لود می‌شن بررسی می‌کنه و با چیزی که خودش حدس زده مقایسه می‌کنه.
اگه تفاوتی باشه، ساختار درخت و سایر بخش‌ها رو اصلاح می‌کنه تا مسیر درست رو نشون بده.