وحدة المعالجة المركزية عالقة بنسبة 100% على كمبيوتر العميل، هل هناك أي اقتراحات لتصحيح الأخطاء؟

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

سؤال

أواجه موقفًا مسدودًا مع أحد العملاء الذين يستخدمون برنامجي.من بين حوالي 40 نسخة من منتجنا المباعة (التطبيق المبرمج في .NET 2.0 باستخدام VB.NET 2005)، أصبح حوالي 2 منها غير مستجيبين مع توقف نواة واحدة من وحدات المعالجة المركزية ثنائية النواة بنسبة 100% (يستخدم البرنامج نواة واحدة فقط)

التخمين الأكثر منطقية هو وجود حلقة لا نهائية تسبب هذا السلوك، ولكن هناك آلاف الأسطر من التعليمات البرمجية مع العديد والعديد من الحلقات.هذه هي كل المعلومات التي لدي.الآن، كيف تقترح أن أتعامل مع تصحيح هذه المشكلة؟

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

يحرر:تم حلها.لقد كانت المشكلة الأكثر احتمالا.إن محرك قاعدة بيانات Access الذي استخدمته كنظام إدارة قواعد البيانات هو في الواقع جزء من تطبيقي الذي يمثل مشكلة.يواجه صعوبة في العمل مع صف واحد فقط في أحد الجداول.لا يمكنني حذفه، أو إضافة سجل مرتبط بهذا الصف في أي جدول آخر؛حتى MS Access 2007 يتسبب في ارتفاع مستوى وحدة المعالجة المركزية إلى 100% عندما أحاول العمل مع هذا الصف!

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

بفضل WinDbg تمكنت من العثور على مكان المشكلة.أنصح الجميع بتعلم كيفية استخدامه لأنه يوفر الوقت الحقيقي.

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

المحلول

قم بتثبيت Windbg (مصحح أخطاء Windows) على الجهاز المستهدف.قم باستدعاء مصحح الأخطاء وإرفاق العملية المشبوهة، قم بتشغيل البرنامج ثم انتظر حتى تحدث المشكلة.عند حدوث المشكلة، قم باستدعاء الأمر التالي في سطر أوامر مصحح الأخطاء

!اهرب

سيُظهر هذا أيًا من سلاسل الرسائل لديك يستهلك معظم الوقت.ثم احصل على العديد من مجموعات الخيوط من هذا الموضوع الذي يستهلك معظم موارد وحدة المعالجة المركزية الخاصة بك.

هنا مثال:

0:015> !runaway

وقت وضع المستخدم وقت الخيط الوقت 0: 1074 0 أيام 0: 00: 21.637 11: 137c 0: 00: 02.792 4: 12C8 0 Days 0: 00: 00.530 9: 1374 0 Days 0: 00: 00.046 15: 13d0 0 0 days 0: 00: 00.000 14: 1204 0 Days 0: 00: 00.000 13: 154c 0 Days 0: 00.000 12: 144c 0 Days 0: 00: 00.000 10: 1378 0 Days 0: 00: 00.000 8: 1340 0 days 0: 00: 00.000 7: 12f0 0 Days 0: 00: 00.000 6: 12d4 0 Days 0: 00.000 5: 12d0 0 Days 0: 00: 00.000 3: 12C4 0 Days 0: 00: 00.000 2: 12c0 0 days 0: 00: 00.000 1: 12B4 0 Days 0: 00: 00.000

لنفترض الآن أننا نريد مكدس استدعاءات للخيط الثاني في القائمة، الخيط 11، لذلك نقوم أولاً بالتبديل إلى الخيط 11.يمكن القيام بذلك عن طريق إدخال ~11s.

0:015> ~11s

eax = 03fbb270 ebx = ffffffff ecx = 00000002 edx = 00000060 esi = 00000000 edi = 00000000 eip = 77475e74 esp = 0572f60c ebp = 0572f6c iopl = 0 nv up ei ei ei = = 0023 FS = 003B GS = 0000 EFL = 00000246 NTDLL! KIFASTSYSTEMCALLRET:77475e74 c3 متقاعد

احصل الآن على مكدس استدعاءات لهذا الموضوع عن طريق تنفيذ kp:

0:011> kp
ChildEBP RetAddr  
0572f608 77475620 ntdll!KiFastSystemCallRet
0572f60c 75b09884 ntdll!NtWaitForSingleObject+0xc
0572f67c 75b097f2 kernel32!WaitForSingleObjectEx+0xbe
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Mozilla Firefox 3.1 Beta 1\nspr4.dll - 
0572f690 10019a0b kernel32!WaitForSingleObject+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
0572f6ac 10015979 nspr4!PR_MD_WAIT_CV+0x8b
0572f6c4 10015763 nspr4!PR_GetPrimordialCPU+0x79
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Mozilla Firefox 3.1 Beta 1\xul.dll - 
0572f6e0 64d44d6a nspr4!PR_Wait+0x33
0572f708 64dbe67e xul!NS_CycleCollectorForget2_P+0x698a
0572f72c 10019b3f xul!gfxWindowsPlatform::FontEnumProc+0xfd4e
0572f734 10015d32 nspr4!PR_MD_UNLOCK+0x1f
0572f738 1001624b nspr4!PR_Unlock+0x22
0572f754 1001838d nspr4!PRP_TryLock+0x4cb
00000000 00000000 nspr4!PR_Now+0x109d

