]> git.vpit.fr Git - perl/modules/Test-Valgrind.git/blobdiff - lib/Test/Valgrind/Suppressions.pm
Z-demangle symbol names in suppressions
[perl/modules/Test-Valgrind.git] / lib / Test / Valgrind / Suppressions.pm
index 3af3a9847631fb3025c7857709b2f4a0ff77287e..dc1878280c3619fca6cc0b2366d017fbd9a90f2f 100644 (file)
@@ -111,6 +111,54 @@ sub strip_tail {
  $supp;
 }
 
+=head2 C<maybe_z_demangle $symbol>
+
+If C<$symbol> is Z-encoded as described in C<valgrind>'s F<include/pub_tool_redir.h>, extract and decode its function name part.
+Otherwise, C<$symbol> is returned as is.
+
+This routine follows C<valgrind>'s F<coregrind/m_demangle/demangle.c:maybe_Z_demangle>.
+
+=cut
+
+my %z_escapes = (
+ a => '*',
+ c => ':',
+ d => '.',
+ h => '-',
+ p => '+',
+ s => ' ',
+ u => '_',
+ A => '@',
+ D => '$',
+ L => '(',
+ R => ')',
+ Z => 'Z',
+);
+
+sub maybe_z_demangle {
+ my ($self, $sym) = @_;
+
+ $sym =~ s/^_vg[rwn]Z([ZU])_// or return $sym;
+
+ my $fn_is_encoded = $1 eq 'Z';
+
+ $sym =~ /^VG_Z_/ and $self->_croak('Symbol with a "VG_Z_" prefix is invalid');
+ $sym =~ s/^[^_]*_//
+                   or $self->_croak('Symbol doesn\'t contain a function name');
+
+ if ($fn_is_encoded) {
+  $sym =~ s/Z(.)/
+   my $c = $z_escapes{$1};
+   $self->_croak('Invalid escape sequence') unless defined $c;
+   $c;
+  /ge;
+ }
+
+ $self->_croak('Empty symbol') unless length $sym;
+
+ return $sym;
+}
+
 =head1 SEE ALSO
 
 L<Test::Valgrind>, L<Test::Valgrind::Command>, L<Test::Valgrind::Tool>, L<Test::Valgrind::Action::Suppressions>.