حين يتعطّل تطبيق التحكّم بكاميرا صناعيّة فجأةً بعد شهر (الجزء الثاني) - ما هو Application Verifier وكيف نبني بنية اختبار لمسارات الفشل

· · تطوير Windows, تصحيح الأخطاء, الكاميرا الصناعيّة, Application Verifier, اختبار مسارات الفشل, handle leak

Application Verifier أداة قويّة جدّاً عندما تريد إظهار السلوك الغريب حول كود Windows الأصليّ أو حدود Win32 في وقت أبكر ممّا يفعله الاختبار العاديّ. هي مفيدة بشكل خاصّ عندما تريد اختبار أمور مثل سوء استخدام handle، وتلف heap، ومسارات الفشل في ظروف الموارد المنخفضة.

في الجزء الأوّل، حين يتعطّل تطبيق التحكّم بكاميرا صناعيّة فجأةً بعد شهر (الجزء الأوّل) - كيفيّة العثور على handle leak وتصميم السجلّات للتشغيل طويل الأمد، نظّمت حالة تبيّن فيها أنّ السبب الجذريّ لتعطّل التشغيل طويل الأمد هو handle leak. لكنّ تعزيز السجلّات وحده ليس سوى نصف القصّة. ما تريده فعلاً هو أن تعرف، مسبقاً، ما إذا كان خطأ مستقبليّ يسبّب تسريب ذاكرة، أو handle leak، أو فشلاً جزئيّاً، أو إغفال تنظيف، فستظلّ قادراً على رؤية ما حدث بوضوح.

هنا يأتي دور Application Verifier. يمكنه تطبيق فحوصات في وقت التشغيل وحقن أعطال على سلوك Windows الأصليّ / حدود Win32. سمة مفيدة بشكل خاصّ في المشاريع الواقعيّة هي أنّه يسمح لك بتشغيل مسارات فشل تشبه نقص الذاكرة أو نقص الموارد دون استنزاف الجهاز بأكمله فعليّاً.

ينظّم هذا الجزء الثاني ما هو Application Verifier، وما يمكنه فعله، وكيفيّة استخدامه لبناء بنية اختبار عمليّة لمسارات الفشل في سياق تطبيق التحكّم بكاميرا صناعيّة.

المحتويات

  1. النسخة المختصرة
  2. ما هو Application Verifier
  3. ماذا يستطيع Application Verifier أن يفعل
  4. لماذا أدخلناه في هذه الحالة
  5. كيفيّة تشغيل سلوك يشبه نقص الذاكرة أو الموارد
  6. كيفيّة فحص المشكلات المتعلّقة بـ handle
  7. كيفيّة بناء بنية اختبار مسارات الفشل
  8. دليل قواعد عامّة تقريبيّة
  9. الخلاصة
  10. المراجع

1. النسخة المختصرة

  • Application Verifier أداة تجعل من الأسهل التقاط سوء الاستخدام حول حدود native / unmanaged / Win32 في وقت التشغيل
  • قيمته ليست فقط “العثور على الأخطاء”، بل أيضاً إجبار مسارات الفشل التي تبقى عادةً مخفيّة على الظهور
  • يمكن لـ Handles التقاط استخدام handle غير صالح، ويمكن لـ Heaps المساعدة في إظهار تلف heap، ويمكن لـ Low Resource Simulation حقن أعطال تشبه نقص الذاكرة أو نقص الموارد
  • ليس من المثاليّ الاعتماد على Application Verifier وحده لتحليل تسرّبات EXE طويل العمر؛ دمجه مع مراقبتك الخاصّة لـ Handle Count وسجلّات دورة حياة الموارد أكثر عمليّةً بكثير
  • في بنية اختبار مسارات الفشل، من الأسهل بكثير قراءة النتائج إذا قمت بتشغيل runs الـ verifier العاديّة وruns حقن الأعطال بشكل منفصل
  • حتّى عندما يكون الشيء الذي تريد اختباره هو DLL، فإنّ الهدف الذي تُمكّنه في Application Verifier عادةً هو EXE الاختبار الذي يحمّله فعلاً

باختصار، Application Verifier أداة لجرّ أخطاء native / Win32 المزعجة التي تبقى لولا ذلك نصف مخفيّة. في عالم تختلط فيه برامج التحكّم بالأجهزة مع SDKs أصليّة وP/Invoke وWin32 APIs، يكون مناسباً بشكل خاصّ.

