Blogとある組み込みエンジニアの備忘録的なブログです。したソースは以下の環境でビルド、動作確認しています。今回実装するスタックトレースの取得方法は、OSやコンパイラといった環境に大きく左右されます。同じOS・コンパイラであってもバージョンによって異なる可能性もありますので、ご了承ください。スタックトレースの取得インタフェースまずは、スタックトレースとして取得する情報をまとめた構造体StackTraceを定義します。symbols;};StackTrace構造体には、トレースした関数のアドレスリスト、関数のアドレスに対応するシンボル(関数)名、トレースした関数の数を保持します。次に、StackTrace構造体を取得するクラスStackTracerを定義します。GetStackTrace();};スタックトレースの取得方法は、OSやコンパイラによって異なるため、ターゲットごとに実装していきます。Windows版Windowsの場合は、ImageHlpライブラリを使うことで、スタックトレースおよび、シンボル情報を取得することが出来ます。Linux版MacやLinuxの場合には、execinfoライブラリを使うことでスタックトレースおよび、シンボル情報を取得することが出来ます。未対応OSの場合は、空のStackTraceを返すようにします。Linux版で取得したシンボル情報は、そのままだと以下のように出力されます(※コンパイラのバージョンなどにより異なる場合があります)。[0x5648b25ab26a]上記のように、そのままのシンボル情報では、関数名に当たる部分が_ZN11StackTracer13GetStackTraceEvといったコンパイラによってマングリング(名前修飾)された状態の名前で出力されます。このままでも分からなくもないですが、デマングルしてより分かりやすい関数名にして出力したいと思います。デマングルを行うライブラリはいくつかあるみたいですが、今回はcxxabi.hライブラリに定義されている、abi::__cxa_demangle関数を用いてデマングルを行います。上記文字列を分解して、以下の情報を取り出します。オブジェクト名マングリングされたシンボル名アドレスアドレスオフセット取り出した情報は、シンボル情報として構造体SymbolInfoに格納することにします。}};シンボル情報をテキストから抽出する関数は、環境ごとに正規表現を使って実装します。symbol_info;}#endif抽出・生成したシンボル情報を元に、シンボルリストに登録する文字列を生成します。その際に、マングリングされたシンボル名をabi::__cxa_demangle関数を使ってデマングルされた関数名に変換します。デマングルに失敗した場合は、マングリングされたシンボル名をそのまま使うようにし、シンボル情報の生成に失敗した場合には、オリジナルのシンボル情報をそのまま返すようにしています。symbol_info_text;}あとは、backtrace_symbols関数で取得したシンボル情報を、上記関数で変換し、シンボルリストに登録するように変更すれば完成です。*/stack_trace.symbols.push_back(symbol_info);StackTracerクラスのソース全文を以下にに示します。stack_trace;}#endif例外処理への組み込みStackTracerクラスを使ったスタックトレース取得処理を、前回作成したAppExceptionクラスに追加してみましょう。__LINE__)コンストラクタ内で、エラーメッセージを生成するために、GenerateErrorMessage関数と、メンバ変数m_ErrorMessageを追加しています。}}上記コードでは、コンストラクタ内でGenerateErrorMessage関数を使ってエラーメッセージを生成し、m_ErrorMessageにセットしています。what関数では、エラー情報(ファイルパスなど)の有無によって、出力するエラーメッセージを切り替えています。GenerateErrorMessage関数では、エラーメッセージ、エラー発生箇所の他に、StackTracerクラスを使ったスタックトレースの取得および、ダンプ処理を追加しています。上記AppExceptionをthrowするとwhat関数からは以下のような情報が出力されます。34行目のTestFunc2関数からAppException例外が発生した事がわかります。TestFunc2と呼ばれたときに例外が発生している事もわかります。あとがき前回と今回で、C++における例外発生箇所やスタックトレースの特定を行う処理を実現できました。ソケットを使ったEthernet通信の実装方法メモです。»プロフィールid:an-embedded-engineerとある組み込みエンジニアの備忘録的なブログです。(1)リンクGitHubcoconalaPieceXアクセス数はてなブログをはじめよう!an-embedded-engineerさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。