1

我有一个并行 (MPI) c/c++ 程序,它在某些情况下不时会导致错误。一旦发生错误,将打印一条消息并退出程序;我想设置一个断点以查看堆栈以及有关导致错误的原因的更多详细信息。我正在使用 TotalView 来调试东西,我希望它在我的错误例程中的断点处停止。我希望它总是自动设置这个断点。有没有办法做到这一点?

我正在研究使用 signal.h 和 raise,但目前尚不清楚 TotalView 如何响应。

看这个问题,在 MPI 错误后如何在 TotalView 中停止?,看来 C++ 异常处理,即 throw(),会自动导致 TotalView 停止。在 C 中执行此操作的正确方法是什么?

4

2 回答 2

4

我不知道什么是totalview,所以这可能不适用。

在 Windows 中: 在 x86 程序集中: 在 linux 中:DebugBreak();
__asm int 3;
raise(SIGTRAP);

对于 Windows 系统,我使用了一个方便的宏:
#define DEBUGME() do{if (IsDebuggerPresent()) DebugBreak();}while(0)
如果没有附加调试器,它会导致执行继续。

于 2011-08-12T20:34:27.887 回答
4

在 TotalView 中,文件 > 信号菜单选项打开此窗口:

TotalView 信号窗口

这是为了控制响应信号调用的默认行为。SIGTRAP 和 SIGSTOP 是保留的,似乎 TotalView 以不同的方式对待它们。在 TotalView中raise(SIGSTOP)并没有像预期的那样停止。

这个程序:

#include <signal.h>

main(int argc, char* argv[])
{
  raise(SIGTRAP);
}

产生这个响应:

意外陷阱不是由断点引起的!

并且程序状态被列为“Exited or Never Created”。当 SIGTRAP 替换为 SIGSTOP 时,会出现相同的结果,但不会出现“Unexpected...”消息。

如上图所示,SIGINT、SIGTSTP、SIGTTIN 和 SIGTTOU 默认会导致 TotalView 停止,就好像有一个断点一样。

与 Mooing Duck 提供的答案类似(Totalview: is there a way to hardcode a break point?),如果您尝试调试,可以选择进行这些 raise() 调用:

#ifdef DEBUG
raise(SIGTSTP)
#endif

这只是可能获得硬编码断点所需效果的众多方法之一。

于 2011-08-15T15:03:47.693 回答