【问题标题】:How to make C++ debug statements appear in the gdb console如何使 C++ 调试语句出现在 gdb 控制台中
【发布时间】:2020-05-30 10:59:52
【问题描述】:

我正在尝试调试在 Ubuntu 18.04 上运行的 gdb 中的应用程序。

在代码的某些部分,我可以设置断点并成功调试问题。

但在其他部分,触发断点会导致进程退出。

有什么方法可以让首次亮相的语句出现在 gdb 控制台中?

我目前使用 gdb 附加到进程,然后从该点进行调试。

【问题讨论】:

  • 请定义“调试语句”的含义。如果您使用 GDB 从控制台运行程序,所有标准输出和标准错误消息都将打印在那里。但是,如果您从 GUI 应用程序启动器运行程序,然后附加到它,输出和错误仍将转到 GUI 的标准输出,一些日志文件,如 ~/.xsession-errors 或您可以使用 journalctl -ef 观看的 systemd 日志/跨度>
  • 或者如果调试语句是 syslog 调用,输出将在系统日志中。 /var/log/messages/var/log/syslog 或其他文件,具体取决于您的设置。或者,在 systemd 日志中。
  • 我有代码 (std::cout) 将语句发送到标准输出,但它们没有显示在 gdb 控制台中。但是我知道这些函数正在执行,因为当我在那里设置断点时,它会中断(但正如我在原始帖子中提到的那样,进程会终止)。

标签: c++ gdb ubuntu-18.04


【解决方案1】:

我有将语句发送到标准输出的代码 (std::cout),但它们没有显示在 gdb 控制台中。

你也不应该期望他们这样做。

当应用程序启动时,其std::cout 消息将发送到文件描述符 1 (stdout)。这可以是启动应用程序的终端窗口,也可以是重定向输出的文件。它也可以是管道或/dev/null

GDB 不会“窃取”该输出(如果这样做了,那么调试作为另一个程序通过管道的输入源的程序会更加困难)。

您的首要任务应该是确定输出的位置。在 Linux 上,这通常就像 ls -l /proc/$pid/fds/1 一样简单(将 $pid 替换为您正在调试的进程的实际进程 ID)。

另一个复杂的问题是stdout 可以被完全缓冲(如果它进入文件、管道或套接字),并且在你的断点被命中时可能不是flushed。

附:理论上,您可以通过运行以下 GDB 命令从任何地方“窃取”输出到当前终端:

(gdb) print open("/dev/tty", 2, 0)  # open new fd in the inferior process
                                    # going to current terminal.
                                    # This will print something, e.g. 5

# Now make stdout go to that newly-opened fd
(gdb) call dup2($whatever_last_command_printed, 1)

但我不建议这样做,因为它会以意想不到的方式干扰程序。

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 1970-01-01
    • 2021-11-24
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2011-03-24
    相关资源
    最近更新 更多