相关疑难解决方法(0)

我的程序崩溃时如何自动生成堆栈跟踪

我正在使用GCC编译器在Linux上工作.当我的C++程序崩溃时,我希望它能自动生成一个堆栈跟踪.

我的程序由许多不同的用户运行,它也可以在Linux,Windows和Macintosh上运行(所有版本都使用编译gcc).

我希望我的程序能够在崩溃时生成堆栈跟踪,并且在用户下次运行它时,它会询问他们是否可以将堆栈跟踪发送给我,以便我可以追踪问题.我可以处理向我发送信息,但我不知道如何生成跟踪字符串.有任何想法吗?

c++ crash gcc assert stack-trace

561
推荐指数
20
解决办法
33万
查看次数

用C或C++打印调用堆栈

有没有办法在每次调用某个函数时在C或C++中正在运行的进程中转储调用堆栈?我的想法是这样的:

void foo()
{
   print_stack_trace();

   // foo's body

   return
}
Run Code Online (Sandbox Code Playgroud)

其中的print_stack_trace工作方式类似于callerPerl.

或类似的东西:

int main (void)
{
    // will print out debug info every time foo() is called
    register_stack_trace_function(foo); 

    // etc...
}
Run Code Online (Sandbox Code Playgroud)

在哪里register_stack_trace_function放置某种内部断点,这将导致在调用时打印堆栈跟踪foo.

在某些标准C库中是否存在这样的事情?

我正在使用GCC在Linux上工作.


背景

我有一个测试运行,基于一些不应该影响此行为的命令行开关,行为不同.我的代码有一个伪随机数生成器,我假设它是基于这些开关被不同地调用的.我希望能够使用每组开关运行测试,并查看随机数生成器是否针对每个开关进行不同的调用.

c c++ linux callstack

98
推荐指数
8
解决办法
15万
查看次数

程序只会崩溃作为发布版本 - 如何调试?

我这里有一个"Schroedinger's Cat"类型的问题 - 我的程序(实际上是我的程序的测试套件,但是程序仍然是)崩溃,但只有在发布模式下构建时才会发生,并且只有在从命令行启动时.通过穴居人调试(即整个地方讨厌的printf()消息),我已经确定了代码崩溃的测试方法,但遗憾的是实际的崩溃似乎发生在某些析构函数中,因为我看到的最后一条跟踪消息都在其他执行干净的析构函数.

当我尝试在Visual Studio中运行此程序时,它不会崩溃.从WinDbg.exe启动时也是如此.仅从命令行启动时才会发生崩溃.这是在Windows Vista,btw下发生的,不幸的是我现在无法访问XP机器进行测试.

这将是非常好的,如果我能得到的Windows打印出堆栈跟踪,或一些其他不是简单地结束,如果它已经退出干净方案.有没有人对如何在这里获得更有意义的信息有任何建议,希望能解决这个问题?

编辑:问题确实是由一个越界数组引起的,我在这篇文章中对此进行了更多描述.感谢大家帮忙找到这个问题!

c++ debugging

88
推荐指数
7
解决办法
7万
查看次数

如何使用带有行号信息的gcc获取C++的堆栈跟踪?

我们在专有的assert宏中使用堆栈跟踪来捕获开发人员的错误 - 当捕获错误时,打印堆栈跟踪.

我发现gcc的配对backtrace()/ backtrace_symbols()方法不足:

  1. 名称被破坏了
  2. 没有行信息

第一个问题可以通过abi :: __ cxa_demangle来解决.

然而,第二个问题更加艰难.我发现了替换backtrace_symbols().这比gcc的backtrace_symbols()更好,因为它可以检索行号(如果使用-g编译),并且不需要使用-rdynamic进行编译.

Hoverer代码是GNU许可的,所以恕我直言我不能在商业代码中使用它.

任何建议?

PS

gdb能够打印传递给函数的参数.可能已经要求太多了:)

PS 2

类似的问题(感谢nobar)

c++ linux gcc stack-trace

57
推荐指数
8
解决办法
6万
查看次数

如何知道导致异常的确切代码行?

如果我自己生成异常,我可以在异常中包含任何信息:源文件的许多代码行和名称.像这样的东西:

