File Coverage

blib/lib/Test/Valgrind/Tool/memcheck.pm
Criterion Covered Total %
statement 38 71 53.5
branch 5 22 22.7
condition 5 20 25.0
subroutine 12 18 66.6
pod 8 8 100.0
total 68 139 48.9


line stmt bran cond sub pod time code
1             package Test::Valgrind::Tool::memcheck;
2              
3 7     7   1883 use strict;
  7         9  
  7         186  
4 7     7   27 use warnings;
  7         6  
  7         268  
5              
6             =head1 NAME
7              
8             Test::Valgrind::Tool::memcheck - Run an analysis through the memcheck tool.
9              
10             =head1 VERSION
11              
12             Version 1.19
13              
14             =cut
15              
16             our $VERSION = '1.19';
17              
18             =head1 DESCRIPTION
19              
20             This class contains the information required by the session for running the C tool.
21              
22             =cut
23              
24 7     7   36 use Scalar::Util ();
  7         7  
  7         121  
25              
26 7     7   27 use base qw;
  7         11  
  7         3211  
27              
28             =head1 METHODS
29              
30             This class inherits L.
31              
32             =head2 C
33              
34             my $required_version = $tvt->requires_version;
35              
36             This tool requires C C<3.1.0>.
37              
38             =cut
39              
40 5     5 1 37 sub requires_version { '3.1.0' }
41              
42             =head2 C
43              
44             my $tvtm = Test::Valgrind::Tool::memcheck->new(
45             callers => $callers,
46             %extra_args,
47             );
48              
49             Your usual constructor.
50              
51             C<$callers> specifies the number of stack frames to inspect for errors : the bigger you set it, the more granular the analysis is.
52              
53             Other arguments are passed straight to C<< Test::Valgrind::Tool->new >>.
54              
55             =cut
56              
57             sub new {
58 7     7 1 71 my $class = shift;
59 7   33     38 $class = ref($class) || $class;
60              
61 7         17 my %args = @_;
62              
63 7         15 my $callers = delete $args{callers};
64 7 100       34 $callers = 24 unless $callers;
65 7 50 33     79 die 'Invalid number of callers'
      33        
66             unless Scalar::Util::looks_like_number($callers) and $callers > 0
67             and $callers <= 24;
68              
69 7         47 my $self = bless $class->Test::Valgrind::Tool::new(%args), $class;
70              
71 7         33 $self->{callers} = $callers;
72              
73 7         26 $self;
74             }
75              
76 0     0 1 0 sub new_trainer { shift->new(callers => 24) }
77              
78             =head2 C
79              
80             my $callers = $tvtm->callers;
81              
82             Read-only accessor for the C option.
83              
84             =cut
85              
86 2     2 1 43 sub callers { $_[0]->{callers} }
87              
88 0     0 1 0 sub suppressions_tag { 'memcheck-' . $_[1]->version }
89              
90             =head2 C
91              
92             my $parser_class = $tvtm->parser_class($session);
93              
94             This tool uses a L parser in analysis mode, and a L parser in suppressions mode.
95              
96             =cut
97              
98             sub parser_class {
99 0     0 1 0 my ($self, $session) = @_;
100              
101 0 0       0 my $class = $session->do_suppressions
102             ? 'Test::Valgrind::Parser::Suppressions::Text'
103             : 'Test::Valgrind::Parser::XML::Twig';
104              
105             {
106 0         0 local $@;
  0         0  
107 0 0       0 eval "require $class; 1" or die $@;
108             }
109              
110 0         0 return $class;
111             }
112              
113             =head2 C
114              
115             my $report_class = $tvtm->report_class($session);
116              
117             This tool emits C object reports in analysis mode, and C object reports in suppressions mode.
118              
119             =cut
120              
121             sub report_class {
122 10     10 1 18 my ($self, $session) = @_;
123              
124 10 50       38 if ($session->do_suppressions) {
125 0         0 require Test::Valgrind::Parser::Suppressions::Text;
126 0         0 return 'Test::Valgrind::Report::Suppressions';
127             } else {
128 10         264 return 'Test::Valgrind::Tool::memcheck::Report';
129             }
130             }
131              
132             sub args {
133 2     2 1 18 my $self = shift;
134 2         14 my ($sess) = @_;
135              
136 2         53 my @args = (
137             '--tool=memcheck',
138             '--leak-check=full',
139             '--leak-resolution=high',
140             '--show-reachable=yes',
141             '--num-callers=' . $self->callers,
142             '--error-limit=yes',
143             );
144              
145 2 50 33     68 push @args, '--track-origins=yes' if $sess->version >= '3.4.0'
146             and not $sess->do_suppressions;
147              
148 2         54 push @args, $self->SUPER::args(@_);
149              
150 2         75 return @args;
151             }
152              
153             =head1 SEE ALSO
154              
155             L, L.
156              
157             =head1 AUTHOR
158              
159             Vincent Pit, C<< >>, L.
160              
161             You can contact me by mail or on C (vincent).
162              
163             =head1 BUGS
164              
165             Please report any bugs or feature requests to C, or through the web interface at L.
166             I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
167              
168             =head1 SUPPORT
169              
170             You can find documentation for this module with the perldoc command.
171              
172             perldoc Test::Valgrind::Tool::memcheck
173              
174             =head1 COPYRIGHT & LICENSE
175              
176             Copyright 2009,2010,2011,2013,2015,2016 Vincent Pit, all rights reserved.
177              
178             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
179              
180             =cut
181              
182             # End of Test::Valgrind::Tool::memcheck
183              
184             package Test::Valgrind::Tool::memcheck::Report;
185              
186 7     7   37 use base qw;
  7         11  
  7         2756  
