]> sourceware.org Git - systemtap.git/blame - coveragedb.cxx
buildrun.cxx: adapt to kernel 5.4+
[systemtap.git] / coveragedb.cxx
CommitLineData
c3a3c0c9
WC
1// coveragedb.cxx
2// Copyright (C) 2007 Red Hat Inc.
3//
4// This file is part of systemtap, and is free software. You can
5// redistribute it and/or modify it under the terms of the GNU General
6// Public License (GPL); either version 2, or (at your option) any
7// later version.
8
9#include "parse.h"
10#include "coveragedb.h"
11#include "config.h"
12#include "elaborate.h"
13#include "tapsets.h"
14#include "session.h"
15#include "util.h"
16
1c0b94ef
FCE
17#ifdef HAVE_LIBSQLITE3
18
c3a3c0c9
WC
19#include <iostream>
20#include <sqlite3.h>
ed7742ee 21#include <cstdlib>
c3a3c0c9
WC
22
23using namespace std;
24
25void print_coverage_info(systemtap_session &s)
26{
c3a3c0c9 27 // print out used probes
19211404 28 clog << _("---- used probes-----") << endl;
c3a3c0c9
WC
29 for (unsigned i=0; i<s.probes.size(); i++) {
30 // walk through the chain of probes
2c5a19c6 31 vector<probe*> used_probe_list;
c3a3c0c9
WC
32 s.probes[i]->collect_derivation_chain(used_probe_list);
33 for (unsigned j=0; j<used_probe_list.size(); ++j) {
34 for (unsigned k=0; k< used_probe_list[j]->locations.size(); ++k)
19211404 35 clog << _("probe: ")
f94baaee 36 << used_probe_list[j]->locations[k]->components.front()->tok->location << endl;
c3a3c0c9 37 }
dff50e09 38
c3a3c0c9
WC
39 clog << "----" << endl;
40 // for each probe print used and unused variables
41 for (unsigned j=0; j<s.probes[i]->locals.size(); ++j) {
19211404 42 clog << _("local: ") << s.probes[i]->locals[j]->tok->location << endl;
c3a3c0c9
WC
43 }
44 for (unsigned j=0; j<s.probes[i]->unused_locals.size(); ++j) {
19211404 45 clog << _("unused_local: ")
c3a3c0c9
WC
46 << s.probes[i]->unused_locals[j]->tok->location
47 << endl;
48 }
49 }
50 // print out unused probes
19211404 51 clog << _("---- unused probes----- ") << endl;
c3a3c0c9
WC
52 for (unsigned i=0; i<s.unused_probes.size(); i++) {
53 // walk through the chain of probes
2c5a19c6 54 vector<probe*> unused_probe_list;
5657c32c 55 s.unused_probes[i]->collect_derivation_chain(unused_probe_list);
c3a3c0c9
WC
56 for (unsigned j=0; j<unused_probe_list.size(); ++j) {
57 for (unsigned k=0; k< unused_probe_list[j]->locations.size(); ++k)
19211404 58 clog << _("probe: ")
f94baaee 59 << unused_probe_list[j]->locations[k]->components.front()->tok->location << endl;
c3a3c0c9
WC
60 }
61
62 }
63 // print out used functions
19211404 64 clog << _("---- used functions----- ") << endl;
f76427a2
FCE
65 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
66 {
67 clog << "function: " << it->second->tok->location
68 << " " << it->second->name
69 << endl;
70 }
c3a3c0c9 71 // print out unused functions
19211404 72 clog << _("---- unused functions----- ") << endl;
c3a3c0c9 73 for (unsigned i=0; i<s.unused_functions.size(); i++) {
19211404 74 clog << _("unused_function: ") << s.unused_functions[i]->tok->location
c3a3c0c9
WC
75 << " " << s.unused_functions[i]->name
76 << endl;
77 }
78 // print out used globals
19211404 79 clog << _("---- used globals----- ") << endl;
c3a3c0c9 80 for (unsigned i=0; i<s.globals.size(); i++) {
19211404 81 clog << _("globals: ") << s.globals[i]->tok->location
c3a3c0c9
WC
82 << " " << s.globals[i]->name
83 << endl;
84 }
85 // print out unused globals
19211404 86 clog << _("---- unused globals----- ") << endl;
c3a3c0c9 87 for (unsigned i=0; i<s.unused_globals.size(); i++) {
19211404 88 clog << _("globals: ") << s.unused_globals[i]->tok->location
c3a3c0c9
WC
89 << " " << s.unused_globals[i]->name
90 << endl;
91 }
92}
93
94
b34237a1
WC
95bool
96has_table(sqlite3 *db, const char * table)
97{
98 int rc, rows, columns;
99 char *errmsg;
100 char **results = NULL;
101
102 ostringstream command;
103 command << "SELECT name FROM sqlite_master "
104 << "WHERE type='table' AND name='" << table << "'";
105
106 rc = sqlite3_get_table(db, command.str().c_str(),
107 &results, &rows, &columns, &errmsg);
108
109 if(rc != SQLITE_OK) {
1b6156ad 110 cerr << _("Error in statement: ") << command.str() << " [" << errmsg << "]."
b34237a1
WC
111 << endl;
112 }
113 sqlite3_free_table(results);
114 return (rows !=0);
115}
116
117
118bool
119has_index(sqlite3 *db, const char * index)
120{
121 int rc, rows, columns;
122 char *errmsg;
123 char **results = NULL;
124
125 ostringstream command;
126 command << "SELECT name FROM sqlite_master "
127 << "WHERE type='index' AND name='" << index << "'";
128
129 rc = sqlite3_get_table(db, command.str().c_str(),
130 &results, &rows, &columns, &errmsg);
131
132 if(rc != SQLITE_OK) {
1b6156ad 133 cerr << _("Error in statement: ") << command.str() << " [" << errmsg << "]."
b34237a1
WC
134 << endl;
135 }
136 sqlite3_free_table(results);
137 return (rows !=0);
138}
139
140
c3a3c0c9
WC
141void sql_stmt(sqlite3 *db, const char* stmt)
142{
143 char *errmsg;
144 int ret;
145
146 // cerr << "sqlite: " << stmt << endl;
147
148 ret = sqlite3_exec(db, stmt, 0, 0, &errmsg);
149
150 if(ret != SQLITE_OK) {
19211404 151 cerr << _("Error in statement: ") << stmt << " [" << errmsg << "]."
c3a3c0c9
WC
152 << endl;
153 }
154}
155
156void enter_element(sqlite3 *db, coverage_element &x)
157{
158 ostringstream command;
1e41115c 159 command << "insert or ignore into counts values ('"
c3a3c0c9
WC
160 << x.file << "', '"
161 << x.line << "', '"
162 << x.col << "', '"
163 << x.type << "','"
164 << x.name << "', '"
165 << x.parent <<"',"
b34237a1 166 << "'0', '0')";
c3a3c0c9
WC
167 sql_stmt(db, command.str().c_str());
168}
169
b34237a1 170
c3a3c0c9
WC
171void increment_element(sqlite3 *db, coverage_element &x)
172{
b34237a1 173 ostringstream command;
c3a3c0c9 174 // make sure value in table
1e41115c 175 command << "insert or ignore into counts values ('"
b34237a1
WC
176 << x.file << "', '"
177 << x.line << "', '"
178 << x.col << "', '"
179 << x.type << "','"
180 << x.name << "', '"
181 << x.parent <<"',"
182 << "'0', '0'); "
6b1a0274 183 // increment appropriate value
b34237a1
WC
184 << "update counts set compiled=compiled+"
185 << x.compiled << " where ("
186 << "file=='" << x.file << "' and "
187 << "line=='" << x.line << "' and "
188 << "col=='" << x.col << "' and "
189 << "type=='" << x.type << "' and "
190 << "name=='" << x.name << "')";
191 sql_stmt(db, command.str().c_str());
c3a3c0c9
WC
192}
193
194
195void
196sql_update_used_probes(sqlite3 *db, systemtap_session &s)
197{
c3a3c0c9
WC
198 // update database used probes
199 for (unsigned i=0; i<s.probes.size(); i++) {
200 // walk through the chain of probes
2c5a19c6 201 vector<probe*> used_probe_list;
c3a3c0c9
WC
202 s.probes[i]->collect_derivation_chain(used_probe_list);
203 for (unsigned j=0; j<used_probe_list.size(); ++j) {
204 for (unsigned k=0; k< used_probe_list[j]->locations.size(); ++k){
f94baaee 205 struct source_loc place = used_probe_list[j]->locations[k]->components.front()->tok->location;
c3a3c0c9
WC
206 coverage_element x(place);
207
b34237a1 208 x.type = db_type_probe;
c3a3c0c9
WC
209 x.name = used_probe_list[j]->locations[k]->str();
210 x.compiled = 1;
211 increment_element(db, x);
212 }
213 }
dff50e09 214
c3a3c0c9
WC
215 // for each probe update used and unused variables
216 for (unsigned j=0; j<s.probes[i]->locals.size(); ++j) {
217 struct source_loc place = s.probes[i]->locals[j]->tok->location;
218 coverage_element x(place);
219
b34237a1 220 x.type = db_type_local;
47d349b1 221 x.name = s.probes[i]->locals[j]->tok->content;
c3a3c0c9
WC
222 x.compiled = 1;
223 increment_element(db, x);
224 }
225 for (unsigned j=0; j<s.probes[i]->unused_locals.size(); ++j) {
226 struct source_loc place = s.probes[i]->unused_locals[j]->tok->location;
227 coverage_element x(place);
228
b34237a1 229 x.type = db_type_local;
47d349b1 230 x.name = s.probes[i]->unused_locals[j]->tok->content;
b34237a1 231 x.compiled = 0;
c3a3c0c9
WC
232 increment_element(db, x);
233 }
234 }
235}
236
237
238void
239sql_update_unused_probes(sqlite3 *db, systemtap_session &s)
240{
c3a3c0c9
WC
241 // update database unused probes
242 for (unsigned i=0; i<s.unused_probes.size(); i++) {
243 // walk through the chain of probes
2c5a19c6 244 vector<probe*> unused_probe_list;
5657c32c 245 s.unused_probes[i]->collect_derivation_chain(unused_probe_list);
c3a3c0c9
WC
246 for (unsigned j=0; j<unused_probe_list.size(); ++j) {
247 for (unsigned k=0; k< unused_probe_list[j]->locations.size(); ++k) {
248
f94baaee 249 struct source_loc place = unused_probe_list[j]->locations[k]->components.front()->tok->location;
c3a3c0c9
WC
250 coverage_element x(place);
251
b34237a1 252 x.type = db_type_probe;
c3a3c0c9 253 x.name = unused_probe_list[j]->locations[k]->str();
b34237a1 254 x.compiled = 0;
c3a3c0c9
WC
255 increment_element(db, x);
256 }
257 }
258 }
259}
260
261
262void
263sql_update_used_functions(sqlite3 *db, systemtap_session &s)
264{
265 // update db used functions
f76427a2
FCE
266 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
267 {
268 struct source_loc place = it->second->tok->location;
269 coverage_element x(place);
270
271 x.type = db_type_function;
272 x.name = it->second->name;
273 x.compiled = 1;
274 increment_element(db, x);
275 }
c3a3c0c9
WC
276}
277
278
279void
280sql_update_unused_functions(sqlite3 *db, systemtap_session &s)
281{
282 // update db unused functions
283 for (unsigned i=0; i<s.unused_functions.size(); i++) {
284 struct source_loc place = s.unused_functions[i]->tok->location;
285 coverage_element x(place);
286
b34237a1 287 x.type = db_type_function;
c3a3c0c9 288 x.name = s.unused_functions[i]->name;
b34237a1 289 x.compiled = 0;
c3a3c0c9
WC
290 increment_element(db, x);
291 }
292}
293
294
295void
296sql_update_used_globals(sqlite3 *db, systemtap_session &s)
297{
298 // update db used globals
299 for (unsigned i=0; i<s.globals.size(); i++) {
c3a3c0c9
WC
300 struct source_loc place = s.globals[i]->tok->location;
301 coverage_element x(place);
302
b34237a1 303 x.type = db_type_global;
c3a3c0c9
WC
304 x.name = s.globals[i]->name;
305 x.compiled = 1;
306 increment_element(db, x);
307 }
308}
309
310
311void
312sql_update_unused_globals(sqlite3 *db, systemtap_session &s)
313{
314 // update db unused globals
315 for (unsigned i=0; i<s.unused_globals.size(); i++) {
316 struct source_loc place = s.unused_globals[i]->tok->location;
317 coverage_element x(place);
318
b34237a1 319 x.type = db_type_global;
c3a3c0c9 320 x.name = s.unused_globals[i]->name;
b34237a1 321 x.compiled = 0;
c3a3c0c9
WC
322 increment_element(db, x);
323 }
324}
325
c3a3c0c9
WC
326void update_coverage_db(systemtap_session &s)
327{
328 sqlite3 *db;
329 int rc;
330
331 string filename(s.data_path + "/" + s.kernel_release + ".db");
332
333 rc = sqlite3_open(filename.c_str(), &db);
334 if( rc ){
335 cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
336 sqlite3_close(db);
504d2b61 337 return;
c3a3c0c9
WC
338 }
339
b34237a1
WC
340 // lock the database
341 sql_stmt(db, "begin");
342
343 string create_table("create table counts ("
c3a3c0c9
WC
344 "file text, line integer, col integer, "
345 "type text, name text, parent text, "
b34237a1 346 "compiled integer, executed integer)");
8a2b19ab 347 string create_index("create unique index tokens on counts (file, line, col, "
b34237a1 348 "type, name)");
c3a3c0c9 349
b34237a1
WC
350 // make sure the table is there
351 if (!has_table(db, "counts"))
352 sql_stmt(db, create_table.c_str());
c3a3c0c9 353
b34237a1
WC
354 // make sure the index is there
355 if (!has_index(db, "tokens"))
356 sql_stmt(db, create_index.c_str());
c3a3c0c9 357
c3a3c0c9
WC
358 sql_update_used_probes(db, s);
359 sql_update_unused_probes(db, s);
360 sql_update_used_functions(db, s);
361 sql_update_unused_functions(db, s);
362 sql_update_used_globals(db, s);
363 sql_update_unused_globals(db, s);
364
365 // unlock the database and close database
366 sql_stmt(db, "commit");
367
368 sqlite3_close(db);
369}
1c0b94ef
FCE
370
371#endif /* HAVE_LIBSQLITE3 */
73267b89
JS
372
373/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.159458 seconds and 5 git commands to generate.