2. ما هو Application Verifier

2.1. الوصف بجملة واحدة

Application Verifier هو أداة تحقّق في وقت التشغيل لتطبيقات user-mode في Windows. يلاحظ كيف يستخدم التطبيق OS APIs والموارد أثناء تشغيله فعليّاً، ويمكنه كلّ من اكتشاف السلوك المشبوه وحقن حالات الفشل عمداً.

على عكس التحليل الساكن أو اختبارات الوحدة العاديّة، يُظهر ما يحدث على مسار التنفيذ الفعليّ. ولهذا بالضبط هو مفيد جدّاً لاختبار مسارات الفشل.

flowchart LR
    A[Test harness] --> B[Control application / SDK wrapper]
    B --> C[Application Verifier]
    C --> D[Win32 APIs / native DLLs / OS resources]
    C --> E[verifier stop]
    C --> F[debugger output]
    C --> G[AppVerifier logs]
    B --> H[structured application log]

2.2. أين يكون فعّالاً

يكون فعّالاً بشكل خاصّ في حالات مثل هذه:

  • يستدعي التطبيق native DLLs أو SDKs للأجهزة
  • يعبر حدود P/Invoke أو COM
  • يستخدم handles أو heaps أو locks أو ذاكرة افتراضيّة بكثرة، مباشرةً أو غير مباشرة
  • نادراً ما تفشل اختبارات المسار الطبيعيّ، لكن معالجة دورة حياة مسار الفشل تبدو مشبوهة
  • العَرَض الأوّل المرئيّ ليس تعطّلاً، بل حالات فشل غريبة عرضيّة

من ناحية أخرى، Application Verifier ليس الأداة الرئيسيّة الصحيحة لمطاردة تسرّبات object-graph المُدارة الخالصة. لذا حتّى في تطبيق C#، يصبح أكثر قيمةً بكثير عندما تكون SDKs الأصليّة أو حدود Win32 جوهريّةً.

2.3. لماذا هو مفيد عمليّاً

الفوائد العمليّة هي بشكل رئيسيّ هذه:

  1. يمكنه إيقاف سوء استخدام الحدود الأصليّة في وقت أبكر
    • invalid handle
    • heap corruption
    • lock misuse
    • سوء استخدام API الذاكرة الافتراضيّة
  2. يمكنه إجبار مسارات الفشل التي يصعب عادةً تشغيلها
    • حالات فشل تشبه التخصيص
    • حالات فشل إنشاء ملف / حدث
    • سلوك الموارد المنخفضة دون انهيار الجهاز بأكمله فعليّاً
  3. يعمل بشكل جيّد مع أدوات التصحيح
    • !avrf
    • !htrace
    • !heap -p -a
    • معلومات verifier stop

في تطبيقات التحكّم بالأجهزة، فإنّ الجزء الأصعب غالباً ليس “هناك خطأ”. الجزء الأصعب هو “لا نستطيع رؤية ما حدث بوضوح عند تشغيل المسار غير الطبيعيّ”. يساعد Application Verifier كثيراً في ذلك.

3. ماذا يستطيع Application Verifier أن يفعل

3.1. الأساسيّات: Handles / Heaps / Locks / Memory / TLS وما إلى ذلك

مجموعة الاختبار الأساسيّة في Application Verifier هي عادةً منطقة Basics. تتضمّن أنواع الفحوصات التي تريدها فعلاً في كثير من تطبيقات الحدود الأصليّة.

الطبقة ما يفحصه كيف يساعد في هذا السياق
Handles استخدام handle غير صالح يلتقط مسارات use-after-close ومسارات handle السيّئ
Heaps تلف heap يساعد في إظهار التلف أو use-after-free بالقرب من حدود SDK الأصليّة
Leak الموارد غير المحرّرة عند unload لـ DLL مفيد بشكل خاصّ في سيناريوهات harness قصيرة العمر
Locks / SRWLock سوء استخدام lock مفيد حول سباقات إعادة الاتّصال والإيقاف
Memory سوء استخدام APIs مثل VirtualAlloc مفيد للـ buffers الكبيرة أو سلوك الذاكرة المُعيَّنة
TLS سوء استخدام التخزين المحلّيّ للـ thread مفيد في الكود الأصليّ بافتراضات thread معقّدة
Threadpool صحّة worker threadpool وAPI مفيد عند تضمين callbacks وعمل غير متزامن أصليّ

