سؤال

في إم إس في سي، تصحيح الأخطاء () أو __debugbreak يتسبب في كسر المصحح.على نظام التشغيل x86، يعادل ذلك كتابة "_asm int 3"، أما على نظام التشغيل x64 فهو شيء مختلف.عند التحويل البرمجي باستخدام gcc (أو أي مترجم قياسي آخر) أريد إجراء اقتحام لمصحح الأخطاء أيضًا.هل هناك وظيفة مستقلة للمنصة أم جوهرية؟رأيت سؤال اكس كود حول ذلك، ولكن لا يبدو أنه محمول بما فيه الكفاية.

ملاحظة جانبية:أريد بشكل أساسي تنفيذ ASSERT مع ذلك، وأدرك أنه يمكنني استخدام التأكيد () لذلك، ولكنني أريد أيضًا كتابة DEBUG_BREAK أو أي شيء آخر في الكود.

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

المحلول

وماذا عن تحديد ماكرو المشروط على أساس #IFDEF التي تتسع ليبني المختلفة استنادا إلى البنية الحالية أو منصة.

وشيء من هذا القبيل:

#ifdef _MSC_VER
#define DEBUG_BREAK __debugbreak()
#else
...
#endif

وسوف يتم توسيع هذا من قبل المعالج الصحيح تعليمات كسر المصحح تعتمد على منصة حيث يتم ترجمة التعليمات البرمجية. وبهذه الطريقة يمكنك دائما استخدام DEBUG_BREAK في التعليمات البرمجية.

نصائح أخرى

وهناك طريقة التي هو محمول على معظم أنظمة POSIX هو:

raise(SIGTRAP);

ودول مجلس التعاون الخليجي لديه وظيفة مدمج اسمه __builtin_trap التي تستطيع أن ترى <لأ href = "http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005ftrap-2760 "يختلط =" noreferrer "> هنا ، ومع ذلك فمن المفترض أن يوقف تنفيذ التعليمات البرمجية مرة واحدة يتم التوصل إلى ذلك.

ولكم <م> يجب ضمان أن الدعوة __builtin_trap() مشروطة، وإلا سوف تنبعث أية تعليمات برمجية بعد ذلك.

وهذا المنصب يغذيه كل 5 دقائق من الاختبار، YMMV.

وهذا يبدو وكأنه مكتبة المتوافق https://github.com/scottt/debugbreak

أضفت للتو وحدة نمطية ل المقتطفات المحمولة (مجموعة من مقتطفات المجال العام من التعليمات البرمجية المحمولة) للقيام بذلك.إنها ليست محمولة بنسبة 100%، ولكن يجب أن تكون قوية جدًا:

  • __builtin_debugtrap بالنسبة لبعض إصدارات clang (المحددة بـ __has_builtin(__builtin_debugtrap))
  • على MSVC وIntel C/C++ Compiler: __debugbreak
  • بالنسبة للمترجم ARM C/C++: __breakpoint(42)
  • بالنسبة إلى x86/x86_64، التجميع: int $03
  • بالنسبة لإبهام ARM، التجميع: .inst 0xde01
  • بالنسبة إلى ARM AArch64، التجميع: .inst 0xd4200000
  • بالنسبة لـ ARM الأخرى، التجميع: .inst 0xe7f001f0
  • بالنسبة إلى ألفا، التجميع: bpt
  • بالنسبة إلى C غير المستضاف مع دول مجلس التعاون الخليجي (أو أي شيء يتنكر باسمه)، __builtin_trap
  • وإلا تشمل signal.h و
    • لو defined(SIGTRAP) (أي بوسيكس)، raise(SIGTRAP)
    • خلاف ذلك، raise(SIGABRT)

في المستقبل، قد تتوسع الوحدة النمطية الموجودة في المقتطفات المحمولة لتشمل منطقًا آخر، وربما سأنسى تحديث هذه الإجابة، لذا يجب عليك البحث هناك عن التحديثات.إنه مجال عام (CC0)، لذا لا تتردد في سرقة الكود.

إذا كنت تنظر تأكيد (خ) المحمولة بما فيه الكفاية، تأكيد (كاذبة) ويبدو أن الحل المحمولة واضح للمشكلة.

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

http://www.cplusplus.com/reference/cstdlib/abort/

وبدلا من استخدام فواصل التصحيح "العادية"، لماذا لا تستخدم أحد الخيارات التالية، مثل القسمة على صفر:

int iCrash = 13 / 0;

وأو dereference مؤشر NULL:

BYTE bCrash = *(BYTE *)(NULL);

وعلى الأقل هذا هو تزوجنا المحمولة العديد من المنصات / أبنية.

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

#define __debugbreak() \
do \
{       static bool b; \
        while (!b) \
                sleep(1); \
        b = false; \
} while (false)

عند ينامون هذه العملية، يمكن إرفاق المصحح لهذه العملية، تغيير المتغير b للخروج من حلقة وبدورك. هذا الرمز قد لا تعمل في بناء الأمثل!

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