.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Debug 3pm" .TH Debug 3pm 2024-03-07 "perl v5.38.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Coro::Debug \- various functions that help debugging Coro programs .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 1 \& use Coro::Debug; \& \& our $server = new_unix_server Coro::Debug "/tmp/socketpath"; \& \& $ socat readline unix:/tmp/socketpath .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" This module is an AnyEvent user, you need to make sure that you use and run a supported event loop. .PP This module provides some debugging facilities. Most will, if not handled carefully, severely compromise the security of your program, so use it only for debugging (or take other precautions). .PP It mainly implements a very primitive debugger that is very easy to integrate in your program: .PP .Vb 2 \& our $server = new_unix_server Coro::Debug "/tmp/somepath"; \& # see new_unix_server, below, for more info .Ve .PP It lets you list running coroutines: .PP .Vb 10 \& state (rUnning, Ready, New or neither) \& |cctx allocated \& || resident set size (octets) \& || | scheduled this many times \& > ps || | | \& PID SC RSS USES Description Where \& 14572344 UC 62k 128k [main::] [dm\-support.ext:47] \& 14620056 \-\- 2260 13 [coro manager] [Coro.pm:358] \& 14620128 \-\- 2260 166 [unblock_sub scheduler] [Coro.pm:358] \& 17764008 N\- 152 0 [EV idle process] \- \& 13990784 \-\- 2596 10k timeslot manager [cf.pm:454] \& 81424176 \-\- 18k 4758 [async pool idle] [Coro.pm:257] \& 23513336 \-\- 2624 1 follow handler [follow.ext:52] \& 40548312 \-\- 15k 5597 player scheduler [player\-scheduler.ext:13] \& 29138032 \-\- 2548 431 music scheduler [player\-env.ext:77] \& 43449808 \-\- 2260 3493 worldmap updater [item\-worldmap.ext:115] \& 33352488 \-\- 19k 2845 [async pool idle] [Coro.pm:257] \& 81530072 \-\- 13k 43k map scheduler [map\-scheduler.ext:65] \& 30751144 \-\- 15k 2204 [async pool idle] [Coro.pm:257] .Ve .PP Lets you do backtraces on about any coroutine: .PP .Vb 5 \& > bt 18334288 \& coroutine is at /opt/cf/ext/player\-env.ext line 77 \& eval {...} called at /opt/cf/ext/player\-env.ext line 77 \& ext::player_env::_\|_ANON_\|_ called at \-e line 0 \& Coro::_run_coro called at \-e line 0 .Ve .PP Or lets you eval perl code: .PP .Vb 2 \& > 5+7 \& 12 .Ve .PP Or lets you eval perl code within other coroutines: .PP .Vb 2 \& > eval 18334288 caller(1); $DB::args[0]\->method \& 1 .Ve .PP It can also trace subroutine entry/exits for most coroutines (those not having recursed into a C function), resulting in output similar to: .PP .Vb 10 \& > loglevel 5 \& > trace 94652688 \& 2007\-09\-27Z20:30:25.1368 (5) [94652688] enter Socket::sockaddr_in with (8481,\ex{7f}\ex{00}\ex{00}\ex{01}) \& 2007\-09\-27Z20:30:25.1369 (5) [94652688] leave Socket::sockaddr_in returning (\ex{02}\ex{00}...) \& 2007\-09\-27Z20:30:25.1370 (5) [94652688] enter Net::FCP::Util::touc with (client_get) \& 2007\-09\-27Z20:30:25.1371 (5) [94652688] leave Net::FCP::Util::touc returning (ClientGet) \& 2007\-09\-27Z20:30:25.1372 (5) [94652688] enter AnyEvent::Impl::Event::io with (AnyEvent,fh,GLOB(0x9256250),poll,w,cb,CODE(0x8c963a0)) \& 2007\-09\-27Z20:30:25.1373 (5) [94652688] enter Event::Watcher::_\|_ANON_\|_ with (Event,poll,w,fd,GLOB(0x9256250),cb,CODE(0x8c963a0)) \& 2007\-09\-27Z20:30:25.1374 (5) [94652688] enter Event::io::new with (Event::io,poll,w,fd,GLOB(0x9256250),cb,CODE(0x8c963a0)) \& 2007\-09\-27Z20:30:25.1375 (5) [94652688] enter Event::Watcher::init with (Event::io=HASH(0x8bfb120),HASH(0x9b7940)) .Ve .PP If your program uses the Coro::Debug::log facility: .PP .Vb 2 \& Coro::Debug::log 0, "important message"; \& Coro::Debug::log 9, "unimportant message"; .Ve .PP Then you can even receive log messages in any debugging session: .PP .Vb 2 \& > loglevel 5 \& 2007\-09\-26Z02:22:46 (9) unimportant message .Ve .PP Other commands are available in the shell, use the \f(CW\*(C`help\*(C'\fR command for a list. .SH FUNCTIONS .IX Header "FUNCTIONS" None of the functions are being exported. .ie n .IP "log $level, $msg" 4 .el .IP "log \f(CW$level\fR, \f(CW$msg\fR" 4 .IX Item "log $level, $msg" Log a debug message of the given severity level (0 is highest, higher is less important) to all interested parties. .ie n .IP "stderr_loglevel $level" 4 .el .IP "stderr_loglevel \f(CW$level\fR" 4 .IX Item "stderr_loglevel $level" Set the loglevel for logging to stderr (defaults to the value of the environment variable PERL_CORO_STDERR_LOGLEVEL, or \-1 if missing). .ie n .IP "session_loglevel $level" 4 .el .IP "session_loglevel \f(CW$level\fR" 4 .IX Item "session_loglevel $level" Set the default loglevel for new coro debug sessions (defaults to the value of the environment variable PERL_CORO_DEFAULT_LOGLEVEL, or \-1 if missing). .ie n .IP "trace $coro, $loglevel" 4 .el .IP "trace \f(CW$coro\fR, \f(CW$loglevel\fR" 4 .IX Item "trace $coro, $loglevel" Enables tracing the given coroutine at the given loglevel. If loglevel is omitted, use 5. If coro is omitted, trace the current coroutine. Tracing incurs a very high runtime overhead. .Sp It is not uncommon to enable tracing on oneself by simply calling \&\f(CW\*(C`Coro::Debug::trace\*(C'\fR. .Sp A message will be logged at the given loglevel if it is not possible to enable tracing. .ie n .IP "untrace $coro" 4 .el .IP "untrace \f(CW$coro\fR" 4 .IX Item "untrace $coro" Disables tracing on the given coroutine. .ie n .IP "command $string" 4 .el .IP "command \f(CW$string\fR" 4 .IX Item "command $string" Execute a debugger command, sending any output to STDOUT. Used by \&\f(CW\*(C`session\*(C'\fR, below. .ie n .IP "session $fh" 4 .el .IP "session \f(CW$fh\fR" 4 .IX Item "session $fh" Run an interactive debugger session on the given filehandle. Each line entered is simply passed to \f(CW\*(C`command\*(C'\fR (with a few exceptions). .ie n .IP "$server = new_unix_server Coro::Debug $path" 4 .el .IP "\f(CW$server\fR = new_unix_server Coro::Debug \f(CW$path\fR" 4 .IX Item "$server = new_unix_server Coro::Debug $path" Creates a new unix domain socket that listens for connection requests and runs \f(CW\*(C`session\*(C'\fR on any connection. Normal unix permission checks and umask applies, so you can protect your socket by puttint it into a protected directory. .Sp The \f(CW\*(C`socat\*(C'\fR utility is an excellent way to connect to this socket: .Sp .Vb 1 \& socat readline /path/to/socket .Ve .Sp Socat also offers history support: .Sp .Vb 1 \& socat readline:history=/tmp/hist.corodebug /path/to/socket .Ve .Sp The server accepts connections until it is destroyed, so you must keep the return value around as long as you want the server to stay available. .ie n .IP "$server = new_tcp_server Coro::Debug $port" 4 .el .IP "\f(CW$server\fR = new_tcp_server Coro::Debug \f(CW$port\fR" 4 .IX Item "$server = new_tcp_server Coro::Debug $port" Similar to \f(CW\*(C`new_unix_server\*(C'\fR, but binds on a TCP port. \fINote that this is usually results in a gaping security hole\fR. .Sp Currently, only a TCPv4 socket is created, in the future, a TCPv6 socket might also be created. .SH AUTHOR/SUPPORT/CONTACT .IX Header "AUTHOR/SUPPORT/CONTACT" .Vb 2 \& Marc A. Lehmann \& http://software.schmorp.de/pkg/Coro.html .Ve