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
47           trace.
48
49       One interface to many tools
50           Currently Carp provides several configuration variables such as
51           @CARP_NOT to give you control over where a trace starts. Other
52           modules that provide stack traces all provide their own variables.
53           If you want to control stack traces you need to account for all the
54           possible tracing tools that could be used. Many tracing tools do
55           not provide enough control, including "Carp" itself.
56

SPECIFICATION

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

CLASS METHODS

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

REFERENCE

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

UTILS

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

TEST

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

PLUGINS

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

SEE ALSO

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

SOURCE

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

MAINTAINERS

302       Chad Granum <exodist@cpan.org>
303

AUTHORS

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