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

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

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

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

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

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

المحتويات

  1. النسخة المختصرة
  2. ما يعنيه handle leak هنا
  3. دراسة حالة: تطبيق التحكّم بالكاميرا الصناعيّة الذي تعطّل بعد شهر
  4. كيف ضيّقنا نطاق التحقيق
  5. ما هي السجلّات اللازمة لمنع تكرار الحادث
  6. دليل قواعد عامّة تقريبيّة
  7. الخلاصة
  8. المراجع

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

  • في تطبيقات التحكّم التي تفشل فقط بعد التشغيل طويل الأمد، انظر دائماً إلى Handle Count بالإضافة إلى Private Bytes
  • تميل عمليّات handle leak إلى الاختباء في مسارات timeout / reconnect / فشل جزئيّ / early return بدلاً من المسار الطبيعيّ
  • السطر الذي يتعطّل فيه التطبيق أخيراً ليس في الغالب هو السطر الذي تسرّب منه المورد أصلاً
  • أهمّ السجلّات هي سياق operation / session، وHandle Count على مستوى العمليّة، وتماثل فتح / إغلاق الموارد، وتفاصيل أخطاء Win32 / HRESULT / SDK
  • بدلاً من انتظار شهر آخر لإعادة الإنتاج، اختصر المسار بضرب سيناريوهات الاتّصال / قطع الاتّصال / إعادة الاتّصال / الفشل في حلقة
  • Application Verifier، الذي نناقشه في الجزء الثاني، فعّال جدّاً، لكنّ سجلّاتك الخاصّة التي تكشف تماثل دورة حياة الموارد هي الأساس

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

تظهر عمليّات handle leak غالباً بوجه عطل ثانويّ لاحق.
إذا قرأت الاستثناء النهائيّ فقط، فمن السهل جدّاً أن تسير في الاتّجاه الخاطئ.

2. ما يعنيه handle leak هنا

2.1. ما يعنيه “handle” في هذا السياق

هنا، يعني handle معرّفاً على مستوى عمليّة Windows يُستخدم للإشارة إلى الموارد التي يديرها نظام التشغيل.
الأمثلة النموذجيّة تشمل:

الفئة الأمثلة
kernel objects event، mutex، semaphore، thread، process، waitable timer
الموارد المتعلّقة بـ I/O file، pipe، socket، فتح الأجهزة
شائعة بشكل خاصّ في تطبيقات التحكّم بالأجهزة events داخليّة لـ SDK، كائنات تسجيل callback، handles مرتبطة بـ thread الالتقاط

ما يسبّب المشاكل غالباً في تطبيقات التحكّم هو إنشاء مورد مؤقّتاً لعمليّة معيّنة ونسيان إغلاقه على مسار فشل في المنتصف.

على سبيل المثال:

  • إنشاء event واحد في كلّ مرّة تبدأ فيها إعادة الاتّصال
  • فشل تسجيل callback أو بدء الالتقاط جزئيّاً في المنتصف
  • المسار الناجح يغلقه، لكنّ مسار الفشل لا يفعل
  • الاختبارات القصيرة تشغّل في معظمها المسار الناجح، لذا يُفوَّت التسريب

هذا النوع من الأخطاء يختبئ بشكل طبيعيّ جدّاً في كلّ من مراجعة الكود والتشغيل الفعليّ.

2.2. لماذا يظهر غالباً بعد التشغيل طويل الأمد فقط

handle leak لا يفشل بالضرورة بشكل مذهل من الحدوث الأوّل.
النمط الخطر عادةً هو ميل صغير جدّاً: مورد واحد يتسرّب لكلّ فشل.

flowchart LR
    A["Normal operation"] --> B["Occasional timeout / reconnect"]
    B --> C["Failure path creates an event handle"]
    C --> D["CloseHandle is not called"]
    D --> E["Handle Count rises slightly"]
    E --> F["The pattern repeats hundreds or thousands of times"]
    F --> G["Later CreateEvent / SDK open starts failing"]
    G --> H["Secondary crash or stop"]

