我试图突破lldb的read-line循环,然后继续我爆发的地方。当我尝试使用C-C时,程序会在"继续"之后退出。命令给lldb。
以下是示例代码:
#include<iostream>
#include<string>
using namespace std;
int main(){
string cmd;
while(true){
if (!getline(cin,cmd)) {
cout<<"ending on eof"<<endl;
break;}
else if (cmd=="GO INTO DEBUGGER"){
//??
}
else
cout<<"Got line: "<<cmd<<endl;
}
cout<<"Exiting program"<<endl;
return 0;
};
执行此程序时,它只回显输入行。当我使用C-C中断程序时,我会反弹回调试器。当我执行&#34;继续&#34;在调试器中,我只是退出EOF消息而不是返回循环。
如何从循环中断时返回循环,使用C-C或者使用某种命令代替&#34; GO INTO DEBUGGER&#34;子句(从&#34;断言(0)&#34返回;很少找到工作。
这是在Mac Mavericks上用clang ++编译的。
注意:由于某种原因lldb backtrace说收到了SIGSTOP,我认为C-C是SIGINT,但我想我已经过时了。
答案 0 :(得分:2)
这种问题是由于信号和系统陷阱之间的相互作用而产生的。 当位于系统陷阱中的程序等待输入(或实际上在任何系统陷阱中)获得信号时,系统可能需要将陷阱中的线程从内核中取出以便将信号传递给它。如果必须这样做,陷阱调用将返回其通常的错误值,并且线程本地“errno”变量将设置为EINTR。
调试器中发生了这种情况,因为调试器必须发送信号(lldb使用SIGSTOP而不是SIGINT,因为无趣的原因)来中断你的程序。
但是,这不是调试器特有的,这可能是因为作业控制信号或程序可能收到的任何其他信号。因此,为了安全起见,当您从某些读取(读取,选择,getline等等)类型调用返回错误时,您应该检查errno并仅将错误视为EOF,如果errno不是EINTR。
话虽如此,似乎getline是错误的w.r.t.信号。如果我在坐在getline中时中断程序,我得到0返回并且errno被正确设置为4.但是下次我调用getline时它再次返回0,但是这次errno没有被重置,这使得在这种情况下很难使用它。有趣...
答案 1 :(得分:0)
您应该在lldb中使用断点,而不是使用Control-C来停止程序。当您附加到程序时,在开始执行之前,您可以通过键入以下内容来设置断点:
break foo.c:11
打破第11行的文件foo.c See the docs以获取更多信息。
一旦调试器在断点处停止,您可以检查变量并执行其他操作,然后键入:
continue
继续执行该程序。