web-dev-qa-db-ja.com

-funwind-tablesを使用してコンパイルすると、正確にはどうなりますか?

差出人: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

_-fexceptions_:例外処理を有効にします。例外の伝播に必要な追加のコードを生成します。一部のターゲットでは、これはGCCがすべての関数のフレーム巻き戻し情報を生成することを意味します。

_-funwind-tables__-fexceptions_に似ていますが、必要な静的データを生成するだけで、生成されたコードには影響しません他の方法。通常、このオプションを有効にする必要はありません。代わりに、この処理を必要とする言語プロセッサがユーザーに代わって有効にします。

誰かが_-funwind-tables_から、「必要な静的データ」の意味を説明できますか?彼らが参照しているデータ。そして、なぜデータを生成する必要があるのですか?そのデータが生成されない場合はどうなりますか?そのデータはどこで使用されますか?

また、「_-fexception_と同様」とも表示されます。そのため、フレームの巻き戻し情報も生成されると思います。フレーム巻き戻し情報とは何ですか?フレーム情報は誰がどのように使用しますか?

一部のSOの投稿では、__Unwind_Backtrace_がこのフラグを使用してプログラムをコンパイルする必要があると正しく動作する必要があることを読みました。__Unwind_Backtrace_が生成した情報を使用する方法を説明してください_-funwind-tables_。

19
Pendyala

_-funwind-tables_オプションで言及されている静的データは、フレームの巻き戻し情報、つまり、実行中のプログラムが特定の実行ポイントから関数呼び出しスタックをウォークバックできるようにするデータです。関数呼び出しスタックを後退することは、呼び出された関数の実行コンテキストから呼び出し元のコンテキストに移動することを意味します。つまり、return関数を除きます。ただし、フレーム巻き戻し情報を使用すると、関数の本体内の任意のポイントからそれを実行できます。また、呼び出された関数を実際に終了する必要はありません。呼び出し側コンテキスト内で単に「ピーク」する(たとえば、呼び出された関数が呼び出された場所を取得する)こともできますが、再帰的に、通常の実行フローを呼び出された関数。

上記を実行できるようにするには、プログラムが「通常の」実行フローに従うために厳密に必要なものよりも多くのコンパイル済みコードに関する情報にアクセスできる必要があります。この情報(つまり、フレームの巻き戻し情報)は、リンカによって特別なリンカセクション(x86プラットフォームの場合は.eh_frameセクション、ARMプラットフォームの場合はARM.exidxセクションと.ARM.extabセクションに配置されます。 )その目的のために専用。これらのリンカーセクションは、C++などの言語で例外処理を実装するために必要なものと同じです。例外がスローされた結果、実行フローが呼び出された関数からその呼び出し元にジャンプする場合があります。 _-fno-unwind-tables_オプションを使用してこのデータの生成を無効にすると、関数呼び出しスタックをウォークバックしたり、C++例外を使用したりできなくなります。

特に、フレーム巻き戻し情報は、バックトレースの生成、コールスタック内の任意のポイントへのジャンプなどをサポートするクロスプラットフォームライブラリ libunwind によって使用されます。

_Unwind_Backtrace()は、GCCコアライブラリ(より具体的にはlibgcc_s)に実装されている関数で、コールスタック内の各フレームに対してコールバック関数(引数として指定)を実行できます(つまり、呼び出し元の関数のコンテキストから開始) 、呼び出し元への移動など。 https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib--unwind-backtrace.html を参照してください。繰り返しになりますが、この機能を実行するには、適切なリンカーセクションからフレームの巻き戻し情報にアクセスする必要があります。

8
Francesco Lavra