القوّة الأساسيّة هنا ليست “قراءة تعطّل بعد وقوعه”. القوّة هي أنّ الاستخدام المشبوه يمكن أن يتوقّف أقرب إلى المكان الذي يحدث فيه فعلاً.

3.2. Low Resource Simulation: إظهار فشل الذاكرة والموارد في وقت أبكر

هذا أحد الأجزاء الأكثر فائدةً عمليّاً. يمكنك تشغيل سلوك يبدو كنقص في الذاكرة أو نقص في الموارد دون استنزاف جهاز التطوير بأكمله فعلاً.

الفكرة الأساسيّة هي حقن الأعطال:

  • اختر بعض APIs لإنشاء الموارد أو التخصيص
  • أجبرها على الفشل باحتماليّة مختارة

هذا يجعل من الأسهل بكثير اختبار مسارات الخطأ التي لولا ذلك لن تعمل تقريباً أبداً.

تشمل الأمثلة النموذجيّة:

  • HeapAlloc
  • VirtualAlloc
  • CreateFile
  • CreateEvent
  • MapViewOfFile
  • تخصيصات OLE / COM مثل SysAllocString

3.3. Page Heap وأداة التصحيح

إذا كان الاشتباه هو تلف heap، فإنّ Heaps بالإضافة إلى page heap يكون قويّاً بشكل خاصّ. يمكن لـ full page heap أن يجعل التلف يتوقّف أقرب بكثير إلى لحظة حدوثه، بفضل سلوك guard-page.

لكنّه ثقيل أيضاً. لذلك يكون عادةً أفضل للاستخدام في:

  • إعادة إنتاج مركّزة
  • سيناريوهات مرفقة بأداة التصحيح
  • تحقيق ضيّق بمجرّد أن يصبح الاشتباه موضعيّاً بالفعل

التقدّم العمليّ غالباً هو:

  1. استخدم Basics على نطاق واسع أوّلاً
  2. إذا أصبح تلف heap محتملاً، انتقل إلى full page heap
  3. إذا كان ذلك ثقيلاً جدّاً، خفّف
  4. اجعل runs طويلة الأمد تشبه الإنتاج تركّز أكثر على counters وسجلّاتك الخاصّة

3.4. !avrf / !htrace / السجلّات

Application Verifier لا يتوقّف عند “حدث verifier stop”. امتدادات أداة التصحيح والسجلّات تجعل من الأسهل بكثير فهم ما حدث.

  • !avrf
    • فحص تكوين verifier الحاليّ وحالة verifier-stop
  • !htrace
    • فحص سجلّ فتح / إغلاق / سوء استخدام handle
  • !heap -p -a
    • فحص كتل heap عند تضمين page heap
  • سجلّات AppVerifier
    • الاحتفاظ بمعلومات الإيقاف

عند تمكين Handles، يصبح تتبّع handle مفيداً بشكل خاصّ لأنّه يصبح من الأسهل بكثير السؤال:

أين فُتح هذا الـ handle، وأين أُغلق؟

4. لماذا أدخلناه في هذه الحالة

4.1. لم يكن الهدف فقط “العثور على خطأ واحد”

لم يكن الهدف في هذه الحالة مجرّد:

“العثور على خطأ واحد بالضبط باستخدام AppVerifier”

كان الهدف الأعمق هو التأكّد من أمور مثل:

  • إذا تسرّب مسار فشل مستقبليّ آخر ذاكرة أو handle، هل يمكننا أن نفهم ما حدث؟
  • هل يمكننا متابعته بالكامل من خلال معلومات أداة التصحيح؟
  • هل يمكننا تجنّب الانتهاء في حالة “شيء ما فشل، لكنّنا لا نعرف لماذا”؟

لذا استُخدم Application Verifier ليس فقط كـ كاشف، بل أيضاً كطريقة لـ اختبار بنية المراقبة نفسها.

4.2. تشغيل ظروف تشبه نقص الذاكرة

استنزاف الذاكرة فعلاً على جهاز التطوير أمر مزعج. وبمجرّد أن يصبح الجهاز بأكمله غير مستقرّ، يمتلئ الاختبار نفسه بالضوضاء.

لذا بدلاً من ذلك، استُخدم Low Resource Simulation للوطء عمداً على أنواع مسارات الفشل التي ستحدث في ظلّ نقص الذاكرة أو الموارد.

