C機能の実行を中断し、C ++発信者に戻る
-
30-09-2019 - |
質問
現在、次の構成を使用して次のシナリオを実装するのに問題があります:GCC 3.4、Linux。
共有ライブラリ(Cで書かれた)をロードするツール(C ++)を書きました。このライブラリには、私が修正するために影響を与えることができないバグがあります。問題は、いくつかの入力を読み取り、デコードされた出力を書き込むことです。入力が間違っている場合、チェックを行わずにこのライブラリが次のメモリ領域のデコードを開始します。それはsegfaultを引き起こします。
当初、私のアイデアは、入力をページメモリ(Linux MMap-Syscall)に入れ、最後のページを保護(mprotect)することでした。独自のsigsegvハンドラーをインストールすることにより、私のc ++ - アプリは例外をスローできます(GCCフラグ-fnon-call-exceptionsでコンパイルされた場合)。この例外は、C LIBの読み取りを中断します。私は、このLIBがスタック不動産中に失われる可能性のあるメモリ(または他のリソース)を割り当てないことを知っていました。シナリオ全体は、すべてが単一のC ++アプリであった私のユニットテストでは正常に機能しました。しかし、libのcコードが私のアプリと呼ばれるとき、私のアプリが終了するだけです...このc-soを-fnon-call-exceptionsフラグで再構築する必要がありますか?このLIBをコンパイルすることはできませんが、OBJファイルのみにアクセスできるため、再リンクするだけです。
これが実行環境の写真です:
+------------C++ APP----------+
| |
| Install SIGSEGV handler |
| code calling C SO functions |
| |
| +----------C SO Functions------------+
| | execute producing SIGSEGV |
| +------------------------------------+
| |
| SIGSEGV Handler called |
| => throw Exception |
| to stop execution of |
| C function |
+-----------------------------+
他の提案は大歓迎です。
どうもありがとう、
卵子
PS私はいくつかの提案と批評家を見ますが、それらはすべてオプチンではありません。その理由は次のとおりです。ライブラリにリンクできるインターフェイスが1つしかありません。ライブラリは、データ構造をデコードするために使用されます。問題は、長さ-1の配列がある場合、ライブラリが長さ0xffffffの配列(32ビットシステム)のデコードを開始することです。私の意見では、LIBが別のプロセスでクラッシュするまで待つことは選択肢ではありません。まず第一に、デコードは一方で考慮すべき時間をかけ、もう片方に大量のゴミを生成します。私のツールは、デコードされた出力をユーザーに確実に表示する必要があるためです。そして、彼らはまだ痕跡を理解できる必要があります。
ここでは、sigsegvを回避するポイントはわかりません。まず、ライブラリはデータを読み取り、以前に渡したファイルハンドルに書き込みます。そのハンドルに書き込み方法を構成できます(バッファリングかどうか)。さらに、ヒープデータやリソースを割り当てないことを正確に知っています。そして最後に、そのようなエラーを回避するために私のアプリが保護したメモリにアクセスしようとします。ユーザーの観点からは、誰かに伝えることはできません。申し訳ありませんが、バイナリトレースは半分しか解読できませんでした。一部のデータが矛盾していたためです。私はこのデータが不可欠であることを知っており、この矛盾に対処する方法を正確に知っています。だから私は優雅に回復することができます。 SigsetJmp/Siglongjmp Posix関数を使用して、例外としてより良いことをすることを願っています。実際、setjmp/longjmpまたはsigsetjmp/siglongjmpのいずれかを使用して例外を実装しています。
はい、アプリケーションをデバッグして、コールスタックが有効であることがわかります。
解決 3
OKみんな、
sigsetjmp/siglongjmpでやった。魅力のように機能します。関数を発信者関数のスタックに飛び越えて、そこでエラー処理を行うことができます。
すべての提案をありがとう。
よろしくお願いします、
卵子
他のヒント
残念ながら、述べたように問題に対する答えはありません - デバッガーの下でアプリケーションを実行して、正確に終了する場所を確認しましたか?
ただし、私の頭に浮かぶ別のアプローチは、故障したライブラリの使用を別のプログラムに入れ、アプリから起動し、パイプ経由でデータを渡すことです。
これは愚かな質問かもしれませんが、コアファイルを調べる必要がありますか?または、デバッガーでアプリケーションを実行しますか?