1AnyEvent::Debug(3) User Contributed Perl Documentation AnyEvent::Debug(3)
2
3
4
6 AnyEvent::Debug - debugging utilities for AnyEvent
7
9 use AnyEvent::Debug;
10
11 # create an interactive shell into the program
12 my $shell = AnyEvent::Debug::shell "unix/", "/home/schmorp/myshell";
13 # then on the shell: "socat readline /home/schmorp/myshell"
14
16 This module provides functionality hopefully useful for debugging.
17
18 At the moment, "only" an interactive shell is implemented. This shell
19 allows you to interactively "telnet into" your program and execute Perl
20 code, e.g. to look at global variables.
21
23 $shell = AnyEvent::Debug::shell $host, $service
24 This function binds on the given host and service port and returns
25 a shell object, which determines the lifetime of the shell. Any
26 number of connections are accepted on the port, and they will give
27 you a very primitive shell that simply executes every line you
28 enter.
29
30 All commands will be executed "blockingly" with the socket
31 "select"ed for output. For a less "blocking" interface see
32 Coro::Debug.
33
34 The commands will be executed in the "AnyEvent::Debug::shell"
35 package, which currently has "help" and a few other commands, and
36 can be freely modified by all shells. Code is evaluated under "use
37 strict 'subs'".
38
39 Every shell has a logging context ($LOGGER) that is attached to
40 $AnyEvent::Log::COLLECT), which is especially useful to gether
41 debug and trace messages.
42
43 As a general programming guide, consider the beneficial aspects of
44 using more global ("our") variables than local ones ("my") in
45 package scope: Earlier all my modules tended to hide internal
46 variables inside "my" variables, so users couldn't accidentally
47 access them. Having interactive access to your programs changed
48 that: having internal variables still in the global scope means you
49 can debug them easier.
50
51 As no authentication is done, in most cases it is best not to use a
52 TCP port, but a unix domain socket, whcih can be put wherever you
53 can access it, but not others:
54
55 our $SHELL = AnyEvent::Debug::shell "unix/", "/home/schmorp/shell";
56
57 Then you can use a tool to connect to the shell, such as the ever
58 versatile "socat", which in addition can give you readline support:
59
60 socat readline /home/schmorp/shell
61 # or:
62 cd /home/schmorp; socat readline unix:shell
63
64 Socat can even give you a persistent history:
65
66 socat readline,history=.anyevent-history unix:shell
67
68 Binding on 127.0.0.1 (or "::1") might be a less secure but sitll
69 not totally insecure (on single-user machines) alternative to let
70 you use other tools, such as telnet:
71
72 our $SHELL = AnyEvent::Debug::shell "127.1", "1357";
73
74 And then:
75
76 telnet localhost 1357
77
78 AnyEvent::Debug::wrap [$level]
79 Sets the instrumenting/wrapping level of all watchers that are
80 being created after this call. If no $level has been specified,
81 then it toggles between 0 and 1.
82
83 The default wrap level is 0, or whatever
84 $ENV{PERL_ANYEVENT_DEBUG_WRAP} specifies.
85
86 A level of 0 disables wrapping, i.e. AnyEvent works normally, and
87 in its most efficient mode.
88
89 A level of 1 or higher enables wrapping, which replaces all
90 watchers by AnyEvent::Debug::Wrapped objects, stores the location
91 where a watcher was created and wraps the callback to log all
92 invocations at "trace" loglevel if tracing is enabled fore the
93 watcher. The initial state of tracing when creating a watcher is
94 taken from the global variable $AnyEvent:Debug::TRACE. The default
95 value of that variable is 1, but it can make sense to set it to 0
96 and then do "local $AnyEvent::Debug::TRACE = 1" in a block where
97 you create "interesting" watchers. Tracing can also be enabled and
98 disabled later by calling the watcher's "trace" method.
99
100 The wrapper will also count how many times the callback was invoked
101 and will record up to ten runtime errors with corresponding
102 backtraces. It will also log runtime errors at "error" loglevel.
103
104 To see the trace messages, you can invoke your program with
105 "PERL_ANYEVENT_VERBOSE=9", or you can use AnyEvent::Log to divert
106 the trace messages in any way you like (the EXAMPLES section in
107 AnyEvent::Log has some examples).
108
109 A level of 2 does everything that level 1 does, but also stores a
110 full backtrace of the location the watcher was created, which slows
111 down watcher creation considerably.
112
113 Every wrapped watcher will be linked into
114 %AnyEvent::Debug::Wrapped, with its address as key. The "wl"
115 command in the debug shell can be used to list watchers.
116
117 Instrumenting can increase the size of each watcher multiple times,
118 and, especially when backtraces are involved, also slows down
119 watcher creation a lot.
120
121 Also, enabling and disabling instrumentation will not recover the
122 full performance that you had before wrapping (the AE::xxx
123 functions will stay slower, for example).
124
125 If you are developing your program, also consider using
126 AnyEvent::Strict to check for common mistakes.
127
128 AnyEvent::Debug::path2mod $path
129 Tries to replace a path (e.g. the file name returned by caller) by
130 a module name. Returns the path unchanged if it fails.
131
132 Example:
133
134 print AnyEvent::Debug::path2mod "/usr/lib/perl5/AnyEvent/Debug.pm";
135 # might print "AnyEvent::Debug"
136
137 AnyEvent::Debug::cb2str $cb
138 Using various gambits, tries to convert a callback (e.g. a code
139 reference) into a more useful string.
140
141 Very useful if you debug a program and have some callback, but you
142 want to know where in the program the callback is actually defined.
143
144 AnyEvent::Debug::backtrace [$skip]
145 Creates a backtrace (actually an AnyEvent::Debug::Backtrace object
146 that you can stringify), not unlike the Carp module would. Unlike
147 the Carp module it resolves some references (such as callbacks) to
148 more user-friendly strings, has a more succinct output format and
149 most importantly: doesn't leak memory like hell.
150
151 The reason it creates an object is to save time, as formatting can
152 be done at a later time. Still, creating a backtrace is a
153 relatively slow operation.
154
156 All watchers created while the wrap level is non-zero will be wrapped
157 inside an AnyEvent::Debug::Wrapped object. The address of the wrapped
158 watcher will become its ID - every watcher will be stored in
159 $AnyEvent::Debug::Wrapped{$id}.
160
161 These wrapper objects can be stringified and have some methods defined
162 on them.
163
164 For debugging, of course, it can be helpful to look into these objects,
165 which is why this is documented here, but this might change at any time
166 in future versions.
167
168 Each object is a relatively standard hash with the following members:
169
170 type => name of the method used ot create the watcher (e.g. C<io>, C<timer>).
171 w => the actual watcher
172 rfile => reference to the filename of the file the watcher was created in
173 line => line number where it was created
174 sub => function name (or a special string) which created the watcher
175 cur => if created inside another watcher callback, this is the string rep of the other watcher
176 now => the timestamp (AE::now) when the watcher was created
177 arg => the arguments used to create the watcher (sans C<cb>)
178 cb => the original callback used to create the watcher
179 called => the number of times the callback was called
180
181 Each object supports the following mehtods (warning: these are only
182 available on wrapped watchers, so are best for interactive use via the
183 debug shell).
184
185 $w->id
186 Returns the numerical id of the watcher, as used in the debug
187 shell.
188
189 $w->verbose
190 Returns a multiline textual description of the watcher, including
191 the first ten exceptions caught while executing the callback.
192
193 $w->trace ($on)
194 Enables ($on is true) or disables ($on is false) tracing on this
195 watcher.
196
197 To get tracing messages, both the global logging settings must have
198 trace messages enabled for the context "AnyEvent::Debug" and
199 tracing must be enabled for the wrapped watcher.
200
201 To enable trace messages globally, the simplest way is to start the
202 program with "PERL_ANYEVENT_VERBOSE=9" in the environment.
203
204 Tracing for each individual watcher is enabled by default (unless
205 $AnyEvent::Debug::TRACE has been set to false).
206
208 Marc Lehmann <schmorp@schmorp.de>
209 http://anyevent.schmorp.de
210
211
212
213perl v5.36.0 2022-07-22 AnyEvent::Debug(3)