1Trace::Mask(3)        User Contributed Perl Documentation       Trace::Mask(3)
2
3
4

NAME

6       Trace::Mask - Standard for masking frames in stack traces.
7

DESCRIPTION

9       This is a specification packages can follow to define behaviors stack
10       tracers may choose to honor. If a module implements this specification
11       than any compliant stack tracer will render the stack trace as desired.
12       Implementing the spec will have no effect on non-complient stack
13       tracers. This specification does not effect caller() in any way.
14

PRACTICAL APPLICATIONS

16       Masking stack traces is not something you want to do every day, but
17       there are situations where it can be helpful, if not essential.
18
19       Emulate existing language structures
20               sub foo {
21                   if ($cond) { trace() }
22               }
23
24           In the example above a stack trace is produced, the call to foo()
25           will show up, but the "if" block will not. This is useful as the
26           conditional is part of the sub, and should not be listed.
27
28           Emulating this behavior would be a useful feature for exception
29           tools that provide try/catch/finally or similar control structures.
30
31               try   { ... }
32               catch { ... };
33
34           In perl the above would be emulated with 2 subs that take
35           codeblocks in their prototype. In a stack trace you see a call to
36           try, and a call to an anonymous block. In a stack trace this is
37           distracting at best. Further it is hard to distinguish which
38           anonymous block you are in, though tools like Sub::Name mitigate
39           this some.
40
41       Testing Tools
42           Tools like Test::Exception use Sub::Uplevel to achieve a similar
43           effect.  This is done by globally overriding caller(), which can
44           have some unfortunate side effects. Using Trace::Mask instead would
45           avoid the nasty side effects, would be much faster than overriding
46           caller(), and give more control over what makes it into the trace.
47
48       One interface to many tools
49           Currently Carp provides several configuration variables such as
50           @CARP_NOT to give you control over where a trace starts. Other
51           modules that provide stack traces all provide their own variables.
52           If you want to control stack traces you need to account for all the
53           possible tracing tools that could be used. Many tracing tools do
54           not provide enough control, including "Carp" itself.
55

SPECIFICATION