إذا تسرّب من إعادة اتّصال واحدة handle واحد فقط، فقد لا يحدث شيء لأيّام.
لكن في تطبيق تحكّم يعمل 24/7، تتكرّر مراراً وتكراراً حواف timeout وإعادة التهيئة وإعادة الاتّصال.
هكذا يمكن للتسريب أن يطفو على السطح بعد أسابيع فقط.

ما يهمّ هو أنّ handle leak نفسه قد لا يكون السطر الفعليّ للتعطّل النهائيّ.
الأشكال النموذجيّة للفشل اللاحق تشمل:

  • استدعاءات API التي تنشئ event / file / thread جديداً تبدأ في الفشل
  • يفشل SDK في تهيئة الموارد الداخليّة ويعيد فقط رمز فشل عامّاً
  • مسار الخطأ رفيع، والكود اللاحق يتعثّر على null أو handle غير صالح
  • يزداد timeout حتّى يقتل التطبيقَ watchdog أو مسار تحكّم على مستوى أعلى

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

2.3. كيف يختلف عن تسريب الذاكرة

أعطال التشغيل طويل الأمد تجعل الناس يشكّون في تسريبات الذاكرة أوّلاً، وهذا أمر طبيعيّ.
لكن غالباً ما ينبغي التحقيق في عمليّات handle leak على محور مختلف.

وجهة النظر تسريب الذاكرة handle leak
أوّل مقياس يجب مراقبته Private Bytes، Commit، Working Set Handle Count
العَرَض النموذجيّ ضغط الذاكرة، paging، تباطؤ، OOM فشل Create* / Open* / تهيئة SDK، أعطال ثانويّة
أين تميل إلى الاختباء المراجع المحتجزة، الـ caches، نسيان التحرير عدم تماثل بين create/open وclose/dispose
الاتّجاه النموذجيّ تنمو الذاكرة باطّراد يرتفع Handle Count ولا يعود

لذلك عند التعامل مع أعطال التشغيل طويل الأمد، فإنّ النظر إلى الذاكرة فقط غالباً ما يشبه القيادة بعين واحدة مغلقة.
كحدّ أدنى، ينبغي فحص Handle Count وThread Count معاً.

3. دراسة حالة: تطبيق التحكّم بالكاميرا الصناعيّة الذي تعطّل بعد شهر

3.1. كيف بدت الأعراض

كانت الأعراض الظاهريّة بسيطة:

  • تطبيق Windows يتحكّم بكاميرا صناعيّة يعمل 24/7
  • في الظروف العاديّة يعمل بشكل جيّد
  • بعد حوالي شهر، يتعطّل فجأةً في يوم ما
  • بعد إعادة التشغيل، يعمل مرّة أخرى لفترة

المشكلة الأولى ببساطة هي أنّ الزمن حتّى الفشل طويل جدّاً.
انتظار شهر لكلّ دورة إعادة إنتاج أمر قاسٍ كاستراتيجيّة تحقيق.

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

بهذا المظهر، تبدو كلّ هذه الأمور معقولةً في البداية:

  • عدم استقرار في SDK الكاميرا
  • أعطال مؤقّتة في الجهاز أو الاتّصالات
  • تسريب ذاكرة
  • بعض السباقات (race) المتعلّقة بالـ threads
  • فشل تهيئة لم يصل إلى السجلّات قطّ

بعبارة أخرى، كان هناك ببساطة عدد كبير جدّاً من الأمور المشبوهة بشكل غامض.

3.2. أوّل المقاييس التي نظرنا إليها

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

المقياس الاتّجاه الملاحَظ القراءة
Handle Count ارتفع قليلاً بعد إعادات الاتّصال أو timeouts ولم يعد اشتبه في handle leak
Private Bytes تحرّك صعوداً وهبوطاً، لكنّه لم يُظهر ميلاً رتيباً قويّاً قد لا تكون ذاكرة الـ heap الجاني الرئيسيّ
Thread Count ثابت في معظمه يبدو تسريب thread أقلّ احتمالاً
موقع التعطّل تنوّع قليلاً في كلّ مرّة يبدو عطل ثانويّ محتملاً

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

3.3. نقطة التسريب الفعليّة

كان السبب النهائيّ هو نسيان إغلاق event handle أُنشئ على مسار فشل تهيئة أثناء إعادة اتّصال الكاميرا.