هذا يجعل أسئلةً مثل هذه أسهل بكثير في الإجابة:

  • إذا فشل CreateEvent، هل تحفظ السجلّات cameraId وphase؟
  • بعد فشل تهيئة جزئيّ، هل يستمرّ التنظيف في العمل؟
  • إذا فشل VirtualAlloc، هل يتصرّف مسار إعادة المحاولة بشكل صحيح؟
  • إذا فشل CreateFile على مسار حفظ، هل يعود عدد handle؟

النقطة هنا ليست مجرّد “اجعل التطبيق يفشل”. النقطة هي:

هل لا يزال بإمكاننا شرح طريقة فشله؟

4.3. التأكّد من أنّ مشكلات handle قابلة للتتبّع فعلاً

كما نوقش في الجزء الأوّل، فإنّ مشكلات handle غالباً ما يكون لها فجوة كبيرة بين المكان الذي يموت فيه التطبيق أخيراً والمكان الذي حدث فيه التسريب الأصليّ.

لذلك أردنا تحديداً التأكّد من:

  • عند ظهور invalid-handle stop، هل يمكن لـ !htrace متابعة سجلّ الفتح / الإغلاق؟
  • هل يمكن ربط هذا السجلّ بسجلّاتنا الخاصّة لـ resourceId / sessionId / phase؟
  • بعد سيناريوهات الأعطال، هل يعود Handle Count؟
  • عندما يستخدم harness عمليّةً قصيرة العمر، هل تصبح التسرّبات أسهل في المقارنة؟

هكذا تنتقل المناقشة من:

“حدث خطأ”

إلى:

“كُسر عقد دورة الحياة في هذه المسؤوليّة المحدّدة”

5. كيفيّة تشغيل سلوك يشبه نقص الذاكرة أو الموارد

5.1. الفكرة الأساسيّة لـ Low Resource Simulation

Low Resource Simulation هو أساساً حقن أعطال. لا يحاول إعادة إنشاء جهاز فعلاً منخفض الموارد بشكل مثاليّ. بدلاً من ذلك، يقدّم عمداً حالات فشل API تمثيليّة تميل إلى الحدوث في ظروف الموارد المنخفضة.

هذا يجعله مفيداً بشكل خاصّ لـ:

  • فحص التنظيف في مسارات الفشل
  • فحص متانة إعادة المحاولة / إعادة الاتّصال
  • فحص التهيئة الناجحة جزئيّاً / الفاشلة جزئيّاً
  • فحص ما إذا كانت حالات الفشل النادرة لا تزال تترك أدلّةً كافيةً في السجلّات

قاعدة عمليّة مهمّة:

لا تشغّل كلّ شيء دفعةً واحدة

إذا قمت بتمكين كلّ نوع من الفشل من البداية، فإنّ السجلّات تنفجر ويصبح من الصعب معرفة ما تنظر إليه فعلاً.

5.2. ما أنواع حالات الفشل التي يمكن حقنها

تشمل الأهداف النموذجيّة أموراً مثل هذه:

النوع المثال المثال في تطبيق التحكّم بالأجهزة
Heap_Alloc تخصيص heap buffers مؤقّتة، buffers metadata، تخصيصات SDK wrapper
Virtual_Alloc تخصيص ذاكرة افتراضيّة frame buffers، ring buffers
File CreateFile والعمليّات ذات الصلة فتح مسار الحفظ، فتح ملفّ السجلّ
Event CreateEvent والعمليّات ذات الصلة إشعارات frame-ready، مزامنة الإيقاف / إعادة الاتّصال
MapView APIs تعيين الذاكرة الذاكرة المشتركة، الملفّات المعيّنة
Ole_Alloc SysAllocString وما شابه حدود COM / OLE
Wait عائلة WaitForXXX فحص معالجة فشل مسار الانتظار
Registry APIs السجلّ إعدادات التكوين والمجاورة للمشغّلات

عمليّاً، يكون أكثر فاعليّةً بكثير تمكين أنواع الفشل القريبة من مسار الفشل المحدّد الذي تهتمّ به بدلاً من تشغيل كلّ شيء دفعةً واحدة.

5.3. كيفيّة توجيهه عمليّاً

يمكن أن يبدو شكل سطر الأوامر تقريباً هكذا:

appverif /verify CameraHarness.exe
appverif /verify CameraHarness.exe /faults
appverif -enable lowres -for CameraHarness.exe -with heap_alloc=20000 virtual_alloc=20000 file=20000 event=20000
appverif -query lowres -for CameraHarness.exe

