9

デバッグ目的で、Android NDK アプリで SIGSEGV などのシグナルをキャッチしようとしています。そのために、sigaction という名前の sigaction をセットアップしました。

私は今、呼び出しのスタックを取得しようとしています。問題は、_Unwind_Backtrace現在のスタックでのみ機能し、sigaction が独自のスタック内で実行されることです。

では、シグナルを受信した実行ポインタのスタックを取得する方法はありますか? (基本的_Unwind_Backtraceに、現在のスタックとは別のスタックを巻き戻すように指示しますか?)

私はそれを指摘する必要があります:

  • これらの関数は Android NDK で提供されていないため、backtrace()とを使用することはできません。backtrace_symbols()

  • GDB を使用して、ローカル デバイスのクラッシュを調査しています。私は GDB を置き換えたくありません。クライアントにテスト ビルドを送信したときに、意味のあるスタック トレースをクライアントから受信できるようにしたいのです。

編集: fadden によって提案されたシステム/コアから Android の libcorkscrew を使用しようとしましたが、unwind_backtrace_signal_arch 関数を使用すると、クラッシュを表さない奇妙なバックトレースが発生します。

4

3 に答える 3

3

私の実践では、標準の _Unwind_Backtrace は信号前スタックへの切り替えに失敗しました。

内部 libgcc __gnu_Unwind_Backtrace を呼び出して、シグナル前のスタックをいくつか取得することができました。「現在のレジストリ値」という追加の引数があるため、現在のスタックではなく、特定のスタックで動作します。

//definitions copied from arm-specific libgcc 4.8 sources.
struct core_regs
{
  _uw r[16];
};

typedef struct
{
  _uw demand_save_flags;
  struct core_regs core;
} phase2_vrs;

extern "C"
_Unwind_Reason_Code
__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
               phase2_vrs * entry_vrs);

// Getting backtrace with those definitions
//istead of _Unwind_Backtrace(tracer, &state);
if (const ucontext_t* signal_context = last_sigaction_parameter)
{
      phase2_vrs pre_signal_state = {};
      pre_signal_state.core = *reinterpret_cast<const core_regs*>(&(signal_context->uc_mcontext.arm_r0));
      __gnu_Unwind_Backtrace(tracer, &state, &pre_signal_state);
}
于 2015-05-28T19:41:58.033 に答える