coveragedb.cxx - systemtap
Functions defined
Source code
#include "parse.h"
#include "coveragedb.h"
#include "config.h"
#include "elaborate.h"
#include "tapsets.h"
#include "session.h"
#include "util.h"
#ifdef HAVE_LIBSQLITE3
#include <iostream>
#include <sqlite3.h>
#include <cstdlib>
using namespace std;
void print_coverage_info(systemtap_session &s)
{
clog << _("---- used probes-----") << endl;
for (unsigned i=0; i<s.probes.size(); i++) {
vector<probe*> used_probe_list;
s.probes[i]->collect_derivation_chain(used_probe_list);
for (unsigned j=0; j<used_probe_list.size(); ++j) {
for (unsigned k=0; k< used_probe_list[j]->locations.size(); ++k)
clog << _("probe: ")
<< used_probe_list[j]->locations[k]->components.front()->tok->location << endl;
}
clog << "----" << endl;
for (unsigned j=0; j<s.probes[i]->locals.size(); ++j) {
clog << _("local: ") << s.probes[i]->locals[j]->tok->location << endl;
}
for (unsigned j=0; j<s.probes[i]->unused_locals.size(); ++j) {
clog << _("unused_local: ")
<< s.probes[i]->unused_locals[j]->tok->location
<< endl;
}
}
clog << _("---- unused probes----- ") << endl;
for (unsigned i=0; i<s.unused_probes.size(); i++) {
vector<probe*> unused_probe_list;
s.unused_probes[i]->collect_derivation_chain(unused_probe_list);
for (unsigned j=0; j<unused_probe_list.size(); ++j) {
for (unsigned k=0; k< unused_probe_list[j]->locations.size(); ++k)
clog << _("probe: ")
<< unused_probe_list[j]->locations[k]->components.front()->tok->location << endl;
}
}
clog << _("---- used functions----- ") << endl;
for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
clog << "function: " << it->second->tok->location
<< " " << it->second->name
<< endl;
}
clog << _("---- unused functions----- ") << endl;
for (unsigned i=0; i<s.unused_functions.size(); i++) {
clog << _("unused_function: ") << s.unused_functions[i]->tok->location
<< " " << s.unused_functions[i]->name
<< endl;
}
clog << _("---- used globals----- ") << endl;
for (unsigned i=0; i<s.globals.size(); i++) {
clog << _("globals: ") << s.globals[i]->tok->location
<< " " << s.globals[i]->name
<< endl;
}
clog << _("---- unused globals----- ") << endl;
for (unsigned i=0; i<s.unused_globals.size(); i++) {
clog << _("globals: ") << s.unused_globals[i]->tok->location
<< " " << s.unused_globals[i]->name
<< endl;
}
}
bool
has_table(sqlite3 *db, const char * table)
{
int rc, rows, columns;
char *errmsg;
char **results = NULL;
ostringstream command;
command << "SELECT name FROM sqlite_master "
<< "WHERE type='table' AND name='" << table << "'";
rc = sqlite3_get_table(db, command.str().c_str(),
&results, &rows, &columns, &errmsg);
if(rc != SQLITE_OK) {
cerr << _("Error in statement: ") << command << " [" << errmsg << "]."
<< endl;
}
sqlite3_free_table(results);
return (rows !=0);
}
bool
has_index(sqlite3 *db, const char * index)
{
int rc, rows, columns;
char *errmsg;
char **results = NULL;
ostringstream command;
command << "SELECT name FROM sqlite_master "
<< "WHERE type='index' AND name='" << index << "'";
rc = sqlite3_get_table(db, command.str().c_str(),
&results, &rows, &columns, &errmsg);
if(rc != SQLITE_OK) {
cerr << _("Error in statement: ") << command << " [" << errmsg << "]."
<< endl;
}
sqlite3_free_table(results);
return (rows !=0);
}
void sql_stmt(sqlite3 *db, const char* stmt)
{
char *errmsg;
int ret;
ret = sqlite3_exec(db, stmt, 0, 0, &errmsg);
if(ret != SQLITE_OK) {
cerr << _("Error in statement: ") << stmt << " [" << errmsg << "]."
<< endl;
}
}
void enter_element(sqlite3 *db, coverage_element &x)
{
ostringstream command;
command << "insert or ignore into counts values ('"
<< x.file << "', '"
<< x.line << "', '"
<< x.col << "', '"
<< x.type << "','"
<< x.name << "', '"
<< x.parent <<"',"
<< "'0', '0')";
sql_stmt(db, command.str().c_str());
}
void increment_element(sqlite3 *db, coverage_element &x)
{
ostringstream command;
command << "insert or ignore into counts values ('"
<< x.file << "', '"
<< x.line << "', '"
<< x.col << "', '"
<< x.type << "','"
<< x.name << "', '"
<< x.parent <<"',"
<< "'0', '0'); "
<< "update counts set compiled=compiled+"
<< x.compiled << " where ("
<< "file=='" << x.file << "' and "
<< "line=='" << x.line << "' and "
<< "col=='" << x.col << "' and "
<< "type=='" << x.type << "' and "
<< "name=='" << x.name << "')";
sql_stmt(db, command.str().c_str());
}
void
sql_update_used_probes(sqlite3 *db, systemtap_session &s)
{
for (unsigned i=0; i<s.probes.size(); i++) {
vector<probe*> used_probe_list;
s.probes[i]->collect_derivation_chain(used_probe_list);
for (unsigned j=0; j<used_probe_list.size(); ++j) {
for (unsigned k=0; k< used_probe_list[j]->locations.size(); ++k){
struct source_loc place = used_probe_list[j]->locations[k]->components.front()->tok->location;
coverage_element x(place);
x.type = db_type_probe;
x.name = used_probe_list[j]->locations[k]->str();
x.compiled = 1;
increment_element(db, x);
}
}
for (unsigned j=0; j<s.probes[i]->locals.size(); ++j) {
struct source_loc place = s.probes[i]->locals[j]->tok->location;
coverage_element x(place);
x.type = db_type_local;
x.name = s.probes[i]->locals[j]->tok->content;
x.compiled = 1;
increment_element(db, x);
}
for (unsigned j=0; j<s.probes[i]->unused_locals.size(); ++j) {
struct source_loc place = s.probes[i]->unused_locals[j]->tok->location;
coverage_element x(place);
x.type = db_type_local;
x.name = s.probes[i]->unused_locals[j]->tok->content;
x.compiled = 0;
increment_element(db, x);
}
}
}
void
sql_update_unused_probes(sqlite3 *db, systemtap_session &s)
{
for (unsigned i=0; i<s.unused_probes.size(); i++) {
vector<probe*> unused_probe_list;
s.unused_probes[i]->collect_derivation_chain(unused_probe_list);
for (unsigned j=0; j<unused_probe_list.size(); ++j) {
for (unsigned k=0; k< unused_probe_list[j]->locations.size(); ++k) {
struct source_loc place = unused_probe_list[j]->locations[k]->components.front()->tok->location;
coverage_element x(place);
x.type = db_type_probe;
x.name = unused_probe_list[j]->locations[k]->str();
x.compiled = 0;
increment_element(db, x);
}
}
}
}
void
sql_update_used_functions(sqlite3 *db, systemtap_session &s)
{
for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
struct source_loc place = it->second->tok->location;
coverage_element x(place);
x.type = db_type_function;
x.name = it->second->name;
x.compiled = 1;
increment_element(db, x);
}
}
void
sql_update_unused_functions(sqlite3 *db, systemtap_session &s)
{
for (unsigned i=0; i<s.unused_functions.size(); i++) {
struct source_loc place = s.unused_functions[i]->tok->location;
coverage_element x(place);
x.type = db_type_function;
x.name = s.unused_functions[i]->name;
x.compiled = 0;
increment_element(db, x);
}
}
void
sql_update_used_globals(sqlite3 *db, systemtap_session &s)
{
for (unsigned i=0; i<s.globals.size(); i++) {
struct source_loc place = s.globals[i]->tok->location;
coverage_element x(place);
x.type = db_type_global;
x.name = s.globals[i]->name;
x.compiled = 1;
increment_element(db, x);
}
}
void
sql_update_unused_globals(sqlite3 *db, systemtap_session &s)
{
for (unsigned i=0; i<s.unused_globals.size(); i++) {
struct source_loc place = s.unused_globals[i]->tok->location;
coverage_element x(place);
x.type = db_type_global;
x.name = s.unused_globals[i]->name;
x.compiled = 0;
increment_element(db, x);
}
}
void update_coverage_db(systemtap_session &s)
{
sqlite3 *db;
int rc;
string filename(s.data_path + "/" + s.kernel_release + ".db");
rc = sqlite3_open(filename.c_str(), &db);
if( rc ){
cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
return;
}
sql_stmt(db, "begin");
string create_table("create table counts ("
"file text, line integer, col integer, "
"type text, name text, parent text, "
"compiled integer, executed integer)");
string create_index("create unique index tokens on counts (file, line, col, "
"type, name)");
if (!has_table(db, "counts"))
sql_stmt(db, create_table.c_str());
if (!has_index(db, "tokens"))
sql_stmt(db, create_index.c_str());
sql_update_used_probes(db, s);
sql_update_unused_probes(db, s);
sql_update_used_functions(db, s);
sql_update_unused_functions(db, s);
sql_update_used_globals(db, s);
sql_update_unused_globals(db, s);
sql_stmt(db, "commit");
sqlite3_close(db);
}
#endif