حين يتعطّل تطبيق التحكّم بكاميرا صناعيّة فجأةً بعد شهر (الجزء الثاني) - ما هو 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، وما يمكنه فعله، وكيفيّة استخدامه لبناء بنية اختبار عمليّة لمسارات الفشل في سياق تطبيق التحكّم بكاميرا صناعيّة.
المحتويات
- النسخة المختصرة
- ما هو Application Verifier
- ماذا يستطيع Application Verifier أن يفعل
- لماذا أدخلناه في هذه الحالة
- كيفيّة تشغيل سلوك يشبه نقص الذاكرة أو الموارد
- كيفيّة فحص المشكلات المتعلّقة بـ handle
- كيفيّة بناء بنية اختبار مسارات الفشل
- دليل قواعد عامّة تقريبيّة
- الخلاصة
- المراجع
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. لماذا هو مفيد عمليّاً
الفوائد العمليّة هي بشكل رئيسيّ هذه:
- يمكنه إيقاف سوء استخدام الحدود الأصليّة في وقت أبكر
- invalid handle
- heap corruption
- lock misuse
- سوء استخدام API الذاكرة الافتراضيّة
- يمكنه إجبار مسارات الفشل التي يصعب عادةً تشغيلها
- حالات فشل تشبه التخصيص
- حالات فشل إنشاء ملف / حدث
- سلوك الموارد المنخفضة دون انهيار الجهاز بأكمله فعليّاً
- يعمل بشكل جيّد مع أدوات التصحيح
!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 لإنشاء الموارد أو التخصيص
- أجبرها على الفشل باحتماليّة مختارة
هذا يجعل من الأسهل بكثير اختبار مسارات الخطأ التي لولا ذلك لن تعمل تقريباً أبداً.
تشمل الأمثلة النموذجيّة:
HeapAllocVirtualAllocCreateFileCreateEventMapViewOfFile- تخصيصات OLE / COM مثل
SysAllocString
3.3. Page Heap وأداة التصحيح
إذا كان الاشتباه هو تلف heap، فإنّ Heaps بالإضافة إلى page heap يكون قويّاً بشكل خاصّ.
يمكن لـ full page heap أن يجعل التلف يتوقّف أقرب بكثير إلى لحظة حدوثه، بفضل سلوك guard-page.
لكنّه ثقيل أيضاً. لذلك يكون عادةً أفضل للاستخدام في:
- إعادة إنتاج مركّزة
- سيناريوهات مرفقة بأداة التصحيح
- تحقيق ضيّق بمجرّد أن يصبح الاشتباه موضعيّاً بالفعل
التقدّم العمليّ غالباً هو:
- استخدم
Basicsعلى نطاق واسع أوّلاً - إذا أصبح تلف heap محتملاً، انتقل إلى full page heap
- إذا كان ذلك ثقيلاً جدّاً، خفّف
- اجعل 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
التسلسل العمليّ عادةً هو:
- شغّل المسار الطبيعيّ مع
Basicsفقط - ثمّ أضف
Low Resource Simulation - إذا لزم الأمر، ركّز على أنواع الفشل التي تهتمّ بها فقط، مثل
fileأوevent - إذا لزم الأمر، وجّهه بشكل أضيق نحو 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دوريّsessionIdresourceIdphase- سجلّات دورة الحياة لـ
create/openوclose/dispose - dumps ومخرجات أداة التصحيح عند توقّف verifier
ثمّ يصبح النمط:
- يكشف تسجيل heartbeat عن ميل مشبوه لـ
Handle Count - تضيّق سجلّات دورة الحياة الموارد التي أُنشئت دون إغلاق مطابق
- تظهر runs الـ verifier استخدام handle غير الصالح أو سوء الاستخدام في وقت أبكر
- يكشف
!htraceعن stacks الفتح / الإغلاق
هذه الرؤية المجمّعة أقوى بكثير من أيّ من تلك الأدوات وحدها.
7. كيفيّة بناء بنية اختبار مسارات الفشل
7.1. ادفع التنفيذ إلى harness EXE
لا يمكن تشغيل Application Verifier بعد أن تكون العمليّة قد بدأت بالفعل. تكوّن أوّلاً، ثمّ تشغّل.
أيضاً، تظلّ إعداداته حتّى تمسحها بشكل صريح. لذلك عمليّاً، يكون عادةً من الأسهل استهداف EXE harness اختباريّ بدلاً من تطبيق الإنتاج الحقيقيّ نفسه.
يبدو الشكل الشائع هكذا:
flowchart LR
A[Scenario Runner] --> B[CameraHarness.exe]
B --> C[CameraSdkWrapper.dll]
C --> D[Vendor SDK]
B --> E[Structured Log]
B --> F[Dump / Debugger]
هذا يعطيك:
- عمليّة واحدة لكلّ سيناريو
- مقارنة تسريب أسهل
- تحكّم سهل في تشغيل / إيقاف إعدادات AppVerifier
- مكان طبيعيّ لاختبار سلوك DLL من خلال EXE الذي يحمّله فعلاً
أشكال الأوامر النموذجيّة هي:
appverif /verify CameraHarness.exe
appverif /n CameraHarness.exe
القاعدة المهمّة هي:
- مكّن قبل التشغيل
- عطّل بشكل صريح عند الانتهاء
التنفيذ بنهج harness-first يقلّل الكثير من الالتباس في التكوين.
7.2. قسّم قائمة الاختبار حسب الغرض
في بنية اختبار مسارات الفشل، يكون من الأوضح عادةً عدم تشغيل كلّ شيء معاً. ثلاث مجموعات هي تقسيم عمليّ جدّاً:
- المسار الطبيعيّ + Basics
- لا حقن أعطال
- فقط تأكّد من أنّ verifier stops لا تحدث في التشغيل العاديّ
- runs حقن الأعطال
- استخدم
Low Resource Simulation - استهدف
eventوfileوheap_allocوvirtual_allocوأنواع فشل مماثلة
- استخدم
- 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 وتصميم السجلّات للتشغيل طويل الأمد
- Application Verifier - Overview
- Application Verifier - Testing Applications
- Application Verifier - Tests within Application Verifier
- Application Verifier - Debugging Application Verifier Stops
- Application Verifier - Features
- !htrace (WinDbg)
- GetProcessHandleCount
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
حين يتعطّل تطبيق التحكّم بكاميرا صناعيّة فجأةً بعد شهر (الجزء الأوّل) - كيفيّة العثور على handle leak وتصميم السجلّات للتشغيل طويل الأمد
تطبيق التحكّم بكاميرا صناعيّة يتعطّل بعد شهر بسبب handle leak على مسار فشل إعادة الاتّصال. نشرح كيف نضيّق التحقيق ونصمّم سجلّات دورة حياة...
حين تتوقّف حركة TCP للكاميرا الصناعيّة لعدّة ثوانٍ - كيف نضيق نطاق انتظار إعادة الإرسال باستخدام طوابع زمنيّة RFC1323
تشريح لتوقّفات TCP المتقطّعة لعدّة ثوانٍ بين تطبيق المضيف والكاميرا الصناعيّة، مع استخدام Wireshark وفقد الحزم وطوابع RFC1323 الزمنيّة لت...
المزالق الشائعة في تطوير مكوّنات COM و OCX / ActiveX - فخاخ Visual Studio بين 32-bit و 64-bit، والتسجيل، وصلاحيّات المسؤول
دليل عمليّ يكشف الأسباب الحقيقيّة لإخفاق مكوّنات COM و OCX و ActiveX: عدم تطابق 32-bit / 64-bit مع Visual Studio 2022، وأخطاء regsvr32 و ...
ما هو ClickOnce - كيف يعمل، وكيف تعمل التحديثات، ومتى يلائم العمل الفعليّ ومتى لا يلائمه
نظرة عمليّة على ClickOnce لتوزيع تطبيقات .NET لسطح مكتب Windows: كيف تعمل manifests والتحديثات والـ cache، ومتى يلائم العمل الداخليّ ومتى...
كيف نستعمل Windows Sandbox لتسريع التحقّق من تطبيقات Windows - صلاحيّات المسؤول والبيئات النظيفة وإعادة إنتاج حالات نقص الصلاحيّات أو الموارد
مرشد عمليّ يبيّن كيف يسرّع Windows Sandbox التحقّق من تطبيقات Windows، عبر ملفّات .wsb لكلّ سيناريو وفحوصات المستخدم القياسيّ ومحاكاة شُح...
دراسة حالة ذات صلة
صفحة دراسة حالة توضّح بنية مشابهة للتشخيص أو تحديد الأولويات أو إعادة التصميم.
دراسة حالة: بنية اختبار مسارات الفشل باستخدام Application Verifier
دراسة حالة لبناء أساس اختبار مسارات الفشل يسهّل التحقيق في الأعطال المستقبلية.
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
التحقيق في الأخطاء وتحليل السبب الجذري
ندعم التحقيق في الأعطال التي يصعب إعادة إنتاجها، والمشكلات بعد التشغيل الطويل، وتوقّفات التواصل.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.
روابط عامة