2017-12-21 24 views
0

私はAndroidネイティブのC++コードを持っています。しかし、バックグラウンドとバックにアプリを送ったときに、それはSIGSEGVでクラッシュすることがあります。私自身のシグナル処理とスタックトレースを使ってデバッグしたいのですが、このエラーが発生すると、シグナル処理がまったくトリガされません。 JNI_OnLoad方法にAndroid - JNI/NDK - SIGSEVによるクラッシュ - シグナル処理が開始されない

、私が追加しました:

struct sigaction sighandler; 
memset (&sighandler, '\0', sizeof(sighandler)); 
sighandler.sa_sigaction = &android_sigaction; 
sighandler.sa_flags = SA_SIGINFO; 

int watched_signals[] = { SIGABRT, SIGILL, SIGSEGV, SIGINT, SIGKILL }; 
for(int signal : watched_signals) 
{ 
    sigaction(signal, &sighandler, &old_sa[signal]); 
} 

そして、私が持っている:

static struct sigaction old_sa[NSIG]; 

static void android_sigaction(int signal, siginfo_t *siginfo, void *context) 
{ 
    MY_LOG("Sending PID: %ld, UID: %ld\n", (long)siginfo->si_pid, (long)siginfo->si_uid); 

    old_sa[signal].sa_handler(signal); 
} 

アプリがバックグラウンドからなるときしかし、android_sigactionは、エラーのためにtrigerredされることはありません。私はコード内でバグを作成しようとしましたが(配列の範囲外に書く)、ボタンを押してトリガーし、コールバックが正しく呼び出されました。 何が起こっていますか?

答えて

1

Android 5.0以降のデバイスを使用していると仮定すると、問題はARTによって発生する可能性があります。自分自身のsignal()sigaction()を公開しているので、信号を盗んで他の場所に渡す機会があります。

for(int signal : watched_signals) 
{ 
    syscall(_NR_sigaction, signal, &sighandler, &old_sa[signal]); 
} 

だから今、あなたのハンドラがカーネルにとARTがそれを変更しないでください直接行く:あなたは、直接システムコールを試みることができるデバッグ目的のために 。 もちろん、デバッグだけでOKです。これをプロダクトのために使いたい場合は、以前のハンドラを尊重するロジックを開発する必要があります。

P.S.戻り値もチェックして、errnoも良い考えです。

+0

@Segio _NR_sigactionとは何ですか? –

+0

'sigaction'に対応するsyscal番号です。それを取得するには ''をインクルードしてください。 – Sergio

+1

オクラホマ...それは助けましたが、私は1つの希少な "__NR_sigaction" –

関連する問題