如何使c++像python一样给出详细的异常信息
How to make C++ give detailed exception information just like python does?
使用python,当发生异常时,即使没有捕获,我也可以获得有关哪个文件引发错误的详细信息:
def hello():
raise Exception;
hello()
Execution result >>
Traceback (most recent call last):
File "exceptionExample.py", line 4, in <module>
hello()
File "exceptionExample.py", line 2, in hello
raise Exception;
Exception
对于c++,这些信息不是那么有用:
#include <iostream>
using namespace std;
class Error
{
};
int value()
{
throw Error();
}
int main(int argc, char *argv[]) {
value();
}
>>
terminate called after throwing an instance of 'Error'
Run Command: line 1: 52772 Abort trap: 6 ./"$2" "${@:3}"
我如何使c++给出更详细的信息,关于哪个模块引发了错误,从哪一行?
您可以在异常消息中使用__FILE__
和__LINE__
定义。
#include <stdexcept>
class Error : public std::runtime_error
{
public:
Error (const std::string &message)
: std::runtime_error(message)
{}
};
int value()
{
std::stringstream ss;
ss << "Issues at " << __FILE__ << " on line " << __LINE__;
throw Error(ss.str());
}
在这个例子中,我使Error
继承自std::runtime_error
(它有一个构造函数,允许您将消息作为字符串传递)…
另外,看看这个SO问题:全局异常处理——注意关于使用set_terminate
函数的答案。这将允许您安装一个全局处理程序,以确保按需要打印消息。下面是关于set_terminate()的一些信息。
Python为未捕获的异常提供堆栈跟踪。我提供的答案只告诉您文件和行号。如果您需要堆栈跟踪,一些评论者参考了其他一些SO问题,这些问题给出了如何在c++中做到这一点的建议。但是,要注意这个问题的非标准解决方案。
您可以创建异常,以便在创建异常时包装堆栈跟踪。但是,请注意只在调试模式下记录此日志,因为日志堆栈跟踪可能是一个安全问题。
还可以使用调试器。
没有可移植的方法来获取堆栈跟踪,一个技巧是在函数上下文中使用对象来保存信息
struct StackTraceInfo {
const char *filename;
int line;
static std::vector<StackTraceInfo *> stack;
StackTraceInfo(const char *filename, int line) :
filename(filename), line(line)
{
stack.push_back(this);
}
~StackTraceInfo()
{
stack.pop_back();
}
};
#define ENTER StackTraceInfo(__FILE__, __LINE__) sinfo_;
在每个函数中只在body的最开始添加一行ENTER
int foo() {
ENTER
....
return 42;
}
在抛出异常的情况下,您需要使用全局StackTraceInfo::stack
向量的内容保存当前堆栈跟踪,以便显示消息的人可以访问该信息。请注意,您无法访问异常处理程序中的堆栈信息,因为此时堆栈已经展开。
还要注意,如果你的应用程序是多线程的,你需要为每个线程使用单独的堆栈,使用局部存储而不是全局存储。
使用标准c++ 11可以获得与Python回溯非常相似的东西,使用:
std::nested_exception
和std::throw_with_nested
在这里和这里的StackOverflow中描述了如何在不需要调试器或繁琐的日志记录的情况下对代码中的异常进行反跟踪,只需编写一个适当的异常处理程序即可重新抛出嵌套异常。
注意,你必须包装所有的函数,你想出现在你的try/catch
的回溯,你需要非标准宏(__FILE__
, __func__
, __LINE__
)自动添加源位置信息。
由于您可以对任何派生异常类执行此操作,因此您可以向此类回溯中添加大量信息!你也可以看看我在GitHub上的MWE或我的"trace"库,其中的反向跟踪看起来像这样:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
- VisualC++ 2010 有没有办法找出有关未处理异常错误的更多详细信息
- CPP 异常获取抛出调用方的详细信息
- 为什么重新抛出异常会丢弃"what()"给出的信息?
- 如何将有关最顶层调用/上下文的信息添加到异常
- 在进程外使用MiniDumpWriteDump时,如何获取异常信息
- 我如何从boost ::异常获得更好的诊断信息
- 提升异常的错误信息
- 我可以复制构造一个带有错误信息的提升::异常吗?
- 如何在不同的上下文(例如线程)中保留原始异常类型信息
- 从用catch(..)捕获的异常中获取一些信息
- 堆栈异常处理和析构函数展开.如何使用这些信息
- 异常是否可以自动提供有关其环境的详细信息
- 捕获所有异常并记录信息
- 如何从谷歌测试中的异常中获取回溯信息
- 如何在'catch(...)'中获取异常信息
- 如何使用boost异常将信息添加到std::异常中
- cpp:用省略号捕获异常并查看信息
- 如何获取有关混合应用程序中缓冲区溢出异常的信息
- 调试异常,源信息丢失
- 如何使c++像python一样给出详细的异常信息