2012-01-12 48 views
32

我有一個正在運行的Perl進程被卡住了,我想用調試器在裏面戳,看看有什麼問題。我無法重新啓動該過程。我可以將調試器連接到正在運行的進程嗎?我知道我可以做gdb -p,但gdb不幫助我。我試過Enbugger,但沒有成功如何將調試器附加到正在運行的Perl進程?

$ perl -e 'while (1) {}'& 
[1] 86836 
$ gdb -p 86836 
… 
Attaching to process 86836. 
Reading symbols for shared libraries . done 
Reading symbols for shared libraries ............................. done 
Reading symbols for shared libraries + done 
0x000000010c1694c6 in Perl_pp_stub() 
(gdb) call (void*)Perl_eval_pv("require Enbugger;Enbugger->stop;",0) 
perl(86836) malloc: *** error for object 0x3: pointer being realloc'd was not allocated 
*** set a breakpoint in malloc_error_break to debug 

Program received signal SIGABRT, Aborted. 
0x00007fff8269d82a in __kill() 
The program being debugged was signaled while in a function called from GDB. 
GDB remains in the frame where the signal was received. 
To change this behavior use "set unwindonsignal on" 
Evaluation of the expression containing the function (Perl_eval_pv) will be abandoned. 
(gdb) 

上午我做錯了?還有其他選擇嗎?


P.S.如果你認爲你可以從連接到正在運行的進程自己一個調試器中獲益,您可以通過插入觸發SIGUSR1調試後門:

use Enbugger::OnError 'USR1'; 

然後,你可以簡單地kill -USR1 pid,你的進程將跳入調試器。

回答

6

我從來沒有使用gdb,但也許你可以得到一些有用的strace?

strace -f -s512 -p <PID> 
11

首先,請使用DEBUGGING perl,如果你想用gdb檢查它。

請定義「卡住」。忙或不忙等待(高或低CPU),是否進食記憶? while 1正在忙着等待。自5.15開始,我通常在Perl_hfree_next_entry()中忙於等待(無窮循環)HV腐敗。非忙等待通常在等待阻塞IO讀取。

我得到正確的:

`0x00007fba15ab35c1 in Perl_runops_debug() at dump.c:2266` 
`2266  } while ((PL_op = PL_op->op_ppaddr(aTHX)));` 

,並可以檢查一切,比用一個簡單的Perl調試等等。使用非線程的perl,你必須輸入less。

`(gdb) p Perl_op_dump(PL_op)` 

等等。

如果您需要使用perl:在pp_stub函數中,輸入Enbugger runloop並不是一個好主意,您應該在dump.c中的主runloop中。爲顯示的行設置一個斷點。

對象0x3的「錯誤」,就像上下文中的內部損壞一樣,因此您應該查看cx和堆棧指針。可能是因爲你在糟糕的背景下開始了它。

相關問題