0

我的程序正在打印几个随机数和字符。它将来自我留下的一些调试代码。它可能是在我最近更改的某些内容中间接打开的。即使在我的库中进行了一些快速的 grep 操作后,我也不知道它是从哪里来的。

如何轻松追踪打印呼叫的来源?
(它将是printf或之一cout <<

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

4

4 回答 4

2

宏可以帮助你。在宏定义中,您可以使用__FILE__and __LINE__(和其他此类宏)来打印位置信息。

这是一个例子:

#include <iostream>

#define mycout std::cout <<  __FILE__  << "(" << __LINE__ << ") "
#define cout mycout

int main()
{
    cout << "Hello";
}

它打印文件名和行号,后跟您的消息("Hello"在这种情况下)。

main.cpp(8) Hello

在线演示

于 2013-10-02T08:55:30.800 回答
2

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

于 2013-10-02T09:06:43.537 回答
1

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

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

write(1, "bar again\n", 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]
于 2013-10-02T09:54:47.017 回答
0

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

向主函数添加一个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>
...

在这种情况下0x4c1cf0,地址在哪里。printf

b *0x4c1cf0
c
...
bt

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

如果只有一种很好的方法可以自动执行此操作,而无需恒定的c/alt-tab/bt循环。

于 2013-10-02T09:39:09.993 回答