我有一个并行(MPI)c / c ++程序,在某些条件下不时会导致错误。一旦发生错误,将打印一条消息并退出程序;我想设置一个断点来查看堆栈以及有关导致错误的更多详细信息。我正在使用TotalView来调试事情,我希望它能在我的错误例程中停止。我总是喜欢它,自动设置这个断点。有没有办法做到这一点?
我正在研究使用signal.h并加注,但目前还不清楚TotalView如何响应。
看看这个问题How do you stop in TotalView after an MPI Error?,似乎C ++异常处理(即throw())会自动导致TotalView停止。在C中执行此操作的正确方法是什么?
答案 0 :(得分:4)
我不知道总视图是什么,所以这可能不适用。
在Windows中:DebugBreak();
在x86汇编中:__asm int 3;
在linux中:raise(SIGTRAP);
对于windows one,我使用了一个方便的宏:
#define DEBUGME() do{if (IsDebuggerPresent()) DebugBreak();}while(0)
如果没有附加调试器,则会导致执行继续。
答案 1 :(得分:4)
在TotalView中,文件>信号菜单选项打开此窗口:
这是为了控制响应信号调用的默认行为。 SIGTRAP和SIGSTOP是保留的,看起来TotalView对待它们的方式不同。那就是raise(SIGSTOP)
并未在TotalView中按预期停止。
这个程序:
#include <signal.h>
main(int argc, char* argv[])
{
raise(SIGTRAP);
}
产生这种回应:
不是由断点引起的意外陷阱!
程序状态列为“已退出或从未创建”。当用SIGSTOP替换SIGTRAP时,会出现相同的结果,但没有“Unexpected ...”消息。
如上图所示,SIGINT,SIGTSTP,SIGTTIN和SIGTTOU默认导致TotalView停止,好像有一个断点。
以与Mooing Duck(Totalview: is there a way to hardcode a break point?)提供的答案类似的方式,如果您尝试调试,可以选择性地进行这些raise()调用:
#ifdef DEBUG
raise(SIGTSTP)
#endif
这只是可能获得硬编码断点所需效果的众多方法之一。