187              
188             our $VERSION = '1.19';
189              
190             my @kinds = qw<
191             InvalidFree
192             MismatchedFree
193             InvalidRead
194             InvalidWrite
195             InvalidJump
196             Overlap
197             InvalidMemPool
198             UninitCondition
199             UninitValue
200             SyscallParam
201             ClientCheck
202             Leak_DefinitelyLost
203             Leak_IndirectlyLost
204             Leak_PossiblyLost
205             Leak_StillReachable
206             >;
207             push @kinds, __PACKAGE__->SUPER::kinds();
208              
209             my %kinds_hashed = map { $_ => 1 } @kinds;
210              
211 0     0   0 sub kinds { @kinds }
212              
213 10     10   60 sub valid_kind { exists $kinds_hashed{$_[1]} }
214              
215 0 0   0     sub is_leak { $_[0]->kind =~ /^Leak_/ ? 1 : '' }
216              
217             my $pad;
218             BEGIN {
219 7     7   34 require Config;
220 7   50     1947 $pad = 2 * ($Config::Config{ptrsize} || 4);
221             }
222              
223             sub dump {
224 0     0     my ($self) = @_;
225              
226 0           my $data = $self->data;
227              
228 0           my $desc = '';
229              
230 0           for ([ '', 2, 4 ], [ 'aux', 4, 6 ], [ 'orig', 4, 6 ]) {
231 0           my ($prefix, $wind, $sind) = @$_;
232              
233 0           my ($what, $stack) = @{$data}{"${prefix}what", "${prefix}stack"};
  0            
234 0 0 0       next unless defined $what and defined $stack;
235              
236 0           $_ = ' ' x $_ for $wind, $sind;
237              
238 0           $desc .= "$wind$what\n";
239 0           for (@$stack) {
240 0 0         my ($ip, $obj, $fn, $dir, $file, $line) = map { (defined) ? $_ : '?' } @$_;
  0            
241 0           my $frame;
242 0 0 0       if ($fn eq '?' and $obj eq '?') {
243 0           $ip =~ s/^0x//gi;
244 0           my $l = length $ip;
245 0 0         $frame = '0x' . ($l < $pad ? ('0' x ($pad - $l)) : '') . uc($ip);
246             } else {
247 0           $frame = sprintf '%s (%s) [%s:%s]', $fn, $obj, $file, $line;
248             }
249 0           $desc .= "$sind$frame\n";
250             }
251             }
252              
253 0           return $desc;
254             }
255              
256             # End of Test::Valgrind::Tool::memcheck::Report
257