【问题标题】:How can I continue from a program that has stopped, using lldb?如何使用 lldb 从已停止的程序继续?
【发布时间】:2014-05-24 19:10:32
【问题描述】:

我正在尝试跳出读取行循环进入 lldb,然后继续我跳出的地方。当我尝试使用 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 中断程序时,我跳回调试器。然后,当我在调试器中执行“继续”时,我没有返回循环,而是使用 EOF 消息退出。

如何从循环中断时返回到循环,使用 C-C 或使用某种命令代替“GO INTO DEBUGGER”子句(从“assert(0)”返回很少有效我找到了。

这都是在 Mac Mavericks 上用 clang++ 编译的。

注意:由于某种原因,lldb 回溯说它收到了 SIGSTOP,我认为 C-C 是 SIGINT,但我想我已经过时了。

【问题讨论】:

    标签: c++ osx-mavericks interrupt lldb clang++


    【解决方案1】:

    这种问题的出现是由于信号和系统陷阱之间的相互作用。 当处于等待输入的系统陷阱中(或实际上在任何系统陷阱中)的程序收到信号时,系统可能需要将处于陷阱中的线程从内核中取出,以便将信号传递给它。如果它必须这样做,陷阱调用将返回其通常的错误值,并且线程本地“errno”变量将设置为 EINTR。

    这在调试器中发生在您身上,因为调试器必须发送一个信号(lldb 使用 SIGSTOP 而不是 SIGINT 出于无趣的原因)来中断您的程序。

    但是,这并不特定于调试器,这可能是由于作业控制信号或您的程序可能收到的任何其他信号而发生的。因此,为了安全起见,当您从某些读取(读取、选择、getline 等)类型调用返回错误时,您应该检查 errno,并且如果 errno 不是 EINTR,则仅将错误视为 EOF。

    话虽如此,getline 似乎有问题。信号。如果我在程序处于 getline 时中断程序,我会得到 0 返回,并且 errno 正确设置为 4。但是下次我调用 getline 时,它​​再次返回 0,但是这次 errno 没有被重置,这使得在这种情况下很难使用。有趣...

    【讨论】:

    • 有趣。顺便说一下,gdb 中的行为与预期的一样。
    【解决方案2】:

    您应该在 lldb 中使用断点,而不是使用 Control-C 来停止程序。当您附加到您的程序时,在开始执行之前,您可以通过键入以下内容设置断点:

    break foo.c:11
    

    在第 11 行插入文件 foo.c。See the docs 了解更多信息。

    一旦调试器在断点处停止,您可以检查变量并执行其他操作,然后键入:

    continue
    

    继续执行程序。

    【讨论】:

    • 我需要自己根据运行时的程序输出来确定何时停止程序。我并不总是停留在某个特定点。因此,此解决方案不适用。
    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 2019-10-03
    • 2012-10-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    相关资源
    最近更新 更多