【问题标题】:C++ program crashes terminal--How do I debug this?C++ 程序崩溃终端——我该如何调试?
【发布时间】:2012-06-11 02:35:53
【问题描述】:

别问我怎么做的——我一点也没有。

以下代码会导致我的终端和我使用的任何运行时分析工具崩溃,但不会引发任何静态检查工具警告。 Valgrind、cppcheck 和 gdb 对我没什么好处。 g++ -Wall 没有给我任何有用的东西。

代码的目标是通过 USB 串行连接将字符写入 audrino。 audrino 地址作为第一个参数传递。传递一个 unsigned int 并将其强制转换为一个 unsigned char。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <iostream>

using namespace std;

int main(int argc,char** argv){

  struct termios stdio;
  int tty_fd;

  unsigned char ctrlChar;
  unsigned int ctrlInt;

  tty_fd=open(argv[1], O_RDWR | O_NONBLOCK);
  tcgetattr(tty_fd, &stdio);
  cfmakeraw(&stdio);
  stdio.c_cc[VMIN]  = 1;
  stdio.c_cc[VTIME] = 0;
  tcsetattr(tty_fd,TCSANOW, &stdio);
  tcsetattr(tty_fd,TCSAFLUSH, &stdio);
  fcntl(tty_fd, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK);

  cfsetospeed(&stdio,B9600);            // 9600 baud
  cfsetispeed(&stdio,B9600);            // 9600 baud

  cout << "ready on " << argv[1] << endl;

  scanf("%u", ctrlInt);
  cout <<"recieved initial read.\n";
  while (ctrlInt < 256){
    ctrlChar = ((char) ctrlInt);
    cout << ctrlInt << ctrlChar << endl;
    write(tty_fd,&ctrlChar,1);
    cout << "sent to audrino.\n";
    scanf("%u", ctrlInt);
  }

  cout << "done!" << endl;

  close(tty_fd);
  return 0;
}

现在,如果这看起来很正常,我将提交一份错误报告。

系统规格:最新的 Arch linux 64 位,使用“g++ -g -Wall code.c”编译

【问题讨论】:

  • 您是否尝试检查核心转储?
  • 它在技术上成功退出,所以我不知道如何从中提取核心转储。编程 5 年,我从未见过一个程序这样做。我很茫然。

标签: c++ terminal serial-port arduino


【解决方案1】:

如果“我的终端崩溃”是指终端停止工作,原因很可能是您在标准输出(也就是您的终端)上将各种标志设置为零。您正在调用 tcsetattr() 并将基本上所有终端控制标志清零。

您应该使用tcgetattr() 获取当前终端标志,修改您要修改的那些,然后使用该结构调用tcsetattr()。不这样做甚至是undefined behavior

如果termios_p 指向的termios 结构的值不是从对fildes 调用tcgetattr() 的结果派生的,则tcsetattr() 的效果未定义;应用程序应该只修改在调用tcgetattr()tcsetattr() 之间由本规范定义的字段和标志,而不修改所有其他字段和标志。

【讨论】:

  • 愚蠢的我假设示例代码很好......我会在早上试试这个。
  • 同样地调用fcntl(2)——你不应该只调用fcntl(..., F_SETFL, &lt;flags&gt;),而应该调用fcntl(..., F_SETFL, &lt;flags&gt; | fcntl(..., F_GETFL))来保留以前的标志并添加你想要的。
  • 我必须报告坏消息。虽然终端不再生气,但它仍然没有响应,实际上已经崩溃。这没有回答我的问题,但无疑有所帮助。上面的代码更新了。
  • @Josh:您仍在将该结构的许多成员设置为0。您是否真的要将c_iflagsc_oflags、...中存储的所有标志设置为零?我不是 termios 方面的专家,但是将所有这些标志设置为 0(无论这意味着什么)对我来说听起来不是一个好主意......
  • 我一直在努力。有没有好地方放文档?我又更新了代码。
【解决方案2】:

如果你使用linux,可以使用strace

strace ./yourProgram

你也可以调试coredump文件,

ulimit -c unlimited
g++ -g ...

程序崩溃时将创建coredump文件。

gdb ./yourProgram coredump

使用bt 命令查看崩溃信息。

【讨论】:

    猜你喜欢
    • 2016-12-12
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多