التسلسل العمليّ عادةً هو:

  1. شغّل المسار الطبيعيّ مع Basics فقط
  2. ثمّ أضف Low Resource Simulation
  3. إذا لزم الأمر، ركّز على أنواع الفشل التي تهتمّ بها فقط، مثل file أو event
  4. إذا لزم الأمر، وجّهه بشكل أضيق نحو DLLs محدّدة

اختصار /faults ملائم، لكنّه يركّز في الغالب على OLE_ALLOC وHEAP_ALLOC. إذا كنت تريد اختبار مسارات فشل CreateFile أو CreateEvent تحديداً، فمن الأوضح بكثير كتابة file=... أو event=... بشكل صريح.

في تطبيقات التحكّم بالأجهزة، غالباً ما يكون من الأسهل بكثير فهم النتيجة إذا وجّهت حقن الأعطال بشكل أضيق نحو camera wrapper أو الكود المتعلّق بمسار الحفظ بدلاً من نشره عبر العمليّة بأكملها.

6. كيفيّة فحص المشكلات المتعلّقة بـ handle

6.1. فحص Handles

بالنسبة للكود الكثير الاستخدام لـ handle، فإنّ أوّل ما يُستخدم هو Handles. هذا يجعل اكتشاف استخدام handle غير الصالح أسهل بكثير.

تشمل الحالات النموذجيّة:

  • استخدام handle بعد إغلاقه
  • تمرير قيمة handle مكسورة
  • استخدام handle غير مهيّأ بعد فشل جزئيّ
  • تجاوز دورة الحياة واستخدام thread آخر لـ handle بشكل غير صحيح

في البرامج طويلة الأمد، قد تظهر هذه فقط على شكل “أحياناً يحدث فشل غريب”. تحت verifier، غالباً ما تتوقّف أقرب بكثير إلى سوء الاستخدام نفسه.

6.2. استخدام !htrace لفحص stacks الفتح / الإغلاق

أحد أسباب قيمة Handles العالية هو مدى نجاحه مع تتبّع handle.

windbg -xd av -xd ch -xd sov CameraHarness.exe
!avrf
!htrace 0x00000ABC

ما تريد عادةً معرفته من !htrace هو:

  • أين فُتح handle
  • أين أُغلق
  • ما إذا كان قد أُشير إليه كـ handle غير صالح
  • ما إذا كانت حالات الفتح تتراكم أكثر من المتوقّع

يصعب التعامل مع handle leaks وسوء استخدام handle بدقّة لأنّ API الفاشل النهائيّ غالباً ليس المكان الذي بدأ فيه الخطأ. يجعل !htrace سجلّ دورة الحياة أكثر تجسيداً بكثير.

6.3. كيفيّة دمجه مع سجلّاتك الخاصّة

ومع ذلك، فإنّ Application Verifier وحده لا يكفي. بالنسبة لتحليل تسرّبات EXE طويل العمر، فإنّ الاعتماد عليه وحده لا يزال مؤلماً جدّاً.

عمليّاً، يعمل بشكل أفضل عند دمجه مع:

  • Handle Count دوريّ
  • sessionId
  • resourceId
  • phase
  • سجلّات دورة الحياة لـ create/open وclose/dispose
  • dumps ومخرجات أداة التصحيح عند توقّف verifier

ثمّ يصبح النمط:

  1. يكشف تسجيل heartbeat عن ميل مشبوه لـ Handle Count
  2. تضيّق سجلّات دورة الحياة الموارد التي أُنشئت دون إغلاق مطابق
  3. تظهر runs الـ verifier استخدام handle غير الصالح أو سوء الاستخدام في وقت أبكر
  4. يكشف !htrace عن stacks الفتح / الإغلاق

هذه الرؤية المجمّعة أقوى بكثير من أيّ من تلك الأدوات وحدها.

7. كيفيّة بناء بنية اختبار مسارات الفشل

7.1. ادفع التنفيذ إلى harness EXE

لا يمكن تشغيل Application Verifier بعد أن تكون العمليّة قد بدأت بالفعل. تكوّن أوّلاً، ثمّ تشغّل.

أيضاً، تظلّ إعداداته حتّى تمسحها بشكل صريح. لذلك عمليّاً، يكون عادةً من الأسهل استهداف EXE harness اختباريّ بدلاً من تطبيق الإنتاج الحقيقيّ نفسه.

