نوع القيمة مقابل أنواع المرجع عبر Windbg

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

  •  25-09-2019
  •  | 
  •  

سؤال

أنا جديد على Windbg وأحاول فهم بعض الأشياء حول أنواع القيمة وأنواع الإحالة .NET. هنا هو الرمز الذي أستخدمه

class Program
{
    struct MyStruct
    {
        int x;
        int y;
    }

    class MyClass 
    {
        int x;
        int y;
    }


    static void Main(string[] args)
    {
        MyStruct s ;
        MyClass c = new MyClass();
        Thread.Sleep(5 * 60 * 1000);
    }
}

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

  1. عندما يتم ربط Windbg بالعملية ، فإنه ينقسم إلى هذا الموضوع رقم 3 ، ولكن كما يمكنني أن أرى أنه لا يوجد مؤشر ترابط مع معرف Thead المدارة 3. هل هذا الموضوع يستخدمه Debugger فقط؟ هل هناك أي مؤشرات ترابط أخرى قد لا يتم عرضها بواسطة أمر المواضيع؟ إذا كان الأمر كذلك ، فهل هناك أي أمر يمكن أن يعطيني كل الخيوط؟

0: 003>! المواضيع -خاصة
ThreadCount: 2
غير لائق: 0
BackgroundThread: 1
PendingThread: 0
deadthread: 0
استضافة وقت التشغيل: لا
وقوانين القفل معرف OSID ThreadObj State GC GC Context Context Count APPT استثناء

0 1 BBC 0000000000190C50 200A020 Enabled 00000000027F3CA8: 00000000027F3FD0 0000000000187E40 0 MTA
2 2 106C 0000000000198430 B220 Enabled 0000000000000000: 00000000000000 0000000000187E40 0 MTA (Finalizer)

نوع الخيط الخاص OSID
1 E98 DBGHelper
2 106c النهائي

0: 003>! clrstack
معرف موضوع OS: 0xe6c (3)
غير قادر على المشي المكدس المدارة. من المحتمل ألا يكون الخيط الحالي
موضوع مُدار. يمكنك تشغيل المواضيع! للحصول على قائمة من المواضيع المدارة في
العملية
0: 003> كيلو بايت
Retaddr: args للطفل: موقع الاتصال
0000000077978778 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : ntdll!DbgBreakPoint
00000000
776d466d: 0000000000000000 0000000000000000 0000000000000000 0000000000000000: NTDLL! DBGUIREMOTEBREAKIN+0x38
00000000778d8791 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : KERNEL32!BaseThreadInitThunk+0xd
00000000
00000000 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000: NTDLL! rtluserTherStart+0x1D

  1. الموضوع 0 يبدو وكأنه موضوع تشغيل طريقتي الرئيسية. عندما أحصل على تفريغ كائن المكدس ، فإنه لا يظهر mystruct ولسبب ما يظهر MyClass مرتين. أي أفكار لماذا؟

0: 000>! clrstack
معرف موضوع OS: 0xBBC (0)
موقع استدعاء Child-SP
000000000031EDB0 000007FEF6B32012 CONSLEAPPLICATION2.Program.Main (System.String [])
0: 000>! dumpstackobjects
معرف موضوع OS: 0xBBC (0)
اسم كائن RSP/Reg
000000000031EDD8 00000000027F3C90 CONSLEAPPLICATION2.Program+MyClass
000000000031EDE8 00000000027F3C90 CONSLEAPPLICATION2.Program+MyClass
000000000031EE00 00000000027F3C70 System.Object [] (System.String [])
000000000031EF88 00000000027F3C70 System.Object [] (System.String [])
000000000031F170 00000000027F3C70 System.Object [] (System.String [])
000000000031F198 00000000027F3C70 System.Object [] (System.String [])

تيا

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

المحلول

  1. ال !Threads يعرض الأوامر مؤشرات الترابط المدارة فقط (سوف يتجاهل مؤشرات الترابط الأصلية البحتة).
    لمشاهدة جميع خيوطك (كلاهما مُدار غير مُدارة) ، يمكنك استخدامه ~. (يمكنك تفريغ المداخن الأصلية باستخدام أمر مثل ~*kb أين * يعني "لكل موضوع"]).

  2. ال !dso يعرض الأمر فقط أنواع المراجع ، وأحيانًا يمكن أن يعرض "إيجابيات كاذبة" أو بيانات خاطئة فقط (ستجد أن SOS لديها القليل من أ طبيعة عربات التي تجرها الدواب).

من مساعدة SOS (!help):

! DumpstackObjects -verify] [Top Stack [Stack Stack]

سيعرض هذا الأمر أي كائنات مُدارة يجدها داخل حدود المكدس الحالي. إلى جانب أوامر تتبع المكدس مثل K و! clrstack ، فهي مساعدة جيدة لتحديد قيم السكان المحليين والمعلمات.

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

يمكن استخدام الاختصار! DSO لإيجاز.

نصائح أخرى

عندما ترفق عملية تشغيل ، يقوم مصحح الأخطاء بحقن خيط في العملية ويتم اختياره كخيط الحالي. كما يشير Liran إلى أمر SOS !threads فقط قوائم المواضيع المدارة.

لتطبيق وحدة التحكم البسيطة ، يجب أن تتوقع رؤية موضوعين مُدارين ؛ الخيط الرئيسي الذي يعمل على التطبيق وخيط Finalizer ، والذي بدأه CLR. في تجربتي ، يتم ترقيمها دائمًا 0 و 2 على التوالي.

ال !dso يعرض الأمر المراجع على المكدس. لا يسرد أنواع القيمة. لذلك يمكنك استخدام !clrstack القيادة مع -l للسكان المحليين. ضع في اعتبارك أنه نادراً ما يتم وضعها على المكدس للرمز المحسن ، وعلى X64 ، تجعل اتفاقية الاتصال من الصعب تتبعها.

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