Programming, Computing etc.
lldbでPerl5の実行中の情報を調べる
lldb の練習も兼ねて, 前回ビルドしたデバッグ情報付きの perl5 を使ってブレークポイントを張ったりスタックトレースを見たりしてみます.
前回のプログラム
print "start loop program.\n";
while (1) {
print "loop.\n";
sleep(1);
}
を実行します.
$ ./output/bin/perl5.31.9 ./sample.pl
ps でプロセスのID(PID)を調べます.
$ ps
PID TTY TIME CMD
58175 ttys003 0:00.00 ./output/bin/perl5.31.9 ./sample.pl
lldb を起動して, -p オプションでPIDを指定して attach します.
$ lldb
(lldb) attach -p 58175
Process 58175 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00007fff65463bba libsystem_kernel.dylib`__semwait_signal + 10
libsystem_kernel.dylib`__semwait_signal:
-> 0x7fff65463bba <+10>: jae 0x7fff65463bc4 ; <+20>
0x7fff65463bbc <+12>: movq %rax, %rdi
0x7fff65463bbf <+15>: jmp 0x7fff6546268d ; cerror
0x7fff65463bc4 <+20>: retq
Target 0: (perl5.31.9) stopped.
Executable module set to "/Users/naru/repo/perl/perl-5.31.9/output/bin/perl5.31.9".
Architecture set to: x86_64h-apple-macosx-.
bt でバックトレースを確認.
$ (lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* frame #0: 0x00007fff65463bba libsystem_kernel.dylib`__semwait_signal + 10
frame #1: 0x00007fff653e70fa libsystem_c.dylib`nanosleep + 196
frame #2: 0x00007fff653e6f62 libsystem_c.dylib`sleep + 41
frame #3: 0x0000000101f48390 perl5.31.9`Perl_pp_sleep at pp_sys.c:4867:11
frame #4: 0x0000000101ea44dd perl5.31.9`Perl_runops_standard at run.c:41:26
frame #5: 0x0000000101d7e584 perl5.31.9`S_run_body(oldscope=1) at perl.c:2764:2
frame #6: 0x0000000101d7dfd6 perl5.31.9`perl_run(my_perl=0x00007fe56cc01750) at perl.c:2687:2
frame #7: 0x0000000101d3c54a perl5.31.9`main(argc=2, argv=0x00007ffeedec4ae0, env=0x00007ffeedec4af8) at perlmain.c:127:9
frame #8: 0x00007fff653207fd libdyld.dylib`start + 1
sleep の真っ最中らしいことが分かります. pp_sys.c にある Perl_pp_sleep が呼ばれているらしい.
先ほどの関数 Perl_pp_sleep にブレークポイントを張って処理を再開してみます.
$ (lldb) breakpoint set -n Perl_pp_sleep
Breakpoint 1: where = perl5.31.9`Perl_pp_sleep + 46 at pp_sys.c:4850:5, address = 0x0000000101f481de
$ (lldb) continue
Process 58175 resuming
Process 58175 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000101f481de perl5.31.9`Perl_pp_sleep at pp_sys.c:4850:5
4847
4848 PP(pp_sleep)
4849 {
-> 4850 dSP; dTARGET;
4851 Time_t lasttime;
4852 Time_t when;
4853
Target 0: (perl5.31.9) stopped.
これで実行中のコードの箇所を調べることができるようになりました.
ちなみに, PP(pp_sleep) は pp.h(L.11) で定義されています.
#define PP(s) OP * Perl_##s(pTHX)
Perl のソースコードはマクロが多用されています. PP ってなんでしょうね.