يبدو الشكل الشائع هكذا:

Scenario RunnerCameraHarness.exeCameraSdkWrapper.dllVendor SDKStructured LogDump / Debugger

هذا يعطيك:

  • عمليّة واحدة لكلّ سيناريو
  • مقارنة تسريب أسهل
  • تحكّم سهل في تشغيل / إيقاف إعدادات AppVerifier
  • مكان طبيعيّ لاختبار سلوك DLL من خلال EXE الذي يحمّله فعلاً

أشكال الأوامر النموذجيّة هي:

appverif /verify CameraHarness.exe
appverif /n CameraHarness.exe

القاعدة المهمّة هي:

  • مكّن قبل التشغيل
  • عطّل بشكل صريح عند الانتهاء

التنفيذ بنهج harness-first يقلّل الكثير من الالتباس في التكوين.

7.2. قسّم قائمة الاختبار حسب الغرض

في بنية اختبار مسارات الفشل، يكون من الأوضح عادةً عدم تشغيل كلّ شيء معاً. ثلاث مجموعات هي تقسيم عمليّ جدّاً:

  1. المسار الطبيعيّ + Basics
    • لا حقن أعطال
    • فقط تأكّد من أنّ verifier stops لا تحدث في التشغيل العاديّ
  2. runs حقن الأعطال
    • استخدم Low Resource Simulation
    • استهدف event وfile وheap_alloc وvirtual_alloc وأنواع فشل مماثلة
  3. runs غوص heap عميق
    • Heaps
    • full page heap
    • إعادة إنتاج مركّزة مرفقة بأداة التصحيح

هذا يحافظ على فصل:

  • “إنّه مكسور حتّى في الاستخدام العاديّ”
  • و”يكسر فقط في ظلّ ظروف الموارد المنخفضة المحقونة”

عن أن يصبحا مختلطين.

7.3. ما الذي تجمعه

كحدّ أدنى، هذه تستحقّ الجمع:

النوع ما يجب جمعه
سجلّات التطبيق cameraId، sessionId، phase، handleCount، error code
حالة العمليّة Handle Count، Private Bytes، Thread Count
معلومات أداة التصحيح !avrf، !htrace، وإذا لزم الأمر !heap -p -a
dump عند verifier stop أو الإنهاء غير الطبيعيّ
سجلّات AppVerifier سجلّات الإيقاف، اختياريّاً مُصدَّرة بصيغة XML

إذا احتجت إلى ذلك، يمكن أيضاً تصدير سجلّات AppVerifier وتجميعها بصيغة XML. لكن في معظم المشاريع العمليّة لا تزال تكون أكثر منطقيّةً عند قراءتها جنباً إلى جنب مع سجلّاتك الخاصّة.

الشيء المهمّ ليس “الكثير من السجلّات”. الشيء المهمّ هو:

هل يمكننا إعادة بناء سلسلة السببيّة لاحقاً؟

7.4. ما ينبغي أن تكون عليه معايير القبول

“لم يتعطّل” ليس كافياً كشرط قبول. على الأقلّ، احتيج إلى هذه في هذا السياق:

  • لا verifier stop خلال runs المسار الطبيعيّ + Basics
  • في runs حقن الأعطال، يكون الفشل المقصود مرئيّاً في السجلّات
  • يتمّ تنظيف الموارد المهيّأة جزئيّاً بشكل صحيح
  • يعود Handle Count بالقرب من baseline بعد إعادة الاتّصال / إعادة المحاولة
  • إذا حدث verifier stop، يمكن تتبّعه من خلال sessionId وphase ومعلومات stack
  • لا يتدهور الفشل أبداً إلى “لا نعرف ما حدث”

من المهمّ تقييم كلّ من:

  • ما إذا كان التطبيق يبقى على قيد الحياة
  • وما إذا كان الفشل يبقى قابلاً للشرح

7.5. أمور يجب مراعاتها

Application Verifier قويّ جدّاً، لكنّه ليس سحراً.

  • يفحص فقط المسارات التي تنفّذها فعلاً
  • full page heap ثقيل
  • قد تحدث verifier stops داخل SDKs الطرف الثالث أيضاً
  • يمكن أن تأخذ runs حقن الأعطال والمسار الطبيعيّ مسارات كود مختلفةً جدّاً
  • ليس الأداة الرئيسيّة لتسرّبات heap المُدارة الخالصة