57       No module (including this one) is required when implementing the spec.
58       Though it is a good idea to list the version of the spec you have
59       implemented in the runtime recommendations for your module. There are
60       no undesired side effects as the specification is completely opt-in,
61       both for modules that want to effect stack traces, and for the stack
62       tracers themselves.
63
64   %Trace::Mask::MASKS
65       Packages that wish to mask stack frames may do so by altering the
66       %Trace::Mask::MASKS package variable. Packages may change this variable
67       at any time, so consumers should not cache the contents, however they
68       may cache the reference to the hash itself.
69
70       This is an overview of the MASKS structure:
71
72           %Trace::Mask::MASKS = (
73               FILE => {
74                   LINE => {
75                       SUBNAME => {
76                           # Behaviors
77                           no_start => BOOL,     # Do not start a trace on this frame
78                           stop     => BOOL,     # Stop tracing at this frame
79                           pause    => BOOL,     # Stop tracing at this frame until you see a restart
80                           restart  => BOOL,     # Start tracing again at this frame
81                           hide     => COUNT,    # Hide the frames completely
82                           shift    => COUNT,    # Pretend this frame started X frames before it did
83                           lock     => BOOL,     # Prevent the frame from being hidden or modified
84
85                           # Replacements
86                           0 => PACKAGE,         # Replace the package listed in the frame
87                           1 => FILE,            # Replace the filename listed in the frame
88                           2 => LINE,            # Replace the linenum listed in the frame
89                           3 => NAME,            # Replace the subname listen in the frame
90                           ...,                  # Replace any index listed in the frame
91                       }
92                   }
93               }
94           );
95
96       No package should ever reset/erase the %Trace::Mask::MASKS variable.
97       They should only ever remove entries they added, even that is not
98       recommended.
99
100       You CAN add entries for files+lines that are not under your control.
101       This is an important allowance as it allows a function to hide the call
102       to itself.
103
104       A stack frame is defined based on the return from caller() which
105       returns the "($package, $file, $line, $subname)" data of a call in the
106       stack. To manipulate a call you define the
107       "$MASKS{$file}->{$line}->{$subname}" path in the hash that matches the
108       call itself.
109
110       'FILE', 'LINE', and 'SUBNAME' can all be replaced with the wildcard '*'
111       string to apply to all:
112
113           # Effect all calls to Foo::foo in any file
114           ('*' => { '*' => { Foo::foo => { ... }}})
115
116           # Effect all sub calls in Foo.pm
117           ('Foo.pm' => { '*' => { '*' => { ... }}});
118
119       You cannot use 3 wildcards to effect all subs. The 3 wildcard entry
120       will be ignored by a compliant tracer.
121
122           # This is not allowed, the entry will be ignored
123           ('*' => { '*' => { '*' => { ... }}});
124
125   CALL MASK HASHES
126       Numeric keys in the behavior structures are replacement values. If you
127       want to replace the package listed in the frame then you specify a
128       value for field '0'.  If you want to replace the filename you would put
129       a value for field '1'.  Numeric fields always correspond to the same
130       index in the list returned from caller().
131
132          {
133              # Behaviors
134              no_start => BOOL,     # Do not start a trace on this frame
135              stop     => BOOL,     # Stop tracing at this frame
136              pause    => BOOL,     # Stop tracing at this frame until you see a restart
137              restart  => BOOL,     # Start tracing again at this frame
138              hide     => COUNT,    # Hide the frames completely
139              shift    => COUNT,    # Pretend this frame started X frames before it did
140              lock     => BOOL,     # Prevent the frame from being hidden or modified
141
142              # Replacements
143              0 => PACKAGE,         # Replace the package listed in the frame
144              1 => FILE,            # Replace the filename listed in the frame
145              2 => LINE,            # Replace the linenum listed in the frame
146              3 => NAME,            # Replace the subname listen in the frame
147              ...,                  # Replace any index listed in the frame
148          }
149
150       The following additional behaviors may be specified:
151
152       no_start => $BOOL
153           This prevents a stack trace from starting at the given call. This
154           is similar to Carp's @CARP_NOT variable. These frames will still
155           appear in the stack trace if they are not the start.
156
157       stop => $BOOL
158           This tells the stack tracer to stop tracing at this frame. The
159           frame itself will be listed in the trace, unless this is combined
160           with the 'hide' option.
161
162           Usually you want pause.
163
164       pause => $BOOL
165           Same as stop, except that things can restart it.
166
167       restart => $BOOL
168           This tells the stack tracer to start again after a pause,
169           effectively skipping all the frames between the pause and this
170           restart. This may be combined with 'pause' in order to show a
171           single frame.
172
173       hide => $COUNT
174           This completely hides the frame from a stack trace. This does not
175           modify the values of any surrounding frames, the frame is simply
176           dropped from the trace.  If $COUNT is greater than 1, then
177           additional frames below the hidden one will also be dropped.
178
179           This has the same effect on a stack trace as Sub::Uplevel.
180
181       shift => $COUNT
182           This is like hide with one important difference, all components of
183           the shifted call, except for package, file, and line, will replace
184           the values of the next frame to be kept in the trace. If $COUNT is
185           large than 1, the shift will hide frames between the shifted frame
186           and the new frame. If $COUNT is larger than the remaining stack,
187           the lowest unhidden/unshifted stack frame will be the recipient of
188           the shift operation, even if the shift frame itself is the lowest.
189
190           This has the same effect on a stack trace as "goto &sub".
191
192       lock => $BOOL
193           Locking a frame means that it must be displayed, and cannot be
194           modified. If it is lower than a stop, or in the middle of a
195           hide/shift span it must be shown anyway. No replacements will have
196           any effect, and it cannot be modified by a shift.
197
198   MASK RESOLUTION
199       Multiple masks in the %Trace::Mask::MASKS structure may apply to any
200       given stack frame, a compliant tracer will account for all of them. A
201       simple hash merge is sufficient so long as they are merged in the
202       correct order. Here is an example:
203
204           my $masks_ref = \%Trace::Mask::MASKS;
205
206           my @all = grep { defined $_ } (
207               $masks_ref->{$file}->{'*'}->{'*'},
208               $masks_ref->{$file}->{$line}->{'*'},
209               $masks_ref->{'*'}->{'*'}->{$name},
210               $masks_ref->{$file}->{'*'}->{$name},
211               $masks_ref->{$file}->{$line}->{$name},
212           );
213
214           my %final = map { %{$_} } @all;
215
216       The most specific path should win out (override others). Rightmost path
217       component is considered the most important. More wildcards means less
218       specific.  Paths may never have wildcards for all 3 components.
219
220   $ENV{'NO_TRACE_MASK'}
221       If this environment variable is set to true then all masking rules
222       should be ignored, tracers should produce full and complete stack
223       traces.
224
225   TRACES STARTING AT $LEVEL
226       If a tracing tool starts at the call to the tool (such as
227       Carp::confess()) then it should account for all the masks starting with
228       the call to confess itself going all the way until the bottom of the
229       stack, or until a mask with 'stop' is found. If a tracing tool allows
230       you to start tracing from a specific level, the tracer should still
231       account for the masks of the frames at the top of the stack on which it
232       is not reporting.
233
234   MASK NUMERIC KEYS
235       Numeric keys in a mask represent items in the list returned from
236       caller().  If you provide numeric keys their values will replace the
237       corresponding value in the caller list before it is used in the trace.
238       You can use this to replace the package, file, etc. This will work for
239       any VALID index into the list. This cannot be used to extend the list.
240       Numeric keys outside the bounds of the list are simply ignored, this is
241       for compatability as different perl versions may have a different size
242       list.
243
244   SPECIAL/MAGIC subs
245       Traces must NEVER hide or alter the following special/magic subs, they
246       should be considered the same as any "lock" frame.
247
248       BEGIN
249       UNITCHECK
250       CHECK
251       INIT
252       END
253       DESTROY
254       import
255       unimport
256
257       These subs are all special in one way or another, hiding them would be
258       hiding critical information.
259

