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