لذا فإنّ تقسيم العمل عادةً هو:

  • اتّجاهات النموّ طويلة الأمد ← counters وسجلّاتك الخاصّة
  • سوء استخدام الحدود الأصليّة ← Application Verifier
  • إعادة بناء سلسلة السببيّة ← السجلّات المنظّمة + dump + أداة التصحيح

هذا التقسيم أكثر عمليّةً بكثير في العمل الواقعيّ من الأمل في أن تشرح أداة واحدة كلّ شيء.

8. دليل قواعد عامّة تقريبيّة

  • اشتباه في handle غير صالح أو إغلاق مزدوج
    • ابدأ بـ Handles + !htrace
  • اشتباه في heap corruption / use-after-free
    • انتقل إلى Heaps + full page heap + !heap -p -a
  • تريد تشغيل سلوك يشبه نقص الذاكرة أو نقص الموارد
    • استخدم Low Resource Simulation
  • عمليّة طويلة الأمد تتدهور ببطء
    • ابدأ أوّلاً بـ Handle Count / Private Bytes / سجلّات دورة الحياة الخاصّة بك
  • تريد اختبار DLL
    • مكّن Application Verifier لـ harness EXE الذي يحمّله فعلاً

إذا قمت بتمكين كلّ شيء دفعةً واحدة، عادةً ما تحصل على ضباب من السجلّات. من الأوضح بكثير توجيه أحدّ حافّة أوّلاً نحو مسار الفشل المحدّد الذي تهتمّ به.

9. الخلاصة

هذه هي النقاط الرئيسيّة التي يجب الاحتفاظ بها.

ما هو Application Verifier:

  • مدقّق وقت تشغيل لسلوك حدود native / Win32 في Windows
  • أداة يمكنها فحص Handles / Heaps / Locks / Memory / TLS / Low Resource Simulation
  • طريقة للوطء على مسارات الفشل التي تبقى عادةً مخفيّةً

ما جعله فعّالاً بشكل خاصّ في هذه الحالة:

  • يصبح سوء استخدام handle أسهل بكثير في التتبّع باستخدام !htrace
  • يمكن تشغيل حالات فشل تشبه نقص الموارد دون تدمير جهاز التطوير بأكمله
  • يمكن اختبار سجلّاتك المنظّمة الخاصّة لمعرفة ما إذا كانت لا تزال تشرح الفشل بوضوح

الطريقة العمليّة لاستخدامه:

  • شغّل runs المسار الطبيعيّ Basics وحقن الأعطال بشكل منفصل
  • قُد السيناريوهات من خلال harness EXE
  • ادمج سجلّاتك الخاصّة وdumps ومعلومات أداة التصحيح
  • استخدم counters الخاصّة بك لمراقبة اتّجاهات التسريب طويلة الأمد

Application Verifier هو، بمعنى عمليّ جدّاً، أداة لـ الخروج لمقابلة حالات الفشل النادرة بدلاً من انتظار حدوثها بالصدفة.

في تطبيقات التحكّم بالأجهزة، لا يهمّ فقط أن يعمل التطبيق عندما يكون كلّ شيء سليماً. يهمّ بنفس القدر أنّه عندما يكسر، يمكنك شرح ما حدث فعلاً.

10. المراجع

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

حين يتعطّل تطبيق التحكّم بكاميرا صناعيّة فجأةً بعد شهر (الجزء الأوّل) - كيفيّة العثور على handle leak وتصميم السجلّات للتشغيل طويل الأمد

تطبيق التحكّم بكاميرا صناعيّة يتعطّل بعد شهر بسبب handle leak على مسار فشل إعادة الاتّصال. نشرح كيف نضيّق التحقيق ونصمّم سجلّات دورة حياة...

كيف نستعمل Windows Sandbox لتسريع التحقّق من تطبيقات Windows - صلاحيّات المسؤول والبيئات النظيفة وإعادة إنتاج حالات نقص الصلاحيّات أو الموارد

مرشد عمليّ يبيّن كيف يسرّع Windows Sandbox التحقّق من تطبيقات Windows، عبر ملفّات .wsb لكلّ سيناريو وفحوصات المستخدم القياسيّ ومحاكاة شُح...

صفحة دراسة حالة توضّح بنية مشابهة للتشخيص أو تحديد الأولويات أو إعادة التصميم.

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.

روابط عامة

العودة إلى المدونة