問題タブ [stack-unwinding]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - アンワインド ハンドラーへのアクセス
このようなコードが表示される理由
次のマシンコードを生成します
特に、無条件の後の行につながるパスが表示されませんjmp .L11
(これは最適化なしの GCC 6.2 であり、コンパイラ エクスプローラで生成されます)
比較のために、clang 5.0.0 は生成します。
lea rdi
ここでも、return ブロックへの無条件ジャンプと、到達不能と思われるunwind ブロック (2 番目の から始まる) があります。
c++ - 破壊中にキャッチされたエラーを取得する RAII の方法
ウィキペディアのファイル I/O の RAII の典型的な例では、ファイルを閉じるときに発生するエラーはすべて飲み込まれます。
file
が自動的に閉じられたときにエラーが発生したかどうかを判断する方法がないようです。スコープ内にあるfile.rdstate()
間だけ呼び出すことができるのは明らかです。file
手動で呼び出しfile.close()
てエラーをチェックすることもできますが、スコープから戻るすべての場所でそれを行う必要があり、RAII の目的に反します。
ファイルシステムの破損などの回復不可能なエラーのみがデストラクタ内で発生する可能性があるとコメントしている人もいますが、デストラクタがファイルを閉じる前にファイルをフラッシュし、フラッシュ中に回復可能なエラーが発生する可能性があるため、それは真実ではないと思います。
では、破壊中に発生するエラーを取得するための一般的な RAII の方法はありますか? デストラクタから例外をスローすることは危険であるため、正しいアプローチとは思えません。
私が考えることができる最も簡単な方法は、破壊中にエラーが発生した場合にデストラクタが呼び出すコールバック関数を登録することです。驚いたことに、これが によってサポートされているイベントはないようですios_base::register_callback
。私が何かを誤解していない限り、それは大きな見落としのようです。
しかし、おそらくコールバックは、最新のクラス設計で破棄中にエラーを通知する最も一般的な方法でしょうか?
デストラクタで任意の関数を呼び出すことも危険だと思いますが、おそらく呼び出しをtry/catch
ブロックでラップすることは完全に安全です。
x86-64 - ELF/Linux でスタック/コール フレームの情報チェーンを壊す?
私は本質的にCFI
(DWARF EH 情報の呼び出しフレーム情報) とrbp
フレームrsp
間のリンクを壊す、かなりニッチなことをしようとしています。その主な理由は、スレッド制御フローの特定のポイントを過ぎて、基本的に一方向のテールコールとスタックをクリーンアップしてからスタックの一番上に戻る利回りを組み合わせたコールの継続を実行したいからです。継続ポイントで再度実行する準備ができています。
原則として、スタックを混乱させる行をコメントアウトしておく限り機能します。
SP/BP レジスタの背後にある一般原則を認識しており、具体的には を使用して-fno-omit-frame-pointer
います。私の質問は、それを機能させるために何時間も費やした後、何が欠けているのでしょうか? スタック レイアウトを変更すると、コールの前にスタックを整列させたままプッシュするだけで、次のようなもの (カスタム シグナル ハンドラー) で始まるスノーボール クラッシュが発生するようです。
問題の ABI はlibc++
/ Linuxlibc++abi
でx86_64
、LLVM/Clang 6.0.X ベースのツールチェーンを使用します。私は事実上すべてを試しました。上記が奇妙に見えることはわかっていますが、これはインライン アセンブリの MS 拡張です。完全に正常なコードを生成することを逆アセンブリで何度も確認しました。私が理解している限り、これは CFI とフレーム ポインター ベースのものとの間の奇妙な競合ですが、私はそれほど得意でx86_64
はないので、何が欠けているのかよくわかりません。アンワインド プロセスが番兵 (最後のフレームで SP/FP が null) によって終了されることを意図していることはわかっていますが、この時点で正直に迷っています。
本当にありがたい提案があれば、いろいろ試してみましたが、コアの問題は同じで、スタックに触れるとすぐに、元に戻してもすべてがうまくいきません。最後の呼び出しは慣習的に戻ることを意図していないため、 asm ブロックを超えた clobber は問題ではありません。私が気づいたことの 1 つは、これが何らかの形で TLV に関連しているように見えることですが、NPTL はそれを構成することを意図しているため、どのようにすればよいかわかりません。
助けや提案があれば、私は非常に感謝しています。
編集:
Valgrind からのこのコメントは、何が起こっているのかを説明しているようです: