2012-01-12 64 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和堆栈指针。可能是因为你在糟糕的背景下开始了它。

相关问题