Linux で NULL ポインター アクセスを C++ 例外に変換する方法はありますか? Java の NullPointerException に似たもの。クラッシュする代わりに、次のプログラムが正常に返されることを願っています (コンパイル時にコンパイラがこの NULL ポインター アクセスを把握できないと仮定します)。
class NullPointerException {};
void accessNullPointer(char* ptr) {
*ptr = 0;
}
int main() {
try {
accessNullPointer(0);
} catch (NullPointerException&) {
return 1;
}
return 0;
}
C ++でのNULLポインターアクセスは未定義の動作であるため、標準的な方法は期待していません。x86_64 Linux / GCCでそれを行う方法を知りたいだけです。
私はこれについて非常に原始的な研究を行いましたが、可能かもしれません:
- Linux で NULL ポインタがアクセスされると、SIGSEGV が生成されます。
- SIGSEGV ハンドラ内では、プログラムのメモリとレジスタ情報が利用可能です (
sigaction()
シグナルハンドラの登録に使用されている場合)。プログラムを逆アセンブルすると、SIGSEGV の原因となった命令も使用できます。 - プログラムのメモリやレジスタを変更し、例外インスタンスを作成/偽造します (おそらく、_Unwind_RaiseException などの低レベルのアンワインド ライブラリ関数を呼び出すことによって)。
- 最後にシグナル ハンドラーから戻ります。通常の例外がスローされたように、プログラムが C++ スタックの巻き戻しプロセスを開始することを願っています。
以下は、GCC のマニュアル ページ (-fnon-call-exceptions) からの引用です。
トラップ命令が例外をスローできるようにするコードを生成します。これには、どこにも存在しないプラットフォーム固有のランタイム サポートが必要であることに注意してください。さらに、トラッピング命令のみが例外をスローすることを許可します。つまり、メモリ参照または浮動小数点命令です。「SIGALRM」などの任意のシグナルハンドラから例外をスローすることはできません。
この「プラットフォーム固有のランタイム」はまさに私が望んでいるもののようです。Linux/x86_64 のそのようなランタイムを知っている人はいますか? または、そのようなランタイムがまだ存在しない場合に、そのようなランタイムを実装する方法に関する情報を教えてください。
ソリューションがマルチスレッドプログラムでも機能することを望みます。