2016-11-22 4 views
2

は、私はちょうど今(5年)によってかなり古いですスタックトレースにファイル名と行番号を取得するためのポータブル/スタンダードに準拠した方法はありますか?

How to generate a stacktrace when my gcc C++ app crashes

を読みました。いくつかの答えは、スタックフレームごとに関数の名前とオフセット(私が推測するスタック内)を得ることを可能にする解決策を示唆しています。しかし、私が(そして他人が)実際に必要とするのは、呼び出しが行われたソースファイル名と行番号です(コードがデバッグ情報でコンパイルされていると仮定します)。これを行うglibcの一部にリンクされている答えの1つ(libSegfault; this directory - segfault.cbacktracesyms.c、のファイルを参照) - それで可能ですです。

私の質問は以下のとおりです。

  • この情報は、プラットフォームに依存しない方法、またはいくつかの標準(POSIX ??)に準拠して1で抽出することができ
  • はなぜこれをサポートしていませんlibunwindの? (I websiteを見てと思っています)
  • これは、コンパイラのC/C++標準ライブラリ(少なくともC/C++アプリケーションの場合)に依存しますか?

注:あなたがバイナリは、それが-gでコンパイルされたC/C++の場合ので、デバッグ情報をしていると仮定して

  • 。もちろん、適切なライブラリでは、デバッグ情報が利用可能かどうかをチェックします。
+1

いいえ。標準的な方法はありません。 CやC++の言語標準やPOSIX標準では、それを行う方法が規定されていません。 Libunwindはおそらくあなたが得ることができるほどの移植可能性に近いです - 他にもいくつかの匹敵するライブラリがあるかもしれません。そして、はい、プラットフォームに依存します - o/sとコンパイラ。シグナルハンドラのスタックトレースは...面白いことがあります。 –

+0

@JonathanLeffler:しかし、gdbは多くのプラットフォームでそれをやっていませんか? gccでコンパイルされていないバイナリに対しても? – einpoklum

+0

はい、GDBには、プラットフォームによって異なる複雑なコードがあります。行って見てください - それは自明ではありません。これはプラットフォーム用に定義されたABIに対応し、デバッグモデル(Dwarf vs ...)、オブジェクトファイル(および実行可能ファイル)の形式(ELF vs COFF vs ...)などに依存します。 macOSで動作するものはWindowsでは動作せず、どちらもLinuxでは動作しません。それはlibunwindのような図書館が活躍する場です。 –

答えて

2

誰かがこれを行うには、プラットフォームに依存しないライブラリを書き込みしない限り、ない。この情報は、プラットフォームに依存しない方法で抽出することができ、またはいくつかの標準(POSIX ??)に準拠して1

。現時点では、私が知っているようなライブラリはありません。

また、プラットフォームに依存しないで「Windowsでも動作」を意味する場合は、Windows固有のデバッグ形式(PDB)は、ごく最近まで独占的かつ文書化されていませんでした。

なぜlibunwindはこれをサポートしていませんか?誰かが(あなたがボランティア活動している?)、このようなサポートに貢献している場合

libunwindこのをサポートすることができました(私はそれがTHERのウェブサイトを見た後、ないと思います)。しかし、それはおそらくそのサイズの4倍になり、現時点ではが維持されていません。

これは、コンパイラのC/C++標準ライブラリ(少なくともC/C++アプリケーションの場合)に依存しますか?

いいえ、デバッグ形式のみに依存します。書式が文書化されている限り(例:LinuxではDWARF4、WindowsではPDB)、このような形式を解析するライブラリを作成することは可能であり、そのようなライブラリは必ずC++標準ライブラリに依存する必要はありません。

P.S.私はC標準ライブラリへの依存があなたにとって本当の懸念事項ではないと考えています。 Cライブラリとは独立している可能性もありますが、ホイールをlotに再作成する必要があります。そのような理由はありません。

P.P.S.

GDBには複雑なコードがあり、実行するプラットフォームによって異なります。

はい、あなた必要複雑なコード、およびそれはプラットフォームによって異なります。そのコードがGDBにあるのか、libunwindにあるのかは変わりません。

P.P.P.S. lldbもあります。これはライブラリとしてのコードの多くを提供しています(しかし、私は様々なプラットフォーム上でどの程度成熟しているかわかりません)。 EmployedRussianの有効な回答@に追加

+0

私は自由な時間があればボランティアをします。私は以前にいくつかのFOSSをリリースしました...しかし、悲しいかな、そうすることは私の研究を何らかの形で推進するものではないので、私は「仕事の時間」にそれをすることはできません。しかし、PPPSは有望なリードであるべきです。 – einpoklum

2

- これを行い、マルチプラットフォームライブラリ一切ありません。

Boost StackTrace

そして、ちょうどあなたが書くした場合、トレースは、どのようなものか説明する:

#include <boost/stacktrace.hpp> 

// ... somewhere inside the `bar(int)` function that is called recursively: 
std::cout << boost::stacktrace::stacktrace(); 

あなたが(たとえばLinuxの場合)のようなものを得る可能性があります:

0# bar(int) at /path/to/source/file.cpp:70 
1# bar(int) at /path/to/source/file.cpp:70 
2# bar(int) at /path/to/source/file.cpp:70 
3# bar(int) at /path/to/source/file.cpp:70 
4# main at /path/to/main.cpp:93 
5# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6 
6# _start 
関連する問題