كيف يمكنني التقاط SIGSEGV (خطأ تجزئة) والحصول على تتبع المكدس تحت JNI على الروبوت ؟

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

سؤال

انا تتحرك مشروع جديد الأصلي الروبوت تطوير Kit (أيJNI) و أود أن قبض SIGSEGV ، ينبغي أن تحدث (ربما أيضا SIGILL, SIGABRT, SIGFPE) من أجل تقديم لطيفة تحطم التقارير الحوار بدلا من (أو قبل) ما يحدث حاليا:الفوري غير رسمي الموت العملية وربما بعض المحاولات من قبل نظام التشغيل إلى إعادة تشغيله.(تحرير: JVM/Dalvik VM يمسك إشارة سجلات تتبع مكدس وغيرها من المعلومات المفيدة ؛ أريد فقط أن توفر للمستخدم خيار البريد الإلكتروني هذه المعلومات بالنسبة لي حقا.)

الحالة:مجموعة كبيرة من التعليمات البرمجية C والتي لم أكتب لا أكثر من عمل في هذا التطبيق (كل لعبة المنطق) و على الرغم من انها مجربة على العديد من منصات أخرى ، فمن الممكن تماما أن كنت في بلدي الروبوت الميناء ، يطعمه القمامة وتسبب الحادث في التعليمات البرمجية الأصلية ، لذلك أريد الحادث مقالب (كل مواطن جافا) حاليا تظهر في الروبوت سجل (أعتقد أنه سيكون stderr في غير الروبوت الحالة).أنا حر في تعديل كل من C و Java البرمجية بشكل تعسفي ، على الرغم من الاسترجاعات (كل من يدخل و يخرج من JNI) عدد حوالي 40 ومن الواضح نقاط مكافأة صغيرة ديفس.

لقد سمعت من الإشارة إلى تسلسل مكتبة في J2SE, libjsig.حتى و لو كان بإمكاني تثبيت بأمان إشارة معالج مثل هذا على الروبوت, التي من شأنها حل اصطياد جزء من سؤالي ولكني لا نرى مثل هذه المكتبة للحصول على الروبوت/Dalvik.

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

المحلول

تحرير: من هلام الفول فصاعدا لا يمكنك الحصول على تتبع المكدس ، لأن READ_LOGS ذهبت بعيدا. :-(

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

  1. استخدام sigaction() للقبض على إشارات وتخزين القديمة معالجات.(الروبوت.ج:570)
  2. الوقت يمر ، segfault يحدث.
  3. في إشارة معالج الاتصال JNI للمرة الأخيرة ثم اتصل القديم معالج.(الروبوت.ج:528)
  4. في هذا JNI المكالمات, تسجيل أي فائدة تصحيح المعلومات و الاتصال startActivity() على النشاط الذي هو علامة على أنها تحتاج إلى أن تكون في عملية الخاصة به.(SGTPuzzles.java:962, AndroidManifest.xml:28)
  5. عندما كنت أعود من جافا و دعوة القديم معالج أندرويد إطار الاتصال debuggerd تسجيل جميل الأصلية تتبع لك ، ومن ثم فإن العملية سوف يموت.(المصحح.ج, debuggerd.ج)
  6. وفي الوقت نفسه ، تحطم التعامل مع النشاط يتم بدء تشغيل.حقا يجب أن تمر عليه PID حتى أنه يمكن أن تنتظر الخطوة 5 كاملة ؛ أنا لا أفعل هذا.هنا اعتذر المستخدم وأسأل ما إذا كان يمكنك ارسال السجل.إذا كان الأمر كذلك ، وجمع الناتج من logcat -d -v threadtime و إطلاق ACTION_SEND مع مستلم الموضوع و الجسم في شغل.سوف يكون لدى المستخدم اضغط على إرسال.(CrashHandler.java, SGTPuzzles.java:462, سلاسل.xml:41
  7. احترس من logcat الفشل أو أخذ أكثر من بضع ثوان.لقد واجهت جهاز واحد, T-Mobile Pulse / Huawei U8220 ، حيث logcat يذهب على الفور إلى T (تتبع) الدولة وتوقف.(CrashHandler.java:70, سلاسل.xml:51)

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

نصائح أخرى

أنا متأخرا بعض الشيء، لكنني تلقيت نفس الحاجة بالضبط، وقد طورت مكتبة صغيرة لمعالجتها، من خلال اصطياد الأعطال الشائعة (SEGV, SIBGUS, ، إلخ) في الداخل كود JNI, ، واستبدالها بانتظام java.lang.Error استثناءات. وبعد مكافأة، إذا كان العميل يعمل على Android> = 4.1.1, ، تتبع المكدس تضمينها Backtrace. من الحادث (تتبع الزائفة التي تحتوي على تتبع المكدس الأصلي الكامل). لن تتعافى من تعطلات شريرة (أي. إذا كنت تفسد المصلح، على سبيل المثال)، ولكن على الأقل يجب أن يسمح لك بالتعافي منه عظم منهم. (يرجى الإبلاغ عن النجاحات والإخفاقات، والرمز هو العلامة التجارية الجديدة)

مزيد من المعلومات في https://github.com/xroche/coffeecatch.(الرمز هو رخصة BSD 2-Claus)

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

في تجربتي المحدودة (غير الروبوت)، ستعطل SIGSEGV في رمز JNI بشكل عام JVM قبل إرجاع عنصر التحكم إلى رمز Java الخاص بك. أتذكر غامضة الاستماع إلى بعض jvm غير SUN JVM والتي تتيح لك التقاط SIGSEGV، ولكن AFAICR لا يمكنك أن تتوقع أن تكون قادرا على القيام بذلك.

يمكنك محاولة التقاطها في C (انظر التقلص (2))، على الرغم من أنه يمكنك القيام بمعالج SIGSEGV (أو SIGFPE أو SIGILL) حيث أن السلوك المستمر لعملية غير محددة رسميا.

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