تعطل تطبيق C ++ بما في ذلك ADA DLL لا يولد تفريغ أساسي

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

  •  19-09-2019
  •  | 
  •  

سؤال

كيف يمكنني الحصول على تطبيق C ++ بما في ذلك مكتبة ADA محملة ADA لتوليد تفريغ أساسي عند التعطل?

لدي تطبيق C ++ الذي يحمل مكتبة ADA المشتركة، داخل رمز ADA أحصل على خطأ تجاوز سعة مكدس يؤدي إلى إنهاء برنامج جنبا إلى جنب مع إخراج وحدة التحكم:

raised STORAGE ERROR

لا يتم إنشاء ملف تفريغ أساسي حتى أصدرت "Ulimit -C غير محدود" قبل بدء تشغيل التطبيق.

يحدث نفس الشيء إذا أرسلت قتل SIGSEGV. إلى التطبيق.

إرسال قتل SIGSEGV. إلى تطبيق آخر لا يستخدم ADA DLL ينشئ ملف تفريغ أساسي بالطريقة التي أريدها.

وجدت بعض المعلومات هنا: http://objectmix.com/ada/301203-gnat-fstack-check-does-work.html.

محدث! كما ذكرها أدريان، لا يوجد تناقض، يحدد حد المكدس -C. يحدد حد الملف الأساسي.

لا تزال المشكلة لا تزال. راجعت الأعلام عند بناء مكتبة ADA و fstack- check. لم يتم تعيين العلم، لذلك يجب أن تولد تفريغ أساسي.

أنا لم أحاول ذلك بعد، يبدو غريبا إلى حد ما. يذكر خيار التحويل البرمجي -Fstack-check + تعيين متغير GNAT_STACK_LIMIT المتغير GNAT_STACK_LIMIT ولكن في نفس الوقت يشير إلى أمر Ulimit الذي يبدو وكأنه تناقض، إعداد "ulimit -c" هو الطريقة الوحيدة التي أعرفها الحصول على تفريغ أساسي في وقت تعطل، إذا كان هذا ينتشر مع خيار التحقق من FSTACK، فإن لدينا القبض على 22.

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

المحلول

الآن بعد ما يقرب من عامين (لا يزال يعملون في نفس الشركة كما فعل كريسفير عندما سأل السؤال)، كان السؤال الذي أثير مرة أخرى - وأخيرا أعتقد أنني أفهم لماذا لا يتم إنشاء تفريغ أساسي !!

المشكلة ناتجة عن وقت التشغيل ADA، والتي تنفذ بشكل افتراضي معالج إشارة لبعض إشارات Posix (لنظام التشغيل Linux: Sigabrt، Sigfpe، Sigill، Sigsegv و Sigbus). لنات / لينكس يسمى معالج الإشارة __nat_error_handler. في a-init.c., ، والتي تبدو مثل هذا:

static void
__gnat_error_handler (int sig)
{
  struct Exception_Data *exception;
  char *msg;
  static int recurse = 0;
  ...
  switch (sig)
    {
    case SIGSEGV:

      if (recurse)
      {
        exception = &constraint_error;
        msg = "SIGSEGV";
      }
      else
      {
        ...
        msg = "stack overflow (or erroneous memory access)";
        exception = &storage_error;
      }
      break;
     }
    recurse = 0;
    Raise_From_Signal_Handler (exception, msg);
 }

هذا المعالج هو "عملية العرض"، وسيتم استدعاؤها بواسطة أي إشارة مرهقة، بغض النظر عن أي جزء من العملية التي تنشأ من (بغض النظر عما إذا كان مشفوفا في ADA / C / C ++ ...).

عند الاتصال به، يرتفع المعالج استثناءا ADA ويتركه إلى وقت تشغيل ADA للعثور على معالج استثناء مناسب - إذا لم يتم العثور على مثل هذا المعالج (على سبيل المثال، عند إنشاء SIGSEGV بواسطة أي جزء من رمز C ++)، ADA -التوجه مرة أخرى إلى إنهاء العملية فقط وترك مجرد طباعة بسيطة من __nat_error_handler. (على سبيل المثال. "فائض المكدس (أو الوصول إلى الذاكرة الخاطئة)").

http://www2.adacore.com/gap-static/gnat_book/html/node25.htm.

لمنع وقت تشغيل ADA من التعامل مع إشارة بوسيكس، وتحويله إلى استثناء ADA، من الممكن تعطيل Beahviour الافتراضي باستخدام

Pragma Intrupt_state (الاسم => القيمة، الحالة => النظام | وقت التشغيل | المستخدم)؛,

على سبيل المثال لتعطيل التعامل مع SIGSEGV، حدد

Pragma Interrupt_State(SIGSEGV, SYSTEM);

في كود ADA الخاص بك - الآن سيتم توالك السلوك الافتراضي للنظام عند رفع SIGSEGV، وسيتم إنشاء تفريغ أساسي تتيح لك تتبع أصل المشكلة!

أعتقد أن هذه مشكلة مهمة للغاية لتكون على دراية عند خلط ADA و C / C ++ على * منصات NIX-NIX، نظرا لأنها قد تضلل منك أن تعتقد أن المشكلات أصول من رمز ADA (نظرا لأن النسخة المطبوعة تشير إلى استثناء تم إنشاؤه من ADA ) عندما يضع المصدر الحقيقي للمشكلة في رمز C / C ++ ...

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

قد تكون إحدى القضايا هي إشارة SIGPPE، والتي ترفع أيضا عبيدا ADA_Error - استثناء افتراضي. يمكن استخدام هذا النوع من الاستثناء من قبل كود ADA كسلوك "سلوك غير متتالي". قد تؤثر تعطيل SIGFPE بواسطة Pragma Instalupt_state بشكل خطير على تنفيذ رمز ADA، وتعطل طلبك خلال "الظروف العادية" - من ناحية أخرى، سيقوم أي تقسيم عن طريق الصفر في C / C + Code Trig آلية معالجة استثناء ADA، واتركك دون أي أثر حقيقي من أصل المشكلة ...

نصائح أخرى

هذا يبدو لي مثل حقا استخدام جيد لك adacore. الدعم. أنت لست عرضة للعثور على الكثير من الشعبية خارج تلك الشركة التي هي على دراية الآثار المترتبة على التفاعلات بين وقت تشغيل GNU ADA و C ++.

أود أن أقترح تصحيح شفرة ADA التي تحاول وضعها في معالج استثناء أخير حول كل شيء، مما يؤدي إلى مقالب مكدس الاستثناء. معظم البائعين لديهم طريقة للقيام بذلك، وعادة ما يعتمد على ada.excepions.exception_information و Ada.Excepions.exception_Message_Message.

وجدت نقاش من منظور أمني (العثور على البرامج الضارة). أساسا هناك 10 إشارات يمكنك محاولة، SIGSEGV هو واحد فقط منهم.

يبدو أنه يمكنك ببساطة الاتصال sigaction(SIGSEGV, 0, SIG_DFL); لاستعادة سلوك الإشارة الافتراضي.

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