CLASS METHODS

261       The masks() method is defined in Trace::Mask, it returns a reference to
262       the %Trace::Mask::MASKS hash for easy access. It is fine to cache this
263       reference, but not the data it contains.
264

REFERENCE

266       Trace::Mask::Reference is included in this distribution. The Reference
267       module contains example tracers, and example tools that benefit from
268       masking stack traces. The examples in this module should NOT be used in
269       production code.
270

UTILS

272       Trace::Mask::Util is included in this distribution. The util module
273       provides utilities for adding stack trace masking behavior. The
274       utilities provided by this module are considered usable in production
275       code.
276

TEST

278       Trace::Mask::Test is included in this distribution. This module
279       provides test cases and tools useful for verifying your tracing tools
280       are compliant with the spec.
281

PLUGINS

283   Carp
284       Trace::Mask::Carp is included in this distribution. This module can
285       make Carp compliant with Trace::Mask.
286
287   Try::Tiny
288       Trace::Mask::TryTiny is included in this ditribution. Simply loading
289       theis module will cause Try::Tiny framework to be hidden in compliant
290       stack traces.
291

SEE ALSO

293       Sub::Uplevel - Tool for hiding stack frames from all callers, not just
294       stack traces.
295

SOURCE

297       The source code repository for Trace-Mask can be found at
298       http://github.com/exodist/Trace-Mask.
299

MAINTAINERS

301       Chad Granum <exodist@cpan.org>
302

AUTHORS

304       Chad Granum <exodist@cpan.org>
305
307       Copyright 2015 Chad Granum <exodist7@gmail.com>.
308
309       This program is free software; you can redistribute it and/or modify it
310       under the same terms as Perl itself.
311
312       See http://www.perl.com/perl/misc/Artistic.html
313
314
315
316perl v5.38.0                      2023-07-21                    Trace::Mask(3)
Impressum