快速跟踪/查找对 printf 或 cout 的调用(丢失已久的调试输出)

Quick way to trace/find a call to printf or cout (long lost debug output)

本文关键字:输出 调试 调用 查找 跟踪 printf cout      更新时间:2023-10-16

我的程序正在打印几个随机数字和字符。它将来自我留下的一些调试代码。它可能在我最近更改的内容中被间接打开了。我不知道它来自哪里,即使在我的图书馆中快速浏览了一些之后。

如何轻松追踪打印呼叫的来源?
(这将是printfcout <<之一)

我假设类似于gdb每次写入 stdout 时都会吐出堆栈跟踪。从现在开始,我肯定会采取预防措施,但只是感兴趣的可能的解决方案。

如果除了要查找的控制台输出之外没有许多其他控制台输出,那么现在是时候使用调试器了。首先,使用 coutprintf 语句编写一个小示例程序。调试到调用以查看其实现,并在那里放置一个制动点。对于 printf,您可能必须在汇编程序中执行此操作。
获得这些断点后,在调试器中运行程序并等待断点命中 - 调用堆栈应告诉您对printf/cout的调用在哪里。

可以帮到你。在宏定义中,您可以使用__FILE____LINE__(以及其他此类宏)来打印位置信息。

下面是一个示例:

#include <iostream>
#define mycout std::cout <<  __FILE__  << "(" << __LINE__ << ") "
#define cout mycout
int main()
{
    cout << "Hello";
}

它打印文件名和行号,后跟您的消息(在本例中为"Hello")。

main.cpp(8) Hello

在线演示

strace-plus看起来可以完成这项工作。特别是能够仅使用-e trace=...选项跟踪某些系统调用以消除混乱。您也可以... 2>&1 | grep -C 20 ...找到确切的打印调用。

这是该工具的给定示例输出:

write(1, "bar againn", 10)             = 10
  > write() ../sysdeps/unix/syscall-template.S:82
  > _IO_new_file_write() fileops.c:1277
  > _IO_new_do_write() fileops.c:531
  > _IO_new_file_overflow() fileops.c:889
  > _IO_puts() ioputs.c:40
  > bar() [/home/pgbovine/strace-plus/hello]
  > foo() [/home/pgbovine/strace-plus/hello]
  > main() [/home/pgbovine/strace-plus/hello]
  > __libc_start_main() libc-start.c:258
  > _start() [/home/pgbovine/strace-plus/hello]

@ArneMertz好主意,谢谢!.在我的情况下,使用调试器效果很好,因为在麻烦的打印之前我没有太多的输出。我只需要弄清楚如何在printfcout呼叫上设置断点。这个页面给了我答案。

主函数添加单个printf和/或cout调用,使用调试信息进行编译,以及

gdb program
br main
r
disas

给出这样的东西:

Dump of assembler code for function main():
   0x00000000004cdb66 <+0>:     push   %rbp
   0x00000000004cdb67 <+1>:     mov    %rsp,%rbp
   0x00000000004cdb6a <+4>:     push   %r12
   0x00000000004cdb6c <+6>:     push   %rbx
   0x00000000004cdb6d <+7>:     sub    $0x380,%rsp
=> 0x00000000004cdb74 <+14>:    mov    $0x5ae287,%edi
   0x00000000004cdb79 <+19>:    callq  0x4c1cf0 <puts@plt>
...

在这种情况下,0x4c1cf0printf的地址。

b *0x4c1cf0
c
...
bt

然后你在下一次调用 printf 时使用堆栈跟踪。

如果有一种很好的方法来自动化它,没有恒定的 c/alt-tab/bt 循环。