7 print "Usage: unlocked_paths.pl <call tree file> <lock> <function>\n";
8 print "Prints a list of paths to <function> which don't take the <lock>.\n";
9 print "Generate the call tree file by running smatch with --call-tree.\n";
19 if (!defined($f_map{$callee})) {
20 $f_map{$callee} = {visited
=> 0, called_by
=> {}};
30 %{$f_map{$callee}->{called_by
}}->{$caller} = 1;
40 if (/.*?:\d+ (.*?)\(\) info: func_call \((.*)\) (.*)/) {
41 my $caller = quotemeta $1;
42 my $locks = quotemeta $2;
43 my $callee = quotemeta $3;
46 if (!($locks =~ /$lock/)) {
47 add_called_by
($caller, $callee);
56 foreach my $f (reverse @fstack) {
62 sub print_unlocked_paths
($)
66 if (! defined %{$f_map{$function}}->{called_by
}) {
67 push @fstack, $function;
73 push @fstack, $function;
75 if (!%{$f_map{$function}}->{visited
}) {
76 %{$f_map{$function}}->{visited
} = 1;
77 foreach my $caller (keys %{%{$f_map{$function}}->{called_by
}}){
78 print_unlocked_paths
($caller);
80 %{$f_map{$function}}->{visited
} = 0;
91 if (!$file || !$lock || !$target) {
95 printf("Error: $file does not exist.\n");
99 load_all
($file, $lock);
100 print_unlocked_paths
($target);