في صورة مبسّطة، بدا التدفّق هكذا:

sequenceDiagram
    participant App as Control app
    participant OS as Windows
    participant SDK as Camera SDK

    App->>OS: CreateEvent
    App->>SDK: Register callback
    SDK-->>App: Partial failure / timeout
    Note over App: failure path returns
    Note over App: CloseHandle is never called

    loop many reconnects
        App->>OS: Handle Count rises little by little
    end

    App->>OS: Next CreateEvent / Open
    OS-->>App: Failure
    App-->>App: Secondary crash

من الناحية المفهوميّة، كان الكود يبدو كهذا النوع من التسريب:

handle = CreateEvent(...)

if (!RegisterCallback(handle))
{
    return Error;   // CloseHandle(handle) is missing
}

if (!StartAcquisition())
{
    return Error;   // close is also missing here
}

...
CloseHandle(handle)

سبب فوات الاختبارات القصيرة لهذا واضح أيضاً نسبيّاً:

  • في بدء التشغيل العاديّ -> الإيقاف العاديّ، يُغلق handle
  • يحدث الفشل فقط أثناء إعادة الاتّصال
  • لا يوجد اختبار يقود ذلك المسار للفشل بشكل متكرّر بحجم كبير
  • في الإنتاج، يتراكم التسريب ببطء على مدى أسابيع

لذلك كانت البنية: غير مرئيّ إذا نظرت إلى المسار الطبيعيّ فقط، لكنّه تسريب عاديّ جدّاً على المسار غير الطبيعيّ.

الإصلاح نفسه لم يكن مبهرجاً:

  • قرّب مسؤوليّات create/open وclose/dispose من بعضها البعض
  • تأكّد من تحرير الموارد دائماً حتّى عند الفشل الجزئيّ، على سبيل المثال باستخدام finally أو destructor أو session object
  • اجعل الملكيّة (ownership) صريحةً قبل وبعد تسجيل callback أو بدء الالتقاط
  • عبّر عن “من يغلق هذا” كمسؤوليّة في الكود وليس كتعليق

هذه ليست خدعة خاصّة بقدر ما هي تصميم لدورة الحياة مدمج في الكود.

4. كيف ضيّقنا نطاق التحقيق

4.1. اضغط إعادة الإنتاج بدلاً من الانتظار شهراً آخر

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

في هذه الحالة، ضُغطت إعادة الإنتاج بحلقات كهذه:

flowchart LR
    A["Start"] --> B["Open camera"]
    B --> C["Start acquisition"]
    C --> D["Simulated timeout / disconnect"]
    D --> E["Reconnect"]
    E --> F["Resume acquisition"]
    F --> G{"Repeat N times"}
    G -- yes --> D
    G -- no --> H["Check the final delta"]

النقطة هي قضاء الوقت على حواف دورة الحياة، وليس على وقت “إنّه يلتقط الإطارات بشكل صحيح” الطبيعيّ.

السيناريوهات التالية تساعد:

  • شغّل open -> start -> stop -> close بحجم كبير
  • احقن timeouts عمداً وافرض إعادات الاتّصال
  • افشل مباشرةً بعد تسجيل callback
  • ضمّن مقاطعة قطع الاتّصال ومقاطعة إعادة الاتّصال وسباقات الإيقاف

لست بحاجة إلى إعادة تشغيل شهر كامل من الإنتاج بشكل مثاليّ.
عادةً ما يكون الوطء على حافّة دورة الحياة التي تشكّ فيها آلاف المرّات أكثر فاعليّةً بكثير.

4.2. انظر إلى ميل Handle Count

في تحقيقات handle leak، يمكن أن تكون القيم المطلقة وحدها مضلّلة.
ما يهمّ هو ما إذا كان العدد يعود بعد عمليّة من المفترض أن تحرّر الموارد، وكم ينمو لكلّ دورة متكرّرة.

تسلسل عمليّ هو:

  1. تحديد baseline بعد warm-up
  2. تسجيل Handle Count بعد إعادة الاتّصال / start-stop / close
  3. فحص الفرق لكلّ دورة
  4. فحص الميل عبر عدّة دورات أيضاً

على سبيل المثال:

leakSlope =
    (currentHandleCount - baselineHandleCount)
    / reconnectCount

ما إذا كانت قيمة مطلقة مثل 2000 عاليةً أم منخفضةً يعتمد على التطبيق.
لكن إذا أضافت إعادة اتّصال واحدة حوالي +1 ولا تعود أبداً، فهذا مشبوه جدّاً.

من المفيد أيضاً عدم النظر إلى Handle Count وحده.
كحدّ أدنى، سجّله مع:

  • Handle Count
  • Private Bytes
  • Thread Count
  • ReconnectCount
  • المرحلة (phase) الحاليّة

هذا يخبرك بسرعة ما إذا كانت الذاكرة تنمو، أو الـ threads تنمو، أو إعادات الاتّصال تعود مع موارد لا تزال غير متوازنة.

4.3. قارن create/open مع close/dispose

حتّى عندما يبدو Handle Count على مستوى العمليّة بأكمله مشبوهاً، فإنّ ذلك وحده لا يخبرك بموقع التسريب.
الشيء التالي الذي تحتاجه هو تسجيل يُظهر دورة حياة الموارد كأزواج متطابقة.

على سبيل المثال، سجلّات منظّمة مثل هذه:

CameraSession session=421 cameraId=CAM01 phase=ReconnectStart reason=FrameTimeout handleCount=1824 privateBytesMB=418

CameraResource session=421 resourceId=evt-884 kind=Event name=FrameReady action=Create osHandle=0x00000ABC handleCount=1825

CameraResource session=421 resourceId=evt-884 kind=Event name=FrameReady action=Close osHandle=0x00000ABC handleCount=1824

النقطة المهمّة هي عدم الاعتماد على osHandle فقط.
يمكن إعادة استخدام قيم handle في Windows لاحقاً، لذا في السجلّات يكون من الأسهل بكثير متابعة القصّة إذا قمت بتضمين على الأقلّ:

  • sessionId
  • resourceId
  • kind
  • action(Create/Open/Register/Close/Dispose/Unregister)
  • osHandle
  • phase

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

4.4. ابحث عن المكان الذي تسرّب فيه handle، لا فقط عن مكان وقوع التعطّل

هذه النقطة مهمّة جدّاً.

تبدو عمليّات handle leak غالباً هكذا:

  • سطر التعطّل: فشل CreateEvent
  • التسريب الحقيقيّ: كان CloseHandle مفقوداً على مسار فشل لأيّام

بعبارة أخرى، فإنّ API الذي يتعطّل أخيراً غالباً ما يكون نقطة خروج الضرر، وليس نقطة دخول السبب.

لذا فإنّ ترتيب التحقيق عادةً ما يكون أفضل هكذا:

  1. انظر إلى أيّ مورد يستمرّ في النموّ
  2. انظر إلى أيّ حدود عمليّات يفشل في العودة
  3. ابحث عن المكان الذي يكون فيه زوج create/open وclose/dispose مكسوراً
  4. ثمّ فقط اقرأ موقع التعطّل النهائيّ

هذا الترتيب يجعل من الأقلّ احتمالاً بكثير أن تضيع.

5. ما هي السجلّات اللازمة لمنع تكرار الحادث

5.1. الحدّ الأدنى الذي يستحقّ الاحتفاظ به

ما ساعد في هذا التحقيق لم يكن “إضافة المزيد من السجلّات فحسب”.
كان إضافة المزيد من المعلومات التي ستسمح لنا لاحقاً بالوصول إلى السبب.

كحدّ أدنى، من المفيد الاحتفاظ بما يلي:

الفئة الحقول الدنيا التي تستحقّ الاحتفاظ بها السبب
سياق العمليّة cameraId، sessionId، operationId، reconnectCount، phase لربط حدث بالعمليّة الدقيقة ودورة إعادة المحاولة
موارد العمليّة handleCount، privateBytes، workingSet، threadCount لتقسيم ما ينمو فعلاً
دورة حياة الموارد action، resourceId، kind، osHandle، owner لمتابعة create/open مقابل close/dispose
نتائج الاستدعاءات الخارجيّة win32Error، HRESULT، sdkError، timeoutMs لمقارنة أنواع الفشل لاحقاً
انتقالات الحالة OpenStart، OpenDone، ReconnectStart، ReconnectDone، ShutdownStart، إلخ. لمعرفة أيّ مرحلة انهارت
بيئة التشغيل pid، tid، buildVersion، machineName لمطابقة الـ dumps والرموز ومنتجات النشر

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

