LCOV - code coverage report
Current view: top level - mnt/wasteland/wcohen/systemtap_write/systemtap - tapset-dynprobe.cxx (source / functions) Hit Total Coverage
Test: stap.info Lines: 1 77 1.3 %
Date: 2013-03-08 Functions: 2 18 11.1 %
Branches: 2 128 1.6 %

           Branch data     Line data    Source code
       1                 :            : // Synthetic derived probe group that enables merging probes from
       2                 :            : // difference derived probe groups for dyninst.
       3                 :            : //
       4                 :            : // Copyright (C) 2013 Red Hat Inc.
       5                 :            : //
       6                 :            : // This file is part of systemtap, and is free software.  You can
       7                 :            : // redistribute it and/or modify it under the terms of the GNU General
       8                 :            : // Public License (GPL); either version 2, or (at your option) any
       9                 :            : // later version.
      10                 :            : 
      11                 :            : 
      12                 :            : #include "session.h"
      13                 :            : #include "tapsets.h"
      14                 :            : #include "tapset-dynprobe.h"
      15                 :            : #include "translate.h"
      16                 :            : 
      17                 :            : #include <cstring>
      18                 :            : #include <string>
      19                 :            : 
      20                 :            : using namespace std;
      21                 :            : using namespace __gnu_cxx;
      22                 :            : 
      23                 :            : // ------------------------------------------------------------------------
      24                 :            : // dynprobe derived 'probes': These don't really exist. The purpose of
      25                 :            : // the dynprobe_derived_probe_group is allow multiple
      26                 :            : // *_derived_probe_group classes to output only one set of
      27                 :            : // 'stapdu_target'/'stapdu_probe' arrays. This class also includes
      28                 :            : // "dyninst/uprobes.c" only once and in the correct place.
      29                 :            : // ------------------------------------------------------------------------
      30                 :            : 
      31         [ #  # ]:          0 : struct dynprobe_derived_probe: public derived_probe
      32                 :            : {
      33                 :            :   // Dummy constructor for gcc 3.4 compatibility
      34                 :            :   dynprobe_derived_probe (): derived_probe (0, 0) { assert(0); }
      35                 :            : };
      36                 :            : 
      37                 :            : struct dynprobe_info
      38                 :            : {
      39                 :            :   bool has_path;
      40                 :            :   const Dwarf_Addr offset;
      41                 :            :   const Dwarf_Addr semaphore_addr;
      42                 :            :   const string flags_string;
      43                 :            :   const string probe_init;
      44                 :            : 
      45                 :          0 :   dynprobe_info(bool hp, const Dwarf_Addr o, const Dwarf_Addr sa,
      46                 :            :                 const string fs, const string pi):
      47                 :            :     has_path(hp), offset(o), semaphore_addr(sa), flags_string(fs),
      48         [ #  # ]:          0 :     probe_init(pi) { }
      49                 :            : };
      50                 :            : 
      51 [ #  # ][ #  # ]:          0 : struct dynprobe_derived_probe_group: public generic_dpg<dynprobe_derived_probe>
         [ #  # ][ #  # ]
                 [ #  # ]
      52                 :            : {
      53                 :            : private:
      54                 :            :   map<string, vector<dynprobe_info*> > info_by_path;
      55                 :            :   typedef map<string, vector<dynprobe_info*> >::iterator i_b_path_iterator;
      56                 :            :   map<Dwarf_Addr, vector<dynprobe_info*> > info_by_pid;
      57                 :            :   typedef map<Dwarf_Addr, vector<dynprobe_info*> >::iterator i_b_pid_iterator;
      58                 :            : 
      59                 :            :   void emit_info(systemtap_session& s, unsigned tgt_idx, dynprobe_info *info);
      60                 :            : 
      61                 :            : public:
      62                 :            :   void emit_module_decls (systemtap_session& s);
      63                 :          0 :   void emit_module_init (systemtap_session& ) { }
      64                 :          0 :   void emit_module_post_init (systemtap_session& ) { }
      65                 :          0 :   void emit_module_exit (systemtap_session& ) { }
      66                 :            : 
      67                 :            :   void add(const string& path, const Dwarf_Addr offset,
      68                 :            :            const Dwarf_Addr semaphore_addr, const string& flags_string,
      69                 :            :            const string& probe_init);
      70                 :            : };
      71                 :            : 
      72                 :            : 
      73                 :            : void
      74                 :          0 : dynprobe_derived_probe_group::add(const string& path, const Dwarf_Addr offset,
      75                 :            :                                   const Dwarf_Addr semaphore_addr,
      76                 :            :                                   const string& flags_string,
      77                 :            :                                   const string& probe_init)
      78                 :            : {
      79         [ #  # ]:          0 :   struct dynprobe_info *info = new dynprobe_info(!path.empty(), offset,
      80                 :            :                                                  semaphore_addr,
      81 [ #  # ][ #  # ]:          0 :                                                  flags_string, probe_init);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      82 [ #  # ][ #  # ]:          0 :   if (!path.empty())
      83 [ #  # ][ #  # ]:          0 :     info_by_path[path].push_back(info);
      84                 :            :   else
      85 [ #  # ][ #  # ]:          0 :     info_by_pid[offset].push_back(info);
      86                 :          0 : }
      87                 :            : 
      88                 :            : void
      89                 :          0 : dynprobe_derived_probe_group::emit_info(systemtap_session& s,
      90                 :            :                                         unsigned tgt_idx, dynprobe_info *info)
      91                 :            : {
      92                 :          0 :   s.op->newline() << "{";
      93                 :          0 :   s.op->line() << " .target=" << tgt_idx << ",";
      94                 :            : 
      95                 :            :   // We have to force path vs. pid probes into
      96                 :            :   // stapdu_target/stapdu_probe. So, here's how we'll do it.
      97                 :            :   //
      98                 :            :   // For path probes, stapdu_target will hold the path, and the
      99                 :            :   // stapdu_probe with the correct index will point to it.
     100                 :            :   //
     101                 :            :   // For pid probes, stapdu_target will have an empty path, and the
     102                 :            :   // 'offset' field of stapdu_probe will really be the pid.
     103         [ #  # ]:          0 :   if (info->has_path)
     104 [ #  # ][ #  # ]:          0 :     s.op->line() << " .offset=" << lex_cast_hex(info->offset) << "ULL,";
     105                 :            :   else
     106                 :          0 :     s.op->line() << " .offset=" << info->offset << "ULL/*pid*/,";
     107         [ #  # ]:          0 :   if (info->semaphore_addr)
     108         [ #  # ]:          0 :     s.op->line() << " .semaphore=" << lex_cast_hex(info->semaphore_addr)
     109         [ #  # ]:          0 :                  << "ULL,";
     110                 :          0 :   s.op->line() << " .flags=" << info->flags_string << ",";
     111                 :          0 :   s.op->line() << " .probe=" << info->probe_init << ",";
     112                 :          0 :   s.op->line() << " },";
     113                 :          0 : }
     114                 :            : 
     115                 :            : void
     116                 :          0 : dynprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
     117                 :            : {
     118         [ #  # ]:          0 :   if (! s.runtime_usermode_p())
     119                 :          0 :     return;
     120                 :            : 
     121                 :          0 :   s.op->newline() << "#include \"dyninst/uprobes.h\"";
     122                 :          0 :   s.op->newline() << "static const struct stapdu_target stapdu_targets[] = {";
     123                 :          0 :   s.op->indent(1);
     124 [ #  # ][ #  # ]:          0 :   for (i_b_path_iterator it = info_by_path.begin();
     125         [ #  # ]:          0 :        it != info_by_path.end(); it++)
     126                 :            :     {
     127 [ #  # ][ #  # ]:          0 :       s.op->newline() << "{";
     128 [ #  # ][ #  # ]:          0 :       s.op->line() << " .path=" << lex_cast_qstring(it->first) << ",";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     129 [ #  # ][ #  # ]:          0 :       s.op->line() << " },";
     130                 :            :     }
     131         [ #  # ]:          0 :   if (! info_by_pid.empty())
     132                 :            :     {
     133                 :          0 :       s.op->newline() << "{";
     134                 :          0 :       s.op->line() << " .path=NULL,";
     135                 :          0 :       s.op->line() << " },";
     136                 :            :     }
     137                 :          0 :   s.op->newline(-1) << "};";
     138                 :          0 :   s.op->assert_0_indent();
     139                 :            : 
     140                 :          0 :   s.op->newline() << "static struct stapdu_probe stapdu_probes[] = {";
     141                 :          0 :   s.op->indent(1);
     142                 :          0 :   unsigned tgt_idx = 0;
     143 [ #  # ][ #  # ]:          0 :   for (i_b_path_iterator it = info_by_path.begin();
     144         [ #  # ]:          0 :        it != info_by_path.end(); it++, tgt_idx++)
     145                 :            :     {
     146 [ #  # ][ #  # ]:          0 :       for (unsigned i = 0; i < it->second.size(); i++)
     147                 :            :         {
     148         [ #  # ]:          0 :           dynprobe_info *info = it->second[i];
     149         [ #  # ]:          0 :           emit_info(s, tgt_idx, info);
     150                 :            :         }
     151                 :            :     }
     152         [ #  # ]:          0 :   if (! info_by_pid.empty())
     153                 :            :     {
     154 [ #  # ][ #  # ]:          0 :       for (i_b_pid_iterator it = info_by_pid.begin();
     155         [ #  # ]:          0 :            it != info_by_pid.end(); it++)
     156                 :            :         {
     157 [ #  # ][ #  # ]:          0 :           for (unsigned i = 0; i < it->second.size(); i++)
     158                 :            :             {
     159         [ #  # ]:          0 :               dynprobe_info *info = it->second[i];
     160         [ #  # ]:          0 :               emit_info(s, tgt_idx, info);
     161                 :            :             }
     162                 :            :         }
     163                 :            :     }
     164                 :          0 :   s.op->newline(-1) << "};";
     165                 :          0 :   s.op->assert_0_indent();
     166                 :            : 
     167                 :          0 :   s.op->newline() << "#include \"dyninst/uprobes.c\"";
     168                 :            : }
     169                 :            : 
     170                 :            : 
     171                 :            : // Declare that dynprobes are needed in this session
     172                 :          0 : void enable_dynprobes(systemtap_session& s)
     173                 :            : {
     174         [ #  # ]:          0 :   if (! s.dynprobe_derived_probes)
     175         [ #  # ]:          0 :     s.dynprobe_derived_probes = new dynprobe_derived_probe_group();
     176                 :          0 : }
     177                 :            : 
     178                 :            : void
     179                 :          0 : dynprobe_add_uprobe(systemtap_session& s, const string& path,
     180                 :            :                     const Dwarf_Addr offset, const Dwarf_Addr semaphore_addr,
     181                 :            :                     const string flags_string, const string probe_init)
     182                 :            : {
     183                 :          0 :   enable_dynprobes(s);
     184                 :            :   s.dynprobe_derived_probes->add(path, offset, semaphore_addr, flags_string,
     185                 :          0 :                                  probe_init);
     186                 :          0 : }
     187                 :            :                     
     188                 :            : void
     189                 :          0 : dynprobe_add_utrace_path(systemtap_session& s, const std::string& path,
     190                 :            :                          const std::string flags_string,
     191                 :            :                          const std::string probe_init)
     192                 :            : {
     193                 :          0 :   enable_dynprobes(s);
     194                 :          0 :   s.dynprobe_derived_probes->add(path, 0, 0, flags_string, probe_init);
     195                 :          0 : }
     196                 :            : 
     197                 :            : void
     198                 :          0 : dynprobe_add_utrace_pid(systemtap_session& s, const Dwarf_Addr pid,
     199                 :            :                         const std::string flags_string,
     200                 :            :                         const std::string probe_init)
     201                 :            : {
     202                 :          0 :   enable_dynprobes(s);
     203                 :            :   // Notice we're passing the pid as the offset. Stapdyn is expecting
     204                 :            :   // this when the path is empty.
     205 [ #  # ][ #  # ]:          0 :   s.dynprobe_derived_probes->add("", pid, 0, flags_string, probe_init);
                 [ #  # ]
     206 [ +  - ][ +  - ]:       7242 : }
     207                 :            : 
     208                 :            : /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */

Generated by: LCOV version 1.9