كيف يمكنني عرض المتغيرات المحلية في حزمة التقييم عند تصحيح أخطاء تطبيق .NET CLR؟

StackOverflow https://stackoverflow.com/questions/522522

سؤال

أنا أستخدم Windbg (مع امتداد sos) وأحاول تصحيح أخطاء التطبيق المعطل.لقد تمكنت من تفريغ IL الخاص بالمكالمة التي طرحت الاستثناء ومن خلال فحص الكود، يبدو أنه يمكنني الحصول على المعلومات التي أحتاجها إذا كان بإمكاني تفريغ محتويات مكدس التقييم.هل من الممكن أن تفعل ما مع WinDbg & sos؟

وإليك ما فعلته:

  1. بدأت WinDbg
  2. تعلق على عملية تحطمت
  3. تحميل بواسطة sos mscorwks (لتحميل ملحق sos)
  4. !token2ee theModuleName 0600009أ (أين theModuleName هو اسم التطبيق (والتجميع) رأي تصحيح الأخطاء و 9 أ هي طريقة إزاحة الطريقة التي تعطلت كما أبلغت عنها أداة Windows Error Reporting.حصلت على هذا الإخراج:

    وحدة:000e2c3c (theApplicationName.exe)
    الرمز المميز:0x0600009a
    وصف الطريقة:000e67c8
    اسم:MyNamespace.MyClassName.theCulpritFn(MyOtherClass)
    عنوان كود JITTED:0081b1d0

  5. !دمبل 00e67c8 (الذي تخلص من IL للطريقة المعنية).هذا هو الإخراج:

    
    // ..
    // .. the previous code omitted for brevity
    .catch
    {
     IL_0071: stloc.0
     IL_0072: nop
     IL_0073: ldstr "Can't set CurrentServer property for: "
     IL_0078: ldarg.0
     IL_0079: ldfld MyNamespace.MyClassName::_currentServer
     IL_007e: brtrue.s IL_0087
     IL_0080: ldstr ""
     IL_0085: br.s IL_0092
     IL_0087: ldarg.0
     IL_0088: ldfld MyNamespace.MyClassName::_currentServer
     IL_008d: callvirt MyNamespace.MyOtherClass::get_Name
     IL_0092: call System.String::Concat
     IL_0097: ldloc.0
     IL_0098: newobj MyNamespace.MySpecialExceptionType::ctor
     IL_009d: throw
    } 
    

    السؤال هو:هل هناك طريقة بالنسبة لي لمعرفة ما تم دفعه على المكدس قبل طرح الاستثناء.إذا لم أكن مخطئًا، فيجب أن تكون الوسيطة التي تم تمريرها إلى مُنشئ الاستثناء هي المتغير المحلي عند الفهرس 0 في حزمة التقييم.

    ملاحظة.عندما حاولت الاتصال !clrstack -a وصلتني رسالة تقول:غير قادر على السير في المكدس المُدار.من المحتمل أن يكون مؤشر الترابط الحالي ليس موضوعًا مُدارًا.يمكنك تشغيل !threads للحصول على قائمة بسلاسل الرسائل المُدارة في هذه العملية.

شكرًا!

هل كانت مفيدة؟

المحلول

تحتاج إلى تحديد واختيار الموضوع الصحيح.يتم عرض معرف مؤشر الترابط الحالي في موجه WinDbg.

!threads سيتم عرض كافة المواضيع المدارة في التطبيق الخاص بك.بمجرد تحديدها يمكنك تبديل المواضيع باستخدام ~Xs حيث X هو معرف WinDbg لمؤشر الترابط.

!clrstack سوف تظهر لك تتبع المكدس.إذا كنت تريد استخدام السكان المحليين و/أو المعلمات -l / -p (أو -a لكليهما).

يمكنك الاطلاع على جميع المواضيع وسرد مكدس الاستدعاءات الخاص بها ~*e!clrstack.

إذا لم توفر لك المعلمات المحلية/المعلمات ما تحتاجه، فاستخدم !dso لعرض الكائنات المدفوعة على المكدس.

نصائح أخرى

واو، هذا صعب بدون وجود مكب نفايات حقيقي يمكن اختراقه.:-)

وهنا سؤالين..وبعد ذلك سأضيف أمرًا واحدًا لم يتم إدراجه مسبقًا في الإجابات أعلاه..

أسئلة:

  1. هل أنت متأكد من أنك حصلت على الاستثناء الأول وليس فقط الاستثناء الأخير الذي لم تتم معالجته وتم هدمه في العملية؟

  2. هل يمكنك إلقاء نظرة على مكدس الاستدعاءات الأصلي لسلسلة الرسائل التي طرحت الاستثناء؟
    ملحوظة:يجب أن يكون هناك استدعاء لـ RaiseException() أو انتهاك الوصول.

  3. احذر من الاستثناءات غير المتزامنة التي ليس لها أي علاقة على الإطلاق بالرمز الخاص بك ويمكن أن تدخل وتدفعك إلى كتلة الالتقاط...أو ما هو أسوأ (Thread.AbortException/System.OutofMemoryException و...StackOverflowException :-)

للحفر أكثر تقوم بالركض !مكدس النفايات على الخيط المعيب..الإخراج هو ليس بالضبط ومع ذلك، فهو يقوم بعمل رائع في السير على مكدس استدعاءات الخيوط وقد تكون محظوظًا وترى ملفًا @ الرمز الذي يشير إلى استثناء بـ .cxr و.exr في الرسالة.إذا قمت بذلك، فيمكنك الركض .cxr -عنوان cxr وانظر ما هو الاستثناء الأول في سلسلة الاستثناءات.

نقطة:على الرغم من أنني قد أجانب السؤال، إذا كان الاستثناء يستدعي WER فقد كان كذلك لم يتم التعامل معها وقمت بإسقاط العملية التي قد ترغب في تسجيل مكدس الاستدعاءات الأولي أو إضافة الاستثناء السابق كاستثناء داخلي حتى تتمكن من تحديد السبب الجذري.

شكرا يا هارون

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top