問題タブ [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++ - デストラクタから例外をスローするC++
これは、デストラクタから例外をスローしても安全かどうかについての質問ではありません。
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9の状態:
「スタックの巻き戻し中に、これらすべてのスタックフレーム内のすべてのローカルオブジェクトが破棄されます。これらのデストラクタの1つが例外をスローした場合(たとえば、Barオブジェクトをスローした場合)、C++ランタイムシステムは勝てない状況にあります。バーに入れて、} catch(Foo e){に最初に向かった場所に行き着きますか?Fooを無視して、} catch(Bar e){ハンドラーを探す必要がありますか?良い答えはありません。どちらを選択しても情報が失われます。」
IE:スタックの巻き戻し中に別の例外がスローされた場合、「検索」するcatchハンドラーがあいまいであるため、ランタイムシステムは勝てない状況になります。
スタックの巻き戻し中にスローされる例外自体がtry/catchブロックにある場合、上記に「例外」はありますか?この場合、あいまいさはありません。
以下はそれを暗示していますが、関連するC++標準セクションを誰かが知っているかどうか疑問に思いました。
「スタックの巻き戻し中にデストラクタが例外をスローし、その例外が処理されない場合、terminate()関数が呼び出されます。次の例はこれを示しています。」
c - SIGSEGV で _Unwind_Backtrace を使用して fullstacktrace を取得する方法
コードで SIGSEGV を処理します。
ハンドラー コードは次のとおりです。
ただし、trace_func は 1 回だけ呼び出され、_Unwind_Backtrace 呼び出しでのみ表示されます。_Unwind_Backtrace を使用して SIGSEGV シグナルを発生させるコードのスタックトレースを取得することはできますか?
thnx
mips - SIGSEGV の mips _Unwind_Backtrace
Mips プラットフォームで、Unwind を機能させようとしています。現在、print_trace を手動で発行すると、スタック トレースは次のように正しく表示されます。
backtrace_helper 0x4b6958
backtrace_helper 0x4b6ab4
backtrace_helper 0x2ac2f628
スタック フレームを 3 つ取得しました。
./v(print_trace+0x38) [0x4b6958]
./v(メイン+0x90) [0x4b6ab4]
/lib/libc.so.0(__uClibc_main+0x24c) [0x2ac2f628]
しかし、SIGSEGV が発生すると、スタック トレースは正しい関数呼び出しシーケンスを示しません。
backtrace_helper 0x4b7a74
backtrace_helper 0x2ab9b84c
スタック フレームを 2 つ取得しました。
./v(getLineIDByPhyIdx+0x3d8) [0x4b7a74]
/lib/libpthread.so.0(__new_sem_post+0x2c8) [0x2ab9b84c]
-g -fexceptions -rdynamic でコンパイルしています。また、gcc C++ アプリがクラッシュしたときにスタックトレースを生成する方法を見てきました。2 番目の回答で間違ったアドレスについて言及されていますが、彼のように設定しても 2 番目のフレームのみが変更され、残りは同じです。コード スニペットは以下のとおりです。
コード:
php - PHP クラス コンストラクターでのスコープの巻き戻し
私は PHP のクラスと例外を学んでいますが、C++ のバックグラウンドを持っているため、次のことは奇妙に思えます。
派生クラスのコンストラクターが例外をスローすると、基本クラスのデストラクターが自動的に実行されないように見えます。
これは以下を出力します:
一方、メンバー オブジェクトのデストラクタは、コンストラクタ (at ) に例外がある場合は適切に#1
実行されます。ここで疑問に思うのは、例外が発生した場合にサブオブジェクトが適切に破棄されるように、PHP のクラス階層で正しいスコープの巻き戻しを実装するにはどうすればよいかということです。
また、すべてのメンバー オブジェクトが破棄された後(で) 、基本デストラクタを実行する方法がないよう#2
です。つまり、行を削除すると#1
、次のようになります。
その問題をどのように解決しますか?
更新:私はまださらなる貢献を受け付けています。PHPオブジェクトシステムが正しい破棄シーケンスを必要としない理由を誰かが十分に正当化している場合、私はそのために別の報奨金を与えます (または、説得力のある他の答えのために)。
c++ - デストラクタ中に例外がアクティブであるかどうかを検出するにはどうすればよいですか?
C ++では、例外がスローされたためにスタックが巻き戻されているかどうかをデストラクタの本体でどのように検出できますか?検出されたら、アクティブな例外への参照を取得できますか?
特定の状況が発生する理由と、それが例外によるものかどうかを説明するデバッグコードを追加したいので、質問します。
c++ - メイン内で例外がキャッチされない場合、デストラクタが呼び出されないのはなぜですか?
次のコードがあります。
ブロック~Foo()
があるときに実行されるセットが表示されます。try{} catch{}
例外ハンドラがない場合、何も出力されません。例外が処理されるときに、スタック割り当てオブジェクトのデストラクタが呼び出されるということですか? または、std::cerr バッファリングの問題のために何も出力されませんか?
c++ - スタックの巻き戻しのスレッド プロシージャで _endthreadex() を使用するべきではありませんか?
win32環境でのスレッド手続きでのスタック巻き戻しについて調べてみました。
私のテストコードは次のとおりです。
出力結果:
ダミーctor
ダミーctor
ダミーctor ダミー
dtor
割り当て不良
ダミー dtor
ご存じのとおり、コンストラクタとデストラクタの出力は対になっていません。_endthreadex() は、スレッド ハンドルにシグナルを送信し、スレッドのスタック巻き戻しをスキップすると思います。
_endthreadex() なしで再度テストしたところ、期待どおりの結果を得ることができました。
この場合、スレッドでスタックの巻き戻しが必要な場合、スレッド プロシージャで _endthreadex() を使用するべきではありませんか?
c++ - C++ でスタック フレーム全体を巻き戻す方法はありますか? (例外の使用を除く)
私は継続、具体的にはコルーチンのライブラリを書いてきました。これは std::thread に似ています (協調的であることを除いて) - 各実行コンテキストは継続オブジェクトで表されます。
問題は、継続オブジェクトの破棄に関するものです。実行コンテキストが正常に終了していない間に継続オブジェクトの dtor が呼び出された場合、オブジェクトを破棄するコンテキストによって強制的に閉じられる必要があります。
このように、スタック フレーム内のすべての C++ オブジェクトは適切に破棄されません。これは誰にとっても快適な状況ではないかもしれません - そこで私は解決策を見つけることにしました.
最初は例外を使って以下のようにスタックフレームを巻き戻そうと思いました。(以下は欠陥のある疑似コードであることに注意してください。)
ただし、いくつかの重大な欠陥を発見しました。以下のように「例外を飲み込む」ユーザー コードは、協調スケジューリングの前提を完全に破ります。
したがって、スタックの巻き戻しを呼び出す他の方法 (または、継続中のスタック オブジェクトを破棄する他の方法) を見つける必要があります。標準準拠の方法は良いでしょうが、継続の実装自体はプラットフォーム固有の API に依存しているため、移植性のない方法も受け入れられます。(私はwin32を使用しています)
c# - x64 と x32 での異なる動作のアンワインド スタック
以下に詳述するシナリオで、同一コードの x64 ではスタック領域が増加するのに、x32 では減少するのはなぜですか?
バックグラウンド:
お客様は、実行時に再帰的手法を使用して解釈され、Web サーバーで実行されるドメイン言語でスクリプトを作成できます。例外をスローするスクリプトで間違いを犯す可能性があります。この例外はキャッチされ、ログに記録されます。
この再帰的な手法により、インタプリタがスクリプトを実行するときに使用されるスタック スペースをチェックし、実際にスタックが不足する前にスクリプトを終了することで、スタック オーバーフローの例外を防ぎます。
32 ビット モードでは、スクリプト作成者がエラーException
を生成し、それがログに記録されると、すべてが正常に機能し、スタックに残されたスペースが増加し、スクリプトが正常に終了する間にスタックが巻き戻されます。
64 ビット モードでは、すべてがあまり良くありません。スクリプタがエラーを生成すると、エラーがログに記録され、スタックの残りのスペースが減少するException
間にスタックが巻き戻されます。これは非常に悪いことです。スクリプトがたまたま多くのスタック スペースを使用してスローした場合、スタックをアンワインドしてエラーをログに記録する行為によって、元の例外が隠蔽され、IIS がホース処理され、すべてが強制終了される可能性があるためです。機内リクエスト (悪い、非常に悪い、本当に本当に悪い)。StackOverflowException
問題の再現:
これは、私が本番環境で使用するコードをモデル化し、x64 に設定すると問題を再現し、x32 で正常に動作するコンソール アプリです。
出力例:
x32 - すべてがダンディです。スタック スペースはホイストの下降時に減少し、巻き戻し中に増加します。
以下は、x64 でのまったく同じコードの出力です。スタック スペースは下降中に増加しますが、巻き戻し中に減少し続けます。
不思議なことに、「Catch」を削除すると、64ビット以下でスタックが同じように使用されますが、キャッチでログを記録する必要があるため、製品でこれを行うことはできません。
signals - hpux _UNW_STACK_TRACEスタックアンワインド機能のシグナルセーフバージョンはありますか?
むしろ奇妙なことに、hpux unwind API _UNW_STACK_TRACEはファイル記述子を取りませんが、代わりに。を取りますFILE*
。新しいAPIuwx_stack_trace
も。を取りますFILE*
。
これらの両方がバッファリングされたIOを使用し、(シグナルセーフIOインターフェイス)//をopen
使用しない場合write
、close
これらはどちらもシグナルハンドラー(最も明白な場所の1つ)で安全に使用できません。
私たちの(おそらく今は死んでいる)ia64プラットフォームの1つで、かつては独自のアンワインド実装がありましたが、維持するのは野獣であり、不安定だったので、そのルートを再び下りたくありません。HPUXスタックアンワインドの他のオプションはありますか?