helper: fix segfault parsing invalid code
[smatch.git] / smatch_data / db / fill_db_caller_info.pl
blobbfcf803754139cfad4fa9b877a0d2f7489a4f6eb
1 #!/usr/bin/perl -w
3 use strict;
4 use DBI;
5 use Scalar::Util qw(looks_like_number);
7 sub usage()
9 print "usage: $0 <project> <smatch_warns.txt> <db_file>\n";
10 exit(1);
13 my %too_common_funcs;
14 sub get_too_common_functions($$$)
16 my $path = shift;
17 my $project = shift;
18 my $warns = shift;
20 open(FUNCS, "grep 'SQL_caller_info: ' $warns | grep '%call_marker%' | cut -d \"'\" -f 6 | sort | uniq -c | ");
22 while (<FUNCS>) {
23 if ($_ =~ /(\d+) (.*)/) {
24 if (int($1) > 200) {
25 $too_common_funcs{$2} = 1;
30 close(FUNCS);
32 open(FILE, "$path/../$project.common_functions");
33 while (<FILE>) {
34 s/\n//;
35 $too_common_funcs{$_} = 1;
37 close(FILE);
39 open(FILE, ">", "$path/../$project.common_functions");
40 foreach my $func (keys %too_common_funcs) {
41 if ($func =~ / /) {
42 next;
44 print FILE "$func\n";
46 close(FILE);
49 my $exec_name = $0;
50 my $path = $exec_name;
51 $path =~ s/(.*)\/.*/$1/;
52 my $project = shift;
53 my $warns = shift;
54 my $db_file = shift;
56 if (!defined($db_file)) {
57 usage();
60 get_too_common_functions($path, $project, $warns);
62 my $db = DBI->connect("dbi:SQLite:$db_file", "", "", {AutoCommit => 0});
63 $db->do("PRAGMA cache_size = 800000");
64 $db->do("PRAGMA journal_mode = OFF");
65 $db->do("PRAGMA count_changes = OFF");
66 $db->do("PRAGMA temp_store = MEMORY");
67 $db->do("PRAGMA locking = EXCLUSIVE");
69 foreach my $func (keys %too_common_funcs) {
70 $db->do("insert into common_caller_info values ('unknown', 'too common', '$func', 0, 0, 0, -1, '', '');");
73 my $call_id = 0;
74 my ($fn, $dummy, $sql);
76 open(WARNS, "<$warns");
77 while (<WARNS>) {
78 # test.c:11 frob() SQL_caller_info: insert into caller_info values ('test.c', 'frob', '__smatch_buf_size', %CALL_ID%, 1, 0, -1, '', ');
80 if (!($_ =~ /^.*? \w+\(\) SQL_caller_info: /)) {
81 next;
83 ($dummy, $dummy, $dummy, $dummy, $dummy, $fn, $dummy) = split(/'/);
85 if ($fn =~ /__builtin_/) {
86 next;
88 if ($fn =~ /^(printk|memset|memcpy|kfree|printf|dev_err|writel)$/) {
89 next;
92 ($dummy, $dummy, $sql) = split(/:/, $_, 3);
94 if ($sql =~ /%call_marker%/) {
95 $sql =~ s/%call_marker%//; # don't need this taking space in the db.
96 $call_id++;
98 $sql =~ s/%CALL_ID%/$call_id/;
100 $db->do($sql);
102 $db->commit();
103 $db->disconnect();