2013-10-02 10 views
0

我的程序正在打印幾個隨機數字和字符。它將來自我留下的一些調試代碼。這可能是我最近改變的東西間接打開的。即使在通過我的圖書館進行了一些快速的思考後,我也不知道它來自哪裏。快速跟蹤/查找printf或cout的調用(長時間丟失調試輸出)

如何輕鬆追蹤打印電話的來源?
(這將是一個printfcout <<

我假設類似gdb吐出一個堆棧跟蹤每一個東西寫入stdout。 我一定會從現在開始採取預防性的方法,但只是感興趣的可能的解決方案。

+0

如何打印'__FILE__,__LINE__'在打印/ COUT聲明? – billz

+0

我不知道print/cout語句的位置,它可能位於我當前的項目或它所依賴的5個或6個庫中的任何一箇中。我正在尋找一種通用的方式來跟蹤'stdout'寫入。我也許可以操縱stdio/iostream頭文件,但是寧願採用一種破壞性更小的方法。 – jozxyqk

+0

您知道,根據visual studio的版本,您可以簡單地進入operator <<並在底層文件寫入操作中插入斷點。當然,如果你的圖書館使用不同的圖書館,這不會幫助你。 – SigTerm

回答

2

宏可以幫助你。在宏定義中,您可以使用__FILE____LINE__(和其他此類宏)來打印位置信息。

下面是一個例子:

#include <iostream> 

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

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

它打印的文件名和行號,然後你的消息(在這種情況下"Hello")。

main.cpp(8) Hello 

Online Demo

+1

雖然這從一開始就是一件好事,但看起來他並沒有這樣做。他將不得不重寫所有的調試輸出。 –

2

如果你沒有,除了你正在尋找一個許多其他的控制檯輸出,這是使用調試的時間。首先,使用coutprintf聲明編寫一個小示例程序。調試調用以查看它們的實現,並在那裏放置一個brakpoint。對於printf,您可能必須在彙編程序中這樣做。
一旦你有了這些斷點,在調試器中運行你的程序並等待,直到斷點出現 - 調用堆棧應該告訴你在哪裏調用printf/cout

0

@ArneMertz好主意,謝謝!使用調試器對我來說效果很好,因爲在麻煩的打印之前我沒有太多的輸出。我只需要弄清楚如何在printfcout調用中設置一個斷點。 This page給了我答案。

添加一個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 <[email protected]> 
... 

0x4c1cf0printf地址在這種情況下。

b *0x4c1cf0 
c 
... 
bt 

然後您在下一次調用printf時使用堆棧跟蹤。

如果只有有一個很好的方法來自動執行此操作,沒有常數c/alt-tab/bt循環。

+0

好吧,看起來你正在使用命令行調試器 - 有圖形調試器可以讓你的生活變得更容易一些。關於'c/alt-tab/bt'循環,我認爲這是因爲你正在運行許多「有效的」printf/cout調用。在許多調試器中,您可以爲斷點添加條件,例如限制變量的內容。這些功能可以幫助過濾掉「有效」的呼叫。 –

+0

@ArneMertz良好的調用,不幸的是,斷點沒有任何調試符號。您可能可以爲printf格式編寫'gdb'條件,但是我已經嘗試了代碼中的打印格式的grepping。 – jozxyqk

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]