كيف يقوم خيار تصحيح الأخطاء -g بتغيير الملف الثنائي القابل للتنفيذ؟

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

  •  01-07-2019
  •  | 
  •  

سؤال

عند كتابة كود C/C++، من أجل تصحيح أخطاء الملف الثنائي القابل للتنفيذ، يجب تمكين خيار التصحيح على المترجم/الرابط.في حالة دول مجلس التعاون الخليجي، الخيار هو -g.عندما يتم تمكين خيار التصحيح، كيف يؤثر ذلك على الملف الثنائي القابل للتنفيذ؟ما هي البيانات الإضافية المخزنة في الملف والتي تسمح بوظيفة مصحح الأخطاء كما تفعل؟

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

المحلول

-g يخبر المترجم بتخزين معلومات جدول الرموز في الملف القابل للتنفيذ.ومن بين أمور أخرى، وهذا يشمل:

  • أسماء الرمز
  • اكتب معلومات عن الرموز
  • الملفات وأرقام الأسطر التي جاءت منها الرموز

يستخدم مصححو الأخطاء هذه المعلومات لإخراج أسماء ذات معنى للرموز ولربط التعليمات بسطور معينة في المصدر.

بالنسبة لبعض المترجمين، سيؤدي توفير -g إلى تعطيل بعض التحسينات.على سبيل المثال، تقوم icc بتعيين مستوى التحسين الافتراضي إلى -O0 مع -g إلا إذا قمت بالإشارة بوضوح إلى -O[123].أيضًا، حتى إذا قمت بتوريد -O[123]، فإن التحسينات التي تمنع تتبع المكدس ستظل معطلة (على سبيل المثال.تجريد مؤشرات الإطار من إطارات المكدس.وهذا له تأثير طفيف فقط على الأداء).

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

لمزيد من المعلومات، نلقي نظرة على قزم, ، تنسيق تصحيح الأخطاء المصمم في الأصل للتوافق مع ELF (التنسيق الثنائي لنظام التشغيل Linux وأنظمة التشغيل الأخرى).

نصائح أخرى

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

بالإضافة إلى معلومات التصحيح والرمز
Google DWARF (نكتة المطورين على ELF)

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

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

تحقق من وثائق المترجم الخاص بك لمزيد من المعلومات:
لكن مثال DevStudio هو:

  • 0xCDCDCDCD تم تخصيصه في الكومة، ولكن لم تتم تهيئته
  • 0xDDDDDDDD تم تحرير ذاكرة الكومة.
  • يتم وضع أسوار 0xFDFDFDFD "NoMansLand" تلقائيًا على حدود ذاكرة الكومة.لا ينبغي أبدا أن يتم الكتابة فوقها.إذا قمت بالكتابة فوق واحدة، فمن المحتمل أنك تبتعد عن نهاية المصفوفة.
  • 0xCCCCCCCC مخصص على المكدس، ولكن لم تتم تهيئته

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

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

هناك بعض التداخل مع هذا سؤال الذي يغطي القضية من الجانب الآخر.

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

بعض أنظمة التشغيل (مثل ض/OS) إنتاج "ملف جانبي" يحتوي على رموز التصحيح.وهذا يساعد على تجنب تضخم الملف القابل للتنفيذ بمعلومات إضافية.

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