throw std::exception("myFile.cpp:255");
Run Code Online (Sandbox Code Playgroud)

但是未处理的异常或不是由我生成的异常是什么?

c++ exception

34
推荐指数
5
解决办法
3万
查看次数

来自未处理异常的c ++堆栈跟踪?

之前已经问过这个问题,并且有特定于Windows的答案,但没有令人满意的gcc答案.我可以set_terminate()用来设置一个函数,terminate()当抛出未处理的异常时,该函数将被调用(代替).我知道如何使用backtrace库从程序中的给定点生成堆栈跟踪.但是,当我的终止替换被调用时,这将无济于事,因为此时堆栈已被解除.

然而,如果我只是允许程序abort(),它将产生一个核心转储,其中包含从抛出异常的点开始的完整堆栈信息.所以信息就在那里 - 但是有没有一种编程方式来获取它,例如它可以被记录,而不是必须检查核心文件?

c++ callstack exception-handling stack-trace unhandled-exception

31
推荐指数
1
解决办法
2万
查看次数

C++中异常的调用栈

今天,在我的C++多平台代码中,我对每个函数都进行了尝试.在每个catch块中,我将当前函数的名称添加到异常并再次抛出,以便在最上面的catch块(我最终打印异常的详细信息)中,我有完整的调用堆栈,这有助于我跟踪异常的原因.

这是一个好习惯,还是有更好的方法来获取异常的调用堆栈?

c++ callstack exception try-catch

30
推荐指数
3
解决办法
2万
查看次数

如何在C++中使用C++和代码注入为已捕获的异常打印堆栈跟踪

我希望堆栈跟踪不仅适用于我的例外,也适用于任何后代 std::exception

据我所知,由于堆栈展开(展开),捕获异常时堆栈跟踪完全丢失.

所以我看到抓住它的唯一方法是在std::exception构造函数调用的地方注入代码保存上下文信息(堆栈跟踪).我对吗?

如果是这种情况,请告诉我如何在C++中完成代码注入(如果可以).您的方法可能不完全安全,因为我只需要我的应用程序的调试版本.可能是我需要使用汇编程序?

我只对GCC的解决方案感兴趣.它可以使用c ++ 0x功能

c++ gcc exception-handling code-injection c++11

25
推荐指数
2
解决办法
2万
查看次数

为什么C++不使用std :: nested_exception来允许从析构函数中抛出?

从析构函数抛出异常的主要问题是,在析构函数被调用的那一刻,另一个异常可能是"在飞行中"(std::uncaught_exception() == true),因此在这种情况下做什么并不明显.用新的"覆盖"旧的异常将是处理这种情况的可能方法之一.但是决定在这种情况下必须调用std::terminate(或其他std::terminate_handler).

C++ 11通过std::nested_exception类引入了嵌套异常功能.该特征可用于解决上述问题.旧(未捕获)异常可能只是嵌套到新异常中(反之亦然?)然后可能抛出嵌套异常.但是没有使用这个想法.std::terminate在C++ 11和C++ 14中仍然会出现这种情况.

所以问题.是否考虑过嵌套异常的想法?它有什么问题吗?是不是在C++ 17中会改变这种情况?

c++ exception-handling exception nested-exceptions c++11

16
推荐指数
2
解决办法
5113
查看次数

异常上的可移植C++堆栈跟踪

我正在写一个我想要移植的库.因此,它不应该依赖于glibc或Microsoft扩展或标准中没有的任何其他内容.我有一个很好的从std :: exception派生的类层次结构,我用它来处理逻辑和输入中的错误.知道在特定文件和行号处抛出特定类型的异常是有用的,但是知道执行的执行方式可能会更有价值,所以我一直在寻找获取堆栈跟踪的方法.

我知道,使用execinfo.h功能(见的是glibc建造时这个数据是可用的质疑76822),并通过微软的C++实现的StackWalk接口(见问题126450),但我非常希望避免任何的不便携.

我正在考虑以这种形式自己实现这个功能:

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
  {
    ...
  } …
Run Code Online (Sandbox Code Playgroud)

c++ portability stack-trace

13
推荐指数
2
解决办法
8526
查看次数