LTP GCOV extension - code coverage report
Current view: directory - src - coveragedb.cxx
Test: stap.info
Date: 2008-03-12 Instrumented lines: 166
Code covered: 1.2 % Executed lines: 2

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

Generated by: LTP GCOV extension version 1.5