5.2. السجلّات التي عزّزناها فعلاً

في هذه الحالة، تمّ تعزيز التسجيل في أربعة اتّجاهات:

  1. heartbeat دوريّ
    • إصدار Handle Count / Private Bytes / Thread Count / ReconnectCount كلّ 1 إلى 5 دقائق
  2. سجلّات حدود session الكاميرا
    • OpenStart
    • CallbackRegistered
    • AcquisitionStart
    • TimeoutDetected
    • ReconnectStart
    • ReconnectDone
    • CloseStart
    • CloseDone
  3. سجلّات دورة حياة الموارد
    • Create/Open/Register وClose/Dispose/Unregister للأحداث والـ threads والملفّات والمؤقّتات وtokens تسجيل SDK
  4. توحيد الأخطاء
    • بدلاً من الاكتفاء برسالة الاستثناء، إصدار win32Error وHRESULT وsdkError وphase معاً

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

5.3. ما مدى دقّة دقّة السجلّ المطلوبة

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

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

  • مراقبة دوريّة
    • Handle Count، Private Bytes، Thread Count، ReconnectCount
  • حدود العمليّات
    • بدء / انتهاء / فشل session
  • حدود الموارد
    • create/open/register وclose/dispose/unregister
  • تفاصيل الحالات غير الطبيعيّة
    • رموز الأخطاء، الـ stack traces، شروط تشغيل dump

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

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

  • يحدث التعطّل فقط بعد أيّام أو أسابيع
    • أوّلاً أضف heartbeat لـ Handle Count / Private Bytes / Thread Count
  • يحتوي النظام على مسارات إعادة المحاولة / إعادة الاتّصال / الإيقاف
    • ابنِ harness يقود تلك الحدود فقط بحجم كبير
  • يستخدم التطبيق الكثير من native SDK أو P/Invoke أو Win32
    • تقنيّات Application Verifier في الجزء 2 تستحقّ الاستخدام بشكل خاصّ
  • يتضمّن التطبيق أيضاً واجهة مستخدم رسوميّة
    • بالإضافة إلى Handle Count، انظر أيضاً إلى GDI Objects وUSER Objects
  • الاستثناء النهائيّ لا يخبرك بشيء تقريباً
    • عادةً ما يكون من الأسرع تحسين السجلّات المنظّمة لدورة حياة العمليّة / session / المورد أوّلاً

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

7. الخلاصة

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

كيفيّة قراءة الأعراض:

  • إذا تعطّل التطبيق فقط بعد التشغيل طويل الأمد، انظر إلى Handle Count بالإضافة إلى الذاكرة
  • تميل عمليّات handle leak إلى الاختباء على مسارات الفشل غير الطبيعيّة بدلاً من المسار الطبيعيّ
  • موقع التعطّل غالباً ما لا يكون موقع التسريب بل فقط نقطة خروج الضرر الثانويّ

تغييرات التصميم التي تساعد في منع التكرار:

  • قرّب مسؤوليّات create/open وclose/dispose من بعضها البعض
  • احتفظ بسجلّات غنيّة بالسياق حسب session / operation
  • سجّل كلّاً من مقاييس الموارد على مستوى العمليّة وأحداث دورة حياة كلّ مورد

استراتيجيّة الاختبار التي تساعد:

  • لا تنتظر إعادة إنتاج بمقياس شهور؛ قُد timeout / إعادة الاتّصال / الإيقاف في حلقة قصيرة
  • لا تجعل “لا يتعطّل” معيار القبول الوحيد؛ اشترط أيضاً أنّه “عندما يتعطّل، يمكننا تتبّعه”
  • في الجزء 2، استخدم Application Verifier لإظهار حالات الفشل التي يصعب تشغيلها مثل استنفاد الموارد وحالات handle الشاذّة في وقت أبكر

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

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

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

8. المراجع

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

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

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

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

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

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

غو كومورا

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

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

روابط عامة

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