how to inspect a running perl process

14
How to inspect RUNNING perl process @hirose31 ひろせ まさあき YAPC::Asia Tokyo 2013 LT Day 1

Upload: masaaki-hirose

Post on 17-May-2015

1.372 views

Category:

Technology


0 download

DESCRIPTION

スクリプトを修正することなく外部から稼働中のperlプロセスの状態を観測する方法について、既存の手法をおさらいした上で、導入コストが小さい手法でパッケージ毎のメモリ使用状況や%INCのダンプをする方法を提案します。

TRANSCRIPT

Page 1: How to inspect a RUNNING perl process

How to inspectRUNNING perl process

@hirose31ひろせ まさあき

YAPC::Asia Tokyo 2013LT Day 1

Page 2: How to inspect a RUNNING perl process

Who am I

• PAUSE ID: HIROSE / @hirose31

• Recognize as NON-human on CPAN

テキスト

https://metacpan.org/module/Acme::CPANAuthors::Nonhuman

Page 3: How to inspect a RUNNING perl process

AgendaHow to inspect a RUNNING perl process

•Motivation

• Revisit existing ideas

• Introduce a my idea

Page 4: How to inspect a RUNNING perl process

Motivation

•WHY: shooting trouble of RUNNING perl process

• examine where perl process is running

•where does process hang up?

•where does process loop forever?

•which pacage leaks memory?

•want to examine from OUTER without editing target process/script

Page 5: How to inspect a RUNNING perl process

Revisit existing ideas‘strace’

• strace -fF -Tttt -s 512 -p PID

• current system call

• show the time spent in system calls

• peep into an ASCII string

• no requires☺, just attach process

• show just name of system call not perl symbol☹

1379392067.757575 accept(5,

1379392038.406593 write(5, "\22\0\0\0\3 select sleep(8) ", 22) = 22 <0.000083>1379392038.406791 read(5,

Page 6: How to inspect a RUNNING perl process

Revisit existing ideas‘gdb’

• Attach and trace code by gdb

• Generate a core file by gcore PID

• “Introduction gdb to perl programmers”, @stanaka, Shibuya.pm #9http://blog.stanaka.org/entry/20080630/1214780557

• show stacktrace with perl symbol

#0 0x00007fb086990c20 in __accept_nocancel () from /lib/libpthread.so.0#1 0x00000000004f19e8 in Perl_pp_accept (my_perl=0xd69010) at pp_sys.c:2554...#5 0x0000000000420eef in main (argc=8, argv=0x7fff34899828, env=0x7fff34899870) at perlmain.c:99

Page 7: How to inspect a RUNNING perl process

Revisit existing ideas‘bulkdbg’

• https://github.com/ahiguti/bulkdbg

• bulkdbg PID

• show stackstrace with perl symbol

• convinient by batch

3183 __accept_nocancel:Perl_pp_accept:Perl_pop_scope:Perl_peep:_dl_rtld_di_serinfo:PerlIO_debug:_dl_rtld_di_serinfo:PerlIO_debug:calloc:calloc:__libc_malloc:calloc:_dl_rtld_di_serinfo:S_hv_fetch_common

Page 8: How to inspect a RUNNING perl process

Revisit existing ideas‘gdbperl’

• https://github.com/ahiguti/gdbperl

• examine state of perl interpreter using gdb

• “debugging Perl script with gdb”, Akira Higuchi, YAPC::Asia Tokyo 2011

http://www.slideshare.net/akirahiguchi/gdbperl

• show stacktrace with perl code☺, package name, line number!!

• depend heavily on perl version/internal structure☹

perl_backtrace:[8] IO::Socket::accept() <- /.../perl-5.8.8-threads/lib/site_perl/5.8.8/Starlet/Server.pm:106(Starlet::Server)[7] (loop) <- /.../perl-5.8.8-threads/lib/site_perl/5.8.8/Starlet/Server.pm:105(Starlet::Server)...[1] Plack::Runner::run() <- /.../perl-5.8.8-threads/bin/plackup:10(main)

Page 9: How to inspect a RUNNING perl process

Introduce a my idea‘inspect-perl-proc’

• https://github.com/hirose31/inspect-perl-proc

• Attach by gdb and run arbitrary Perl code using Perl_eval_pv

• less requires: gdb, perl with debug symbol (-DDEBUGGING=-g)

• not depend on perl version / perl internal structure

• save output to file, not output STDOUT/STDERR of target process

Page 10: How to inspect a RUNNING perl process

dump-perl-stacktrace• dump-perl-stacktrace

= inspect-perl-proc --mode 'dump-stacktrace'

• Carp::longmess(‘Dump stacktrace’)

Dump stacktrace at /.../perl-5.8.8-threads/lib/5.8.8/x86_64-linux-thread-multi/IO/Socket.pm line 237 IO::Socket::accept('IO::Socket::INET=GLOB()') called at /.../Starlet/Server.pm line 106 Starlet::Server::accept_loop('Plack::Handler:: Starlet=HASH()', 'CODE()', 100) called at /.../Starlet.pm line 67 Plack::Handler::Starlet::run('Plack::Handler:: Starlet=HASH()', 'CODE()') called at /.../Plack/Loader.pm line 84... Plack::Runner::run('Plack::Runner=HASH()') called at /.../bin/plackup line 10

Page 11: How to inspect a RUNNING perl process

dump-perl-memusage

• dump-perl-memusage

= inspect-perl-proc --mode 'dump-memusage'

• Dump memory usage with B::Size2::Terse::package_size

for each packages (Devel::Symdump)

• save as as hashref so you can filter or sort easily

{ 'main' => '95589',... 'PerlIO::scalar' => '1025', 'Plack' => '3056', 'Plack::App' => '200', 'Plack::App::URLMap' => '26681', 'Plack::Builder' => '31972',...};

Page 12: How to inspect a RUNNING perl process

dump-perl-inc• dump-perl-inc

= inspect-perl-proc --mode 'dump-inc'

• Dump %INC

• list up loaded modules for preloading (CoW)

• save as as hashref so you can filter or sort easily

{ 'parent.pm' => '/.../parent.pm', 'HTTP/Status.pm' => '/.../HTTP/Status.pm', 'POSIX.pm' => '/.../POSIX.pm', 'List/Util.pm' => '/.../List/Util.pm', 'Plack/Loader.pm' => '/.../Plack/Loader.pm', 'Cwd.pm' => '/.../Cwd.pm', 'Fcntl.pm' => '/.../Fcntl.pm',...};

Page 13: How to inspect a RUNNING perl process

Introduce a my idea‘inspect-perl-proc’

• https://github.com/hirose31/inspect-perl-proc

• Attach by gdb and run arbitrary code using Perl_eval_pv

• less requires: gdb, perl with debug symbol (-DDEBUGGING=-g)

• not depend on perl version / perl internal structure

• save output to file, not output STDOUT/STDERR of target process

Page 14: How to inspect a RUNNING perl process

Thanks :D