如何将调试器附加到运行的Perl进程? [英] How can I attach a debugger to a running Perl process?

查看:182
本文介绍了如何将调试器附加到运行的Perl进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行的Perl进程被卡住了,我想用调试器戳入内部,看看有什么问题。我无法重新启动该过程。我可以将调试器附加到正在运行的进程中吗?我知道我可以做 gdb -p ,但是 gdb 不能帮助我。我试过 Enbugger ,但失败了:

  $ perl -e'while(1){}'& 
[1] 86836
$ gdb -p 86836
...
附加到进程86836.
读取共享库的符号。完成
读取共享库的符号............................. done
读取共享库的符号+完成
0x000000010c1694c6在Perl_pp_stub()
(gdb)调用(void *)Perl_eval_pv(require Enbugger; Enbugger->停止;,0)
perl(86836)malloc:** *对象0x3的错误:未分配的指针是realloc'd
***在malloc_error_break中设置一个断点来调试

程序接收信号SIGABRT,中止。
0x00007fff8269d82a in __kill()
正在调试的程序在从GDB调用的函数中发出信号。
GDB保留在收到信号的帧中。
要更改此行为,请使用set unwindonsignal on
评估包含函数(Perl_eval_pv)的表达式将被放弃。
(gdb)

我做错了吗?还有其他选择吗?






如果您认为自己可以从附加到运行进程的调试器中受益,则可以插入由SIGUSR1触发的调试器后门:

 使用Enbugger :: OnError'USR1'; 

然后你可以简单地 kill -USR1 pid 你的进程将跳转到调试器中。

解决方案

首先,请使用DEBUGGING perl,如果要使用gdb检查。



请定义卡住。忙或不忙等待(高或低CPU),吃记忆还是不记忆?
随着1它正忙着等待。自5.15以来,我经常在Perl_hfree_next_entry()中等待(无休止的循环)。非常繁忙的等待通常是等待阻塞IO读取。



我得到正确的:

 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / code> 

,可以检查所有内容,而不仅仅是一个简单的perl调试器。使用非线程的Perl,您必须输入较少的数据。

 `(gdb)p Perl_op_dump(PL_op)`

等等。



如果你有perl:在pp_stub函数内,进入Enbugger的runloop并不是一个好主意,你应该在dump.c.的主要运行环境中。设置一个断点到显示的行。



对象0x3的错误在eval声音上,如上下文中的内部损坏,所以你应该看看cx和堆栈指针。可能是因为你在恶劣的环境下开始了。


I have a running Perl process that’s stuck, I’d like to poke inside with a debugger to see what’s wrong. I can’t restart the process. Can I attach the debugger to the running process? I know I can do gdb -p, but gdb does not help me. I’ve tried Enbugger, but failed:

$ 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) 

Am I doing it wrong? Are there other options?


P.S. If you think you could benefit from a debugger attached to a running process yourself, you can insert a debugger back door triggered by SIGUSR1:

use Enbugger::OnError 'USR1';

Then you can simply kill -USR1 pid and your process will jump into the debugger.

解决方案

First, please use a DEBUGGING perl, if you want to inspect it with gdb.

Please define "stuck". Busy or non-busy waiting (high or low CPU), eating memory or not? With while 1 it is busy waiting. I usually get busy waiting (endless cycles) on HV corruption in Perl_hfree_next_entry() since 5.15. Non-busy waiting is usually waiting on a blocking IO read.

I get the correct:

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

and can inspect everything, much more than with a simple perl debugger. With a non-threaded perl you have to type less.

`(gdb) p Perl_op_dump(PL_op)`

and so on.

If you have to do with perl: Inside the pp_stub function it is not a good idea to enter the Enbugger runloop, you should be in the main runloop in dump.c. Set a breakpoint to the shown line.

"error for object 0x3" on eval sound like internal corruption in the context, so you should look at the cx and stack pointers. Probably because you started it in a bad context.

这篇关于如何将调试器附加到运行的Perl进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