سيقوم الأمر kp بطباعة المعلمات.يمكن طباعة المتغيرات المحلية باستخدام dv.

وبدلاً من ذلك يمكنك استخدام مستكشف العمليات من sysinternals.

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

نصائح أخرى

وإذا كان ذلك ممكنا، والحصول على تفريغ عملية والنظر في تتبع المكدس.
أنا لم يفعل ذلك، ولكن ينبغي لها أن تعمل مع VS / WinDbg و SOS (ابن الإضراب). هنا هو بلوق وظيفة حول هذا الموضوع.

إذا هو حلقة لا نهائية، ثم حاول إرفاق المصحح وضرب كسر. WinDbg مثالية لهذا الغرض.

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

لقد أنقذت هذه التقنية لي عدة مرات ويعمل بشكل جيد لطلبات معلقة أيضا:)

وكذلك ستحتاج للعمل على حيث انها ضيقة-حلقات. ما هو العميل الخاص به مع البرنامج في ذلك الوقت؟ ماذا يفعل البرنامج في المقام الأول؟

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

استخدم المسجل مثل log4net حيث يمكنك أعرض مصدر برنامج القائمة الخاصة بك مع < وأ href = "http://www.postsharp.org/" يختلط = "نوفولو noreferrer"> postsharp . تسجيل كافة مداخل ومخارج طريقة - لذا يجب عليك العثور على طريقة خاطئة. ثم يمكنك تحسين تسجيل الخاص بك إذا كان لا يزال مطلوبا.

ويبدو أن هذا هو العمل من أجل vb.net، أيضا، على الرغم من أن ليست لدي خبرة هناك. ربما هذه المقالة يساعد لكم قليلا.

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

ثم يضاف بعناية للبحث عن المفقودين، ولا تنسى أن فلوش في نقاط استراتيجية (أو مجموعة AutoFlush).

ولكن يمكن أن يكون مشكلة توقيت خفية أن يذهب بعيدا بسبب تأخر وأضاف تتبع ...

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

(وأنا أعترف بأنني كتب التطبيق مرة أخرى في العصور المظلمة التي لم نظيفة منفصلة المواضيع خلفية واجهة المستخدم وتسبب في مشاكل عندما حصلت على وحدات المعالجة المركزية متعددة النوى السائدة. وكان الحل لاستدعاء SetProcessAffinity لتقييد التطبيق ل جوهر واحد)

إذا كان هذا هو الحال، لا بد من معرفة ما إذا كان 100٪ CPU تحدث فقط مع نوع خاص من وحدة المعالجة المركزية، وسواء باستخدام SetProcessAffinity يحل المشكلة. إذا كان كذلك، كنت أعرف إلى أين تبحث في التعليمات البرمجية.

ويمكن أن يكون مشكلة خيوط؟ "فشل بشكل متقطع" يجعل لي التفكير في الأمر. لا تتلقى إشارات برنامج / رسائل من الخارج، مثل الاتصال عن بعد / DCOM / مآخذ؟ هو التقدم المعلومات المتعلقة بهذه الرسائل الواردة في المستخدم واجهة؟

وأنا الكشف عن مرة واحدة في مشكلة خيوط لأنني دائما استخدام الكثير من يؤكد. كان هناك ASSERT الاختيار التعقل لبداية من رسالة وردت من خلال XML-RPC لتكون:

"<?xml " 

ووASSERT catched الكتابة والذاكرة الرسالة. بواسطة تفتيش هذا تبين أن ذلك يعود قفل المفقودين في جزء حرج. وكان هذا الاكتشاف من الممكن فقط ل وقد catched المشكلة في وقت مبكر جدا من قبل ASSERT (و حدث بما فيه الكفاية في كثير من الأحيان يتم الكشف).

وهذا ليس specfific جدا أو نصيحة موجهة، ولكن بلدي اقتراح ثم هو إضافة يؤكد في الأماكن التي قد تكون تتأثر مشكلة خيوط.

لاحظ أن إطلاق يؤكد لا يعني بالضرورة إجهاض البرنامج أو رمي صناديق الرسالة. ويؤكد يمكن أن يكون إعادة توجيه إلى ملف السجل بدلا من ذلك، بما في ذلك كامل كومة تتبع في ذلك الوقت من إطلاق ASSERT.

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