私は移植したいライブラリを書いています。したがって、glibcやMicrosoftの拡張機能や標準にないその他のものに依存してはいけません。私はstd :: exceptionから派生したクラスの素敵な階層を持っており、ロジックと入力のエラーを処理するために使用しています。特定の種類の例外が特定のファイルと行番号でスローされたことがわかっていますが、実行結果がどのようになっているのかが分かっていると、潜在的にはもっと重要なことになるので、スタックトレースを取得する方法を検討しています。例外のポータブルC++スタックトレース
私は(question 126450を参照)execinfo.h内の関数を使用してglibcのに対して構築(question 76822を参照)、MicrosoftのC++実装でStackWalkインタフェースを介したときに、このデータが利用可能であることを承知していますが、私は非常に多くのものを避けたいですポータブルではありません。
私はこのフォームでこの機能を実装する自分の考えていた:
class myException : public std::exception
{
public:
...
void AddCall(std::string s)
{ m_vCallStack.push_back(s); }
std::string ToStr() const
{
std::string l_sRet = "";
...
l_sRet += "Call stack:\n";
for(int i = 0; i < m_vCallStack.size(); i++)
l_sRet += " " + m_vCallStack[i] + "\n";
...
return l_sRet;
}
private:
...
std::vector<std::string> m_vCallStack;
};
ret_type some_function(param_1, param_2, param_3)
{
try
{
...
}
catch(myException e)
{
e.AddCall("some_function(" + param_1 + ", " + param_2 + ", " + param_3 + ")");
throw e;
}
}
int main(int argc, char * argv[])
{
try
{
...
}
catch (myException e)
{
std::cerr << "Caught exception: \n" << e.ToStr();
return 1;
}
return 0;
}
これはひどいアイデアですか?これは、すべての機能にtry/catchブロックを追加する作業がたくさんあることを意味しますが、私はそのことで暮らすことができます。例外の原因がメモリ破損またはメモリ不足の場合は動作しませんが、その時点ではどうにかなります。スタック内のいくつかの関数が例外をキャッチしてリストに追加して再スローしないと、誤った情報が得られるかもしれませんが、少なくとも私のライブラリ関数のすべてがそのように機能することを保証することはできます。 "実際の"スタックトレースとは異なり、私は関数を呼び出す際に行番号を取得しませんが、少なくとも私は何かを持っています。
私の最大の関心事は、この例外が実際にスローされていなくても景気減速の原因となる可能性があります。これらのtry/catchブロックはすべて、各関数の呼び出し時に追加のセットアップと分解が必要ですか、あるいはコンパイル時に何とか処理されますか?それとも私が考えていない他の問題はありますか?
別の見通しについては、Herb Sutterのhttp://www.gotw.ca/gotw/047.htmをご覧ください。 – AJG85