سؤال

لدي تطبيق C قمنا بنشره على موقع العملاء.تم تجميعه وتشغيله على HP-UX.أبلغ المستخدم عن حدوث عطل وحصلنا على ملف تفريغ أساسي.حتى الآن، لم أتمكن من تكرار الحادث في المنزل.

كما قد تظن، فإن الملف الأساسي/الملف القابل للتنفيذ الذي تم نشره خالٍ تمامًا من أي نوع من الرموز.عندما أقوم بتحميله في gdb وأجري bt، أفضل ما أحصل عليه هو هذا:

(gdb) bt
#0  0xc0199470 in ?? ()

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

لدي نسخة تصحيح (مترجمة مع -g) من الملف القابل للتنفيذ، وهو للأسف أحدث من الإصدار الذي تم إصداره ببضعة أشهر.إذا حاولت بدء gdb مع هذا المحور، أرى هذا:

warning: exec file is newer than core file.
Core was generated by `program_name'.
Program terminated with signal 11, Segmentation fault.
__dld_list is not valid according to __dld_flags.

#0  0xc0199470 in ?? ()
(gdb) bt
#0  0xc0199470 in ?? ()

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

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

هل هناك أي طريقة يمكنني من خلالها الحصول على مزيد من المعلومات من هذا التفريغ الأساسي؟عبر سلاسل أو مصحح أخطاء آخر أو أي شيء؟شكرًا.

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

المحلول

وهذا النوع من الاستجابة من جدب:

(gdb) bt
#0  0xc0199470 in ?? ()

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

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

نصائح أخرى

للمستقبل:

  1. تأكد من أنك تقوم دائمًا بالإنشاء باستخدام قاعدة بيانات رموز خارجية (هذا ليس بناء تصحيح - إنه إصدار إصدار، ولكنك تقوم بتخزين جدول الرموز بشكل منفصل)
  2. احتفظ بها للإصدارات التي تنشرها

لهذه الحالة:

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

وتحت جدب، "معلومات السجلات" يجب أن يوفر لك ما يكفي من دولة التنفيذ في وقت وقوع الحادث للاستخدام مع التفكيك القابل للتنفيذ ووالمكتبات المشتركة ذات الصلة. وعادة ما تستخدم objdump لتفكيك، وإعادة توجيه الإخراج إلى ملف، ثم طرح الملف في محرر بلدي المفضل - وهذا هو مفيد لحفظ الملاحظات كما وبرزت الامور. أيضا جدب و"معلومات الهدف" و "معلومات sharedlib" يمكن أن تكون مفيدة لمعرفة حيث يتم تحميل مكتبات المشتركة.

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

وقد تكون ايضا قادرة على ربط والتفكيك من الإصدار الأحدث بنيت مع -g ضد التفكيك للنسخة جردت.

  1. دائماً استخدم التحكم بالمصادر (CVS/GIT/Subversion/إلخ)، حتى بالنسبة للإصدارات التجريبية
  2. بطاقة شعار الجميع إطلاق
  3. ضع في اعتبارك (في المستقبل) إنشاء إصدار باستخدام تصحيح الأخطاء (-g) وإزالة الملف القابل للتنفيذ قبل الشحن.ملحوظة:لا تقم بإنشاء نسختين باستخدام وبدون -g؛قد لا يتطابقان، نظرًا لأن -g يمكن أن يتسبب في بعض الأحيان في إنشاء تعليمات برمجية مختلفة حتى على نفس مستوى التحسين.في التعليمات البرمجية ذات الأداء الفائق، يمكنك التخلي عن -g للملفات الهامة - ولن يحدث ذلك فرقًا في أغلب الأحيان.
  4. إذا كنت عالقًا حقًا، فقم بتفريغ المكدس وتفريغ الأجزاء ذات الصلة من الكومة إلى شكل سداسي عشري وانظر إليها يدويًا؛ربما أخذ نسخة مُجهزة والبحث عن "توقيعات" مماثلة في الكود الذي تم إنشاؤه وعلى المكدس.هذا هو حقيقي تصحيح الأخطاء "المدرسة القديمة" ...:-)

هل لديك <م> بالضبط المصدر الذي استخدمته لتجميع النسخة القديمة (على سبيل المثال، من خلال علامة في شجرة المصدر أو شيء من هذا القبيل)؟ ربما يمكن أن إعادة بناء باستخدام ذلك، وربما الحصول على نظرة ثاقبة حيث تحطم حدث؟

وحاول تشغيل "PMAP" ضد ملف الأساسية (إذا حصان / UX ديه هذه الأداة). وينبغي أن يقدم تقريرا عن عناوين تبدأ من كافة الوحدات النمطية في ملف الأساسية. مع هذه المعلومات، يجب أن تكون قادرا على اتخاذ عنوان الموقع الفشل ومعرفة ما مكتبة تحطمت. مقارنة أخرى بين عنوان عنوان تحطم وعناوين وظائف معروفة في المكتبة ( "نانومتر" ضد مكتبة يجب ان تحصل على ذلك) قد تساعدك على تحديد ما ظيفة تحطمت.

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

وليس هناك الكثير من المعلومات هنا. ثنائي هو stripped.But النظر إلى خطأ تجزئة ... يجب ان نبحث عن الأماكن التي يوجد فيها احتمال أن كنت الكتابة فوق قطعة من الذاكرة.

وهذا هو مجرد اقتراح. يمكن أن يكون هناك العديد من المشاكل.

وراجع للشغل، إذا لم تكن قادرا على التكاثر في الجهاز المحلي ثم حجم البيانات على العملاء قد يكون هناك مشكلة.

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

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