ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Debug.pm
Revision: 1.43
Committed: Wed Dec 10 04:29:33 2014 UTC (9 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-7_08
Changes since 1.42: +1 -1 lines
Log Message:
7.08

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     AnyEvent::Debug - debugging utilities for AnyEvent
4    
5     =head1 SYNOPSIS
6    
7     use AnyEvent::Debug;
8    
9     # create an interactive shell into the program
10     my $shell = AnyEvent::Debug::shell "unix/", "/home/schmorp/myshell";
11     # then on the shell: "socat readline /home/schmorp/myshell"
12    
13     =head1 DESCRIPTION
14    
15     This module provides functionality hopefully useful for debugging.
16    
17     At the moment, "only" an interactive shell is implemented. This shell
18     allows you to interactively "telnet into" your program and execute Perl
19     code, e.g. to look at global variables.
20    
21     =head1 FUNCTIONS
22    
23     =over 4
24    
25     =cut
26    
27     package AnyEvent::Debug;
28    
29 root 1.32 use B ();
30 root 1.16 use Carp ();
31 root 1.1 use Errno ();
32    
33     use AnyEvent (); BEGIN { AnyEvent::common_sense }
34     use AnyEvent::Util ();
35     use AnyEvent::Socket ();
36 root 1.18 use AnyEvent::Log ();
37 root 1.1
38 root 1.26 our $TRACE = 1; # trace status
39    
40 root 1.20 our ($TRACE_LOGGER, $TRACE_ENABLED);
41    
42 root 1.19 # cache often-used strings, purely to save memory, at the expense of speed
43     our %STRCACHE;
44    
45 root 1.26 =item $shell = AnyEvent::Debug::shell $host, $service
46 root 1.1
47     This function binds on the given host and service port and returns a
48 root 1.4 shell object, which determines the lifetime of the shell. Any number
49 root 1.43 of connections are accepted on the port, and they will give you a very
50 root 1.1 primitive shell that simply executes every line you enter.
51    
52     All commands will be executed "blockingly" with the socket C<select>ed for
53     output. For a less "blocking" interface see L<Coro::Debug>.
54    
55     The commands will be executed in the C<AnyEvent::Debug::shell> package,
56 root 1.31 which currently has "help" and a few other commands, and can be freely
57 root 1.6 modified by all shells. Code is evaluated under C<use strict 'subs'>.
58 root 1.1
59 root 1.31 Every shell has a logging context (C<$LOGGER>) that is attached to
60     C<$AnyEvent::Log::COLLECT>), which is especially useful to gether debug
61     and trace messages.
62    
63     As a general programming guide, consider the beneficial aspects of
64     using more global (C<our>) variables than local ones (C<my>) in package
65     scope: Earlier all my modules tended to hide internal variables inside
66     C<my> variables, so users couldn't accidentally access them. Having
67     interactive access to your programs changed that: having internal
68     variables still in the global scope means you can debug them easier.
69 root 1.1
70 root 1.4 As no authentication is done, in most cases it is best not to use a TCP
71     port, but a unix domain socket, whcih can be put wherever you can access
72 root 1.1 it, but not others:
73    
74     our $SHELL = AnyEvent::Debug::shell "unix/", "/home/schmorp/shell";
75    
76     Then you can use a tool to connect to the shell, such as the ever
77     versatile C<socat>, which in addition can give you readline support:
78    
79     socat readline /home/schmorp/shell
80     # or:
81     cd /home/schmorp; socat readline unix:shell
82    
83     Socat can even give you a persistent history:
84    
85     socat readline,history=.anyevent-history unix:shell
86    
87     Binding on C<127.0.0.1> (or C<::1>) might be a less secure but sitll not
88     totally insecure (on single-user machines) alternative to let you use
89     other tools, such as telnet:
90    
91     our $SHELL = AnyEvent::Debug::shell "127.1", "1357";
92    
93     And then:
94    
95     telnet localhost 1357
96    
97     =cut
98    
99     sub shell($$) {
100 root 1.27 local $TRACE = 0;
101    
102 root 1.1 AnyEvent::Socket::tcp_server $_[0], $_[1], sub {
103     my ($fh, $host, $port) = @_;
104    
105 root 1.6 syswrite $fh, "Welcome, $host:$port, use 'help' for more info!\015\012> ";
106 root 1.1 my $rbuf;
107 root 1.30
108     my $logger = new AnyEvent::Log::Ctx
109     log_cb => sub {
110     syswrite $fh, shift;
111     0
112     };
113    
114     my $logger_guard = AnyEvent::Util::guard {
115     $AnyEvent::Log::COLLECT->detach ($logger);
116     };
117     $AnyEvent::Log::COLLECT->attach ($logger);
118    
119 root 1.27 local $TRACE = 0;
120 root 1.3 my $rw; $rw = AE::io $fh, 0, sub {
121 root 1.1 my $len = sysread $fh, $rbuf, 1024, length $rbuf;
122    
123 root 1.30 $logger_guard if 0; # reference it
124    
125 root 1.1 if (defined $len ? $len == 0 : $! != Errno::EAGAIN) {
126     undef $rw;
127     } else {
128     while ($rbuf =~ s/^(.*)\015?\012//) {
129     my $line = $1;
130    
131     AnyEvent::Util::fh_nonblocking $fh, 0;
132    
133     if ($line =~ /^\s*exit\b/) {
134     syswrite $fh, "sorry, no... if you want to execute exit, try CORE::exit.\015\012";
135 root 1.42 } elsif ($line =~ /^\s*coro\b\s*(.*)/) {
136     my $arg = $1;
137     if (eval { require Coro; require Coro::Debug }) {
138     if ($arg =~ /\S/) {
139     Coro::async (sub {
140     select $fh;
141     Coro::Debug::command ($arg);
142     local $| = 1; # older Coro versions do not flush
143     syswrite $fh, "> ";
144     });
145     return;
146     } else {
147     undef $rw;
148     syswrite $fh, "switching to Coro::Debug...\015\012";
149     Coro::async (sub { Coro::Debug::session ($fh) });
150     return;
151     }
152     } else {
153     syswrite $fh, "Coro not available.\015\012";
154     }
155    
156 root 1.1 } else {
157     package AnyEvent::Debug::shell;
158    
159     no strict 'vars';
160 root 1.30 local $LOGGER = $logger;
161 root 1.1 my $old_stdout = select $fh;
162     local $| = 1;
163    
164     my @res = eval $line;
165    
166     select $old_stdout;
167     syswrite $fh, "$@" if $@;
168     syswrite $fh, "\015\012";
169    
170     if (@res > 1) {
171     syswrite $fh, "$_: $res[$_]\015\012" for 0 .. $#res;
172     } elsif (@res == 1) {
173     syswrite $fh, "$res[0]\015\012";
174     }
175     }
176    
177     syswrite $fh, "> ";
178     AnyEvent::Util::fh_nonblocking $fh, 1;
179     }
180     }
181 root 1.3 };
182 root 1.1 }
183     }
184    
185 root 1.6 {
186     package AnyEvent::Debug::shell;
187    
188 root 1.30 our $LOGGER;
189    
190 root 1.6 sub help() {
191     <<EOF
192     help this command
193     wr [level] sets wrap level to level (or toggles if missing)
194 root 1.27 v [level] sets verbosity (or toggles between 0 and 9 if missing)
195 root 1.6 wl 'regex' print wrapped watchers matching the regex (or all if missing)
196 root 1.28 i id,... prints the watcher with the given ids in more detail
197 root 1.27 t enable tracing for newly created watchers (enabled by default)
198     ut disable tracing for newly created watchers
199     t id,... enable tracing for the given watcher (enabled by default)
200 root 1.41 ut id,... disable tracing for the given watcher
201 root 1.28 w id,... converts the watcher ids to watcher objects (for scripting)
202 root 1.42 coro xxx run xxx as Coro::Debug shell command, if available
203     coro switch to Coro::Debug shell, if available
204 root 1.6 EOF
205     }
206    
207     sub wl(;$) {
208     my $re = @_ ? qr<$_[0]>i : qr<.>;
209    
210     my %res;
211    
212     while (my ($k, $v) = each %AnyEvent::Debug::Wrapped) {
213     my $s = "$v";
214     $res{$s} = $k . (exists $v->{error} ? "*" : " ")
215     if $s =~ $re;
216     }
217    
218     join "", map "$res{$_} $_\n", sort keys %res
219     }
220    
221 root 1.28 sub w {
222     map {
223     $AnyEvent::Debug::Wrapped{$_} || do {
224     print "$_: no such wrapped watcher.\n";
225     ()
226 root 1.6 }
227 root 1.28 } @_
228     }
229 root 1.6
230 root 1.28 sub i {
231     join "",
232     map $_->id . " $_\n" . $_->verbose . "\n",
233     &w
234 root 1.6 }
235    
236     sub wr {
237     AnyEvent::Debug::wrap (@_);
238    
239     "wrap level now $AnyEvent::Debug::WRAP_LEVEL"
240     }
241    
242 root 1.27 sub t {
243     if (@_) {
244 root 1.29 @_ = &w;
245     $_->trace (1)
246     for @_;
247     "tracing enabled for @_."
248 root 1.27 } else {
249     $AnyEvent::Debug::TRACE = 1;
250     "tracing for newly created watchers is now enabled."
251     }
252     }
253    
254     sub u {
255     if (@_) {
256 root 1.29 @_ = &w;
257     $_->trace (0)
258     for @_;
259     "tracing disabled for @_."
260 root 1.27 } else {
261     $AnyEvent::Debug::TRACE = 0;
262     "tracing for newly created watchers is now disabled."
263     }
264     }
265    
266 root 1.18 sub v {
267 root 1.30 $LOGGER->level (@_ ? $_[0] : $LOGGER->[1] ? 0 : 9);
268 root 1.27
269 root 1.30 "verbose logging is now " . ($LOGGER->[1] ? "enabled" : "disabled") . "."
270 root 1.6 }
271     }
272    
273 root 1.4 =item AnyEvent::Debug::wrap [$level]
274    
275     Sets the instrumenting/wrapping level of all watchers that are being
276     created after this call. If no C<$level> has been specified, then it
277     toggles between C<0> and C<1>.
278    
279 root 1.5 The default wrap level is C<0>, or whatever
280     C<$ENV{PERL_ANYEVENT_DEBUG_WRAP}> specifies.
281    
282 root 1.4 A level of C<0> disables wrapping, i.e. AnyEvent works normally, and in
283     its most efficient mode.
284    
285 root 1.26 A level of C<1> or higher enables wrapping, which replaces all watchers
286     by AnyEvent::Debug::Wrapped objects, stores the location where a
287     watcher was created and wraps the callback to log all invocations at
288     "trace" loglevel if tracing is enabled fore the watcher. The initial
289     state of tracing when creating a watcher is taken from the global
290     variable C<$AnyEvent:Debug::TRACE>. The default value of that variable
291     is C<1>, but it can make sense to set it to C<0> and then do C<< local
292     $AnyEvent::Debug::TRACE = 1 >> in a block where you create "interesting"
293     watchers. Tracing can also be enabled and disabled later by calling the
294     watcher's C<trace> method.
295    
296     The wrapper will also count how many times the callback was invoked and
297     will record up to ten runtime errors with corresponding backtraces. It
298     will also log runtime errors at "error" loglevel.
299 root 1.22
300     To see the trace messages, you can invoke your program with
301     C<PERL_ANYEVENT_VERBOSE=9>, or you can use AnyEvent::Log to divert
302     the trace messages in any way you like (the EXAMPLES section in
303     L<AnyEvent::Log> has some examples).
304 root 1.4
305     A level of C<2> does everything that level C<1> does, but also stores a
306 root 1.19 full backtrace of the location the watcher was created, which slows down
307     watcher creation considerably.
308 root 1.4
309 root 1.6 Every wrapped watcher will be linked into C<%AnyEvent::Debug::Wrapped>,
310 root 1.33 with its address as key. The C<wl> command in the debug shell can be used
311 root 1.6 to list watchers.
312    
313 root 1.4 Instrumenting can increase the size of each watcher multiple times, and,
314     especially when backtraces are involved, also slows down watcher creation
315     a lot.
316    
317     Also, enabling and disabling instrumentation will not recover the full
318     performance that you had before wrapping (the AE::xxx functions will stay
319     slower, for example).
320    
321 root 1.15 If you are developing your program, also consider using AnyEvent::Strict
322     to check for common mistakes.
323 root 1.4
324     =cut
325    
326     our $WRAP_LEVEL;
327     our $TRACE_CUR;
328     our $POST_DETECT;
329    
330     sub wrap(;$) {
331     my $PREV_LEVEL = $WRAP_LEVEL;
332     $WRAP_LEVEL = @_ ? 0+shift : $WRAP_LEVEL ? 0 : 1;
333    
334 root 1.16 if ($AnyEvent::MODEL) {
335 root 1.4 if ($WRAP_LEVEL && !$PREV_LEVEL) {
336 root 1.20 $TRACE_LOGGER = AnyEvent::Log::logger trace => \$TRACE_ENABLED;
337 root 1.24 AnyEvent::_isa_hook 0 => "AnyEvent::Debug::Wrap", 1;
338 root 1.4 AnyEvent::Debug::Wrap::_reset ();
339     } elsif (!$WRAP_LEVEL && $PREV_LEVEL) {
340 root 1.24 AnyEvent::_isa_hook 0 => undef;
341 root 1.4 }
342     } else {
343     $POST_DETECT ||= AnyEvent::post_detect {
344     undef $POST_DETECT;
345     return unless $WRAP_LEVEL;
346    
347     (my $level, $WRAP_LEVEL) = ($WRAP_LEVEL, undef);
348    
349 root 1.34 require AnyEvent::Strict unless $AnyEvent::Strict::VERSION;
350 root 1.4
351     AnyEvent::post_detect { # make sure we run after AnyEvent::Strict
352     wrap ($level);
353     };
354     };
355     }
356     }
357    
358     =item AnyEvent::Debug::path2mod $path
359    
360     Tries to replace a path (e.g. the file name returned by caller)
361     by a module name. Returns the path unchanged if it fails.
362    
363     Example:
364    
365     print AnyEvent::Debug::path2mod "/usr/lib/perl5/AnyEvent/Debug.pm";
366     # might print "AnyEvent::Debug"
367    
368     =cut
369    
370     sub path2mod($) {
371     keys %INC; # reset iterator
372    
373     while (my ($k, $v) = each %INC) {
374     if ($_[0] eq $v) {
375     $k =~ s%/%::%g if $k =~ s/\.pm$//;
376     return $k;
377     }
378     }
379    
380     my $path = shift;
381    
382     $path =~ s%^\./%%;
383    
384     $path
385     }
386    
387     =item AnyEvent::Debug::cb2str $cb
388    
389     Using various gambits, tries to convert a callback (e.g. a code reference)
390     into a more useful string.
391    
392     Very useful if you debug a program and have some callback, but you want to
393 root 1.16 know where in the program the callback is actually defined.
394 root 1.4
395     =cut
396    
397     sub cb2str($) {
398     my $cb = shift;
399    
400     "CODE" eq ref $cb
401     or return "$cb";
402    
403 root 1.32 eval {
404     my $cv = B::svref_2object ($cb);
405    
406     my $gv = $cv->GV
407     or return "$cb";
408 root 1.4
409 root 1.32 my $name = $gv->NAME;
410 root 1.4
411 root 1.32 return (AnyEvent::Debug::path2mod $gv->FILE) . ":" . $gv->LINE
412     if $name eq "__ANON__";
413 root 1.4
414 root 1.32 $gv->STASH->NAME . "::" . $name;
415     } || "$cb"
416 root 1.4 }
417    
418 root 1.16 sub sv2str($) {
419     if (ref $_[0]) {
420     if (ref $_[0] eq "CODE") {
421     return "$_[0]=" . cb2str $_[0];
422     } else {
423     return "$_[0]";
424     }
425     } else {
426     for ("\'$_[0]\'") { # make copy
427     substr $_, $Carp::MaxArgLen, length, "'..."
428     if length > $Carp::MaxArgLen;
429     return $_;
430     }
431     }
432     }
433    
434 root 1.17 =item AnyEvent::Debug::backtrace [$skip]
435 root 1.16
436     Creates a backtrace (actually an AnyEvent::Debug::Backtrace object
437     that you can stringify), not unlike the Carp module would. Unlike the
438 root 1.35 Carp module it resolves some references (such as callbacks) to more
439 root 1.16 user-friendly strings, has a more succinct output format and most
440     importantly: doesn't leak memory like hell.
441    
442     The reason it creates an object is to save time, as formatting can be
443     done at a later time. Still, creating a backtrace is a relatively slow
444     operation.
445    
446     =cut
447    
448 root 1.17 sub backtrace(;$) {
449     my $w = shift;
450    
451     my (@bt, @c);
452 root 1.16 my ($modlen, $sub);
453    
454     for (;;) {
455     # 0 1 2 3 4 5 6 7 8 9 10
456     # ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
457     package DB;
458     @c = caller $w++
459     or last;
460     package AnyEvent::Debug; # no block for speed reasons
461    
462     if ($c[7]) {
463     $sub = "require $c[6]";
464     } elsif (defined $c[6]) {
465     $sub = "eval \"\"";
466     } else {
467     $sub = ($c[4] ? "" : "&") . $c[3];
468    
469     $sub .= "("
470     . (join ",",
471     map sv2str $DB::args[$_],
472     0 .. (@DB::args < $Carp::MaxArgNums ? @DB::args : $Carp::MaxArgNums) - 1)
473     . ")"
474     if $c[4];
475     }
476    
477 root 1.19 push @bt, [\($STRCACHE{$c[1]} ||= $c[1]), $c[2], $sub];
478 root 1.16 }
479    
480     @DB::args = ();
481    
482     bless \@bt, "AnyEvent::Debug::Backtrace"
483     }
484    
485 root 1.19 =back
486    
487     =cut
488    
489 root 1.4 package AnyEvent::Debug::Wrap;
490    
491     use AnyEvent (); BEGIN { AnyEvent::common_sense }
492     use Scalar::Util ();
493     use Carp ();
494    
495     sub _reset {
496     for my $name (qw(io timer signal child idle)) {
497     my $super = "SUPER::$name";
498    
499     *$name = sub {
500     my ($self, %arg) = @_;
501    
502     my $w;
503    
504 root 1.26 my $t = $TRACE;
505    
506 root 1.4 my ($pkg, $file, $line, $sub);
507    
508     $w = 0;
509     do {
510     ($pkg, $file, $line) = caller $w++;
511 root 1.24 } while $pkg =~ /^(?:AE|AnyEvent::(?:Socket|Handle|Util|Debug|Strict|Base|CondVar|CondVar::Base|Impl::.*)|Coro::AnyEvent::CondVar)$/;
512 root 1.4
513 root 1.16 $sub = (caller $w)[3];
514 root 1.4
515     my $cb = $arg{cb};
516     $arg{cb} = sub {
517 root 1.6 ++$w->{called};
518    
519 root 1.24 local $TRACE_CUR = $w;
520 root 1.4
521 root 1.26 $TRACE_LOGGER->("enter $w") if $TRACE_ENABLED && $t;
522 root 1.4 eval {
523 root 1.24 local $SIG{__DIE__} = sub {
524     die $_[0] . AnyEvent::Debug::backtrace
525     if defined $^S;
526     };
527 root 1.4 &$cb;
528     };
529     if ($@) {
530 root 1.32 my $err = "$@";
531     push @{ $w->{error} }, [AE::now, $err]
532 root 1.6 if @{ $w->{error} } < 10;
533 root 1.32 AE::log die => "($w) $err"
534     or warn "($w) $err";
535 root 1.4 }
536 root 1.26 $TRACE_LOGGER->("leave $w") if $TRACE_ENABLED && $t;
537 root 1.4 };
538    
539     $self = bless {
540     type => $name,
541     w => $self->$super (%arg),
542 root 1.19 rfile => \($STRCACHE{$file} ||= $file),
543 root 1.4 line => $line,
544     sub => $sub,
545 root 1.24 cur => "$TRACE_CUR",
546 root 1.6 now => AE::now,
547 root 1.11 arg => \%arg,
548 root 1.4 cb => $cb,
549 root 1.6 called => 0,
550 root 1.26 rt => \$t,
551 root 1.4 }, "AnyEvent::Debug::Wrapped";
552    
553 root 1.11 delete $arg{cb};
554    
555 root 1.17 $self->{bt} = AnyEvent::Debug::backtrace 1
556 root 1.4 if $WRAP_LEVEL >= 2;
557    
558     Scalar::Util::weaken ($w = $self);
559     Scalar::Util::weaken ($AnyEvent::Debug::Wrapped{Scalar::Util::refaddr $self} = $self);
560    
561 root 1.26 $TRACE_LOGGER->("creat $w") if $TRACE_ENABLED && $t;
562 root 1.4
563     $self
564     };
565     }
566     }
567    
568     package AnyEvent::Debug::Wrapped;
569    
570 root 1.19 =head1 THE AnyEvent::Debug::Wrapped CLASS
571    
572     All watchers created while the wrap level is non-zero will be wrapped
573     inside an AnyEvent::Debug::Wrapped object. The address of the
574     wrapped watcher will become its ID - every watcher will be stored in
575     C<$AnyEvent::Debug::Wrapped{$id}>.
576    
577 root 1.27 These wrapper objects can be stringified and have some methods defined on
578     them.
579 root 1.19
580     For debugging, of course, it can be helpful to look into these objects,
581     which is why this is documented here, but this might change at any time in
582     future versions.
583    
584     Each object is a relatively standard hash with the following members:
585    
586     type => name of the method used ot create the watcher (e.g. C<io>, C<timer>).
587     w => the actual watcher
588     rfile => reference to the filename of the file the watcher was created in
589     line => line number where it was created
590     sub => function name (or a special string) which created the watcher
591     cur => if created inside another watcher callback, this is the string rep of the other watcher
592     now => the timestamp (AE::now) when the watcher was created
593     arg => the arguments used to create the watcher (sans C<cb>)
594     cb => the original callback used to create the watcher
595     called => the number of times the callback was called
596    
597 root 1.27 Each object supports the following mehtods (warning: these are only
598     available on wrapped watchers, so are best for interactive use via the
599     debug shell).
600    
601     =over 4
602    
603 root 1.19 =cut
604    
605 root 1.4 use AnyEvent (); BEGIN { AnyEvent::common_sense }
606    
607 root 1.16 use overload
608     '""' => sub {
609     $_[0]{str} ||= do {
610     my ($pkg, $line) = @{ $_[0]{caller} };
611    
612 root 1.19 my $mod = AnyEvent::Debug::path2mod ${ $_[0]{rfile} };
613 root 1.16 my $sub = $_[0]{sub};
614    
615     if (defined $sub) {
616     $sub =~ s/^\Q$mod\E:://;
617     $sub = "($sub)";
618     }
619 root 1.6
620 root 1.16 "$mod:$_[0]{line}$sub>$_[0]{type}>"
621     . (AnyEvent::Debug::cb2str $_[0]{cb})
622     };
623     },
624     fallback => 1,
625     ;
626 root 1.4
627 root 1.28 =item $w->id
628    
629     Returns the numerical id of the watcher, as used in the debug shell.
630    
631     =cut
632    
633     sub id {
634     Scalar::Util::refaddr shift
635     }
636    
637 root 1.27 =item $w->verbose
638    
639     Returns a multiline textual description of the watcher, including the
640     first ten exceptions caught while executing the callback.
641    
642     =cut
643    
644 root 1.6 sub verbose {
645     my ($self) = @_;
646    
647 root 1.9 my $res = "type: $self->{type} watcher\n"
648 root 1.11 . "args: " . (join " ", %{ $self->{arg} }) . "\n" # TODO: decode fh?
649 root 1.18 . "created: " . (AnyEvent::Log::ft $self->{now}) . " ($self->{now})\n"
650 root 1.19 . "file: ${ $self->{rfile} }\n"
651 root 1.6 . "line: $self->{line}\n"
652     . "subname: $self->{sub}\n"
653     . "context: $self->{cur}\n"
654 root 1.26 . "tracing: " . (${ $self->{rt} } ? "enabled" : "disabled") . "\n"
655 root 1.6 . "cb: $self->{cb} (" . (AnyEvent::Debug::cb2str $self->{cb}) . ")\n"
656     . "invoked: $self->{called} times\n";
657    
658 root 1.7 if (exists $self->{bt}) {
659 root 1.25 $res .= "created\n$self->{bt}";
660 root 1.7 }
661    
662     if (exists $self->{error}) {
663 root 1.6 $res .= "errors: " . @{$self->{error}} . "\n";
664    
665 root 1.18 $res .= "error: " . (AnyEvent::Log::ft $_->[0]) . " ($_->[0]) $_->[1]\n"
666 root 1.6 for @{$self->{error}};
667     }
668    
669     $res
670     }
671    
672 root 1.27 =item $w->trace ($on)
673    
674     Enables (C<$on> is true) or disables (C<$on> is false) tracing on this
675     watcher.
676    
677     To get tracing messages, both the global logging settings must have trace
678     messages enabled for the context C<AnyEvent::Debug> and tracing must be
679     enabled for the wrapped watcher.
680    
681     To enable trace messages globally, the simplest way is to start the
682     program with C<PERL_ANYEVENT_VERBOSE=9> in the environment.
683    
684     Tracing for each individual watcher is enabled by default (unless
685     C<$AnyEvent::Debug::TRACE> has been set to false).
686    
687     =cut
688    
689     sub trace {
690     ${ $_[0]{rt} } = $_[1];
691     }
692    
693 root 1.4 sub DESTROY {
694 root 1.26 $TRACE_LOGGER->("dstry $_[0]") if $TRACE_ENABLED && ${ $_[0]{rt} };
695 root 1.4
696     delete $AnyEvent::Debug::Wrapped{Scalar::Util::refaddr $_[0]};
697     }
698    
699 root 1.27 =back
700    
701     =cut
702    
703 root 1.16 package AnyEvent::Debug::Backtrace;
704    
705     use AnyEvent (); BEGIN { AnyEvent::common_sense }
706    
707     sub as_string {
708     my ($self) = @_;
709    
710     my @bt;
711     my $modlen;
712    
713     for (@$self) {
714     my ($rpath, $line, $sub) = @$_;
715    
716     $rpath = (AnyEvent::Debug::path2mod $$rpath) . " line $line";
717     $modlen = length $rpath if $modlen < length $rpath;
718    
719 root 1.37 $sub =~ s/\r/\\r/g;
720     $sub =~ s/\n/\\n/g;
721     $sub =~ s/([\x00-\x1f\x7e-\xff])/sprintf "\\x%02x", ord $1/ge;
722     $sub =~ s/([^\x20-\x7e])/sprintf "\\x{%x}", ord $1/ge;
723    
724 root 1.16 push @bt, [$rpath, $sub];
725     }
726    
727     join "",
728     map { sprintf "%*s %s\n", -$modlen, $_->[0], $_->[1] }
729     @bt
730     }
731    
732     use overload
733     '""' => \&as_string,
734     fallback => 1,
735     ;
736    
737 root 1.1 =head1 AUTHOR
738    
739     Marc Lehmann <schmorp@schmorp.de>
740 root 1.40 http://anyevent.schmorp.de
741 root 1.1
742     =cut
743    
744 root 1.38 1
745