LCOV - code coverage report
Current view: top level - src - DbgBreakpoint.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2 161 1.2 %
Date: 2010-12-13 Functions: 2 24 8.3 %
Branches: 2 90 2.2 %

           Branch data     Line data    Source code
       1                 :            : // $Id: DbgBreakpoint.cc 1345 2005-09-08 07:42:11Z vern $
       2                 :            : 
       3                 :            : // Implementation of breakpoints.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include <assert.h>
       8                 :            : 
       9                 :            : #include "ID.h"
      10                 :            : #include "Queue.h"
      11                 :            : #include "Debug.h"
      12                 :            : #include "Scope.h"
      13                 :            : #include "Func.h"
      14                 :            : #include "Stmt.h"
      15                 :            : #include "DbgBreakpoint.h"
      16                 :            : #include "Timer.h"
      17                 :            : 
      18                 :            : 
      19                 :            : // BreakpointTimer used for time-based breakpoints
      20 [ #  # ][ #  # ]:          0 : class BreakpointTimer : public Timer {
      21                 :            : public:
      22                 :            :         BreakpointTimer(DbgBreakpoint* arg_bp, double arg_t)
      23                 :            :                 : Timer(arg_t, TIMER_BREAKPOINT)
      24                 :            :                         { bp = arg_bp; }
      25                 :            : 
      26                 :            :         void Dispatch(double t, int is_expire);
      27                 :            : 
      28                 :            : protected:
      29                 :            :         DbgBreakpoint* bp;
      30                 :            : };
      31                 :            : 
      32                 :          0 : void BreakpointTimer::Dispatch(double t, int is_expire)
      33                 :            :         {
      34         [ #  # ]:          0 :         if ( is_expire )
      35                 :          0 :                 return;
      36                 :            : 
      37                 :          0 :         bp->ShouldBreak(t);
      38                 :            :         }
      39                 :            : 
      40                 :            : 
      41                 :          0 : DbgBreakpoint::DbgBreakpoint()
      42                 :            :         {
      43                 :          0 :         kind = BP_STMT;
      44                 :            : 
      45                 :          0 :         enabled = temporary = false;
      46                 :          0 :         BPID = -1;
      47                 :            : 
      48                 :          0 :         at_stmt = 0;
      49                 :          0 :         at_time = -1.0;
      50                 :            : 
      51                 :          0 :         repeat_count = hit_count = 0;
      52                 :            : 
      53                 :          0 :         description[0] = 0;
      54                 :          0 :         }
      55                 :            : 
      56                 :          0 : DbgBreakpoint::~DbgBreakpoint()
      57                 :            :         {
      58                 :          0 :         SetEnable(false);       // clean up any active state
      59                 :          0 :         RemoveFromGlobalMap();
      60                 :          0 :         }
      61                 :            : 
      62                 :          0 : bool DbgBreakpoint::SetEnable(bool do_enable)
      63                 :            :         {
      64                 :          0 :         bool old_value = enabled;
      65                 :          0 :         enabled = do_enable;
      66                 :            : 
      67                 :            :         // Update statement counts.
      68 [ #  # ][ #  # ]:          0 :         if ( do_enable && ! old_value )
      69                 :          0 :                 AddToStmt();
      70                 :            : 
      71 [ #  # ][ #  # ]:          0 :         else if ( ! do_enable && old_value )
      72                 :          0 :                 RemoveFromStmt();
      73                 :            : 
      74                 :          0 :         return old_value;
      75                 :            :         }
      76                 :            : 
      77                 :          0 : void DbgBreakpoint::AddToGlobalMap()
      78                 :            :         {
      79                 :            :         // Make sure it's not there already.
      80                 :          0 :         RemoveFromGlobalMap();
      81                 :            : 
      82                 :          0 :         g_debugger_state.breakpoint_map.insert(BPMapType::value_type(at_stmt, this));
      83                 :          0 :         }
      84                 :            : 
      85                 :          0 : void DbgBreakpoint::RemoveFromGlobalMap()
      86                 :            :         {
      87                 :          0 :         pair<BPMapType::iterator, BPMapType::iterator> p;
      88                 :          0 :         p = g_debugger_state.breakpoint_map.equal_range(at_stmt);
      89                 :            : 
      90         [ #  # ]:          0 :         for ( BPMapType::iterator i = p.first; i != p.second; ++i )
      91                 :            :                 {
      92         [ #  # ]:          0 :                 if ( i->second == this )
      93                 :          0 :                         g_debugger_state.breakpoint_map.erase(i);
      94                 :            :                 }
      95                 :          0 :         }
      96                 :            : 
      97                 :          0 : void DbgBreakpoint::AddToStmt()
      98                 :            :         {
      99         [ #  # ]:          0 :         if ( at_stmt )
     100                 :          0 :                 at_stmt->IncrBPCount();
     101                 :          0 :         }
     102                 :            : 
     103                 :          0 : void DbgBreakpoint::RemoveFromStmt()
     104                 :            :         {
     105         [ #  # ]:          0 :         if ( at_stmt )
     106                 :          0 :                 at_stmt->DecrBPCount();
     107                 :          0 :         }
     108                 :            : 
     109                 :            : 
     110                 :          0 : bool DbgBreakpoint::SetLocation(ParseLocationRec plr, string loc_str)
     111                 :            :         {
     112         [ #  # ]:          0 :         if ( plr.type == plrUnknown )
     113                 :            :                 {
     114                 :          0 :                 debug_msg("Breakpoint specifier invalid or operation canceled.\n");
     115                 :          0 :                 return false;
     116                 :            :                 }
     117                 :            : 
     118         [ #  # ]:          0 :         if ( plr.type == plrFileAndLine )
     119                 :            :                 {
     120                 :          0 :                 kind = BP_LINE;
     121                 :          0 :                 source_filename = plr.filename;
     122                 :          0 :                 source_line = plr.line;
     123                 :            : 
     124         [ #  # ]:          0 :                 if ( ! plr.stmt )
     125                 :            :                         {
     126                 :          0 :                         debug_msg("No statement at that line.\n");
     127                 :          0 :                         return false;
     128                 :            :                         }
     129                 :            : 
     130                 :          0 :                 at_stmt = plr.stmt;
     131                 :            :                 safe_snprintf(description, sizeof(description), "%s:%d",
     132                 :          0 :                               source_filename, source_line);
     133                 :            : 
     134                 :          0 :                 debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
     135                 :            :                 }
     136                 :            : 
     137         [ #  # ]:          0 :         else if ( plr.type == plrFunction )
     138                 :            :                 {
     139                 :          0 :                 kind = BP_FUNC;
     140                 :            :                 function_name = make_full_var_name(current_module.c_str(),
     141                 :          0 :                                                         loc_str.c_str());
     142                 :          0 :                 at_stmt = plr.stmt;
     143                 :          0 :                 const Location* loc = at_stmt->GetLocationInfo();
     144                 :            :                 safe_snprintf(description, sizeof(description), "%s at %s:%d",
     145                 :          0 :                               function_name.c_str(), loc->filename, loc->last_line);
     146                 :            : 
     147                 :          0 :                 debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
     148                 :            :                 }
     149                 :            : 
     150                 :          0 :         SetEnable(true);
     151                 :          0 :         AddToGlobalMap();
     152                 :          0 :         return true;
     153                 :            :         }
     154                 :            : 
     155                 :          0 : bool DbgBreakpoint::SetLocation(Stmt* stmt)
     156                 :            :         {
     157         [ #  # ]:          0 :         if ( ! stmt )
     158                 :          0 :                 return false;
     159                 :            : 
     160                 :          0 :         kind = BP_STMT;
     161                 :          0 :         at_stmt = stmt;
     162                 :            : 
     163                 :          0 :         SetEnable(true);
     164                 :          0 :         AddToGlobalMap();
     165                 :            : 
     166                 :          0 :         const Location* loc = stmt->GetLocationInfo();
     167                 :            :         safe_snprintf(description, sizeof(description), "%s:%d",
     168                 :          0 :                       loc->filename, loc->last_line);
     169                 :            : 
     170                 :          0 :         debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
     171                 :            : 
     172                 :          0 :         return true;
     173                 :            :         }
     174                 :            : 
     175                 :          0 : bool DbgBreakpoint::SetLocation(double t)
     176                 :            :         {
     177                 :          0 :         debug_msg("SetLocation(time) has not been debugged.");
     178                 :          0 :         return false;
     179                 :            : 
     180                 :            :         kind = BP_TIME;
     181                 :            :         at_time = t;
     182                 :            : 
     183                 :            :         timer_mgr->Add(new BreakpointTimer(this, t));
     184                 :            : 
     185                 :            :         debug_msg("Time-based breakpoints not yet supported.\n");
     186                 :            :         return false;
     187                 :            :         }
     188                 :            : 
     189                 :          0 : bool DbgBreakpoint::Reset()
     190                 :            :         {
     191                 :            :         ParseLocationRec plr;
     192                 :            : 
     193      [ #  #  # ]:          0 :         switch ( kind ) {
     194                 :            :         case BP_TIME:
     195                 :          0 :                 debug_msg("Time-based breakpoints not yet supported.\n");
     196                 :          0 :                 break;
     197                 :            : 
     198                 :            :         case BP_FUNC:
     199                 :            :         case BP_STMT:
     200                 :            :         case BP_LINE:
     201                 :          0 :                 plr.type = plrFunction;
     202                 :            :                 //### How to deal with wildcards?
     203                 :            :                 //### perhaps save user choices?--tough...
     204                 :            :                 break;
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         internal_error("DbgBreakpoint::Reset function incomplete.");
     208                 :            :         }
     209                 :            : 
     210                 :          0 : bool DbgBreakpoint::SetCondition(const string& new_condition)
     211                 :            :         {
     212                 :          0 :         condition = new_condition;
     213                 :          0 :         return true;
     214                 :            :         }
     215                 :            : 
     216                 :          0 : bool DbgBreakpoint::SetRepeatCount(int count)
     217                 :            :         {
     218                 :          0 :         repeat_count = count;
     219                 :          0 :         return true;
     220                 :            :         }
     221                 :            : 
     222                 :          0 : BreakCode DbgBreakpoint::HasHit()
     223                 :            :         {
     224         [ #  # ]:          0 :         if ( temporary )
     225                 :            :                 {
     226                 :          0 :                 SetEnable(false);
     227                 :          0 :                 return bcHitAndDelete;
     228                 :            :                 }
     229                 :            : 
     230         [ #  # ]:          0 :         if ( condition.size() )
     231                 :            :                 {
     232                 :            :                 // TODO: ### evaluate using debugger frame too
     233                 :          0 :                 Val* yes = dbg_eval_expr(condition.c_str());
     234                 :            : 
     235         [ #  # ]:          0 :                 if ( ! yes )
     236                 :            :                         {
     237                 :            :                         debug_msg("Breakpoint condition '%s' invalid, removing condition.\n",
     238                 :          0 :                         condition.c_str());
     239                 :          0 :                         SetCondition("");
     240                 :          0 :                         PrintHitMsg();
     241                 :          0 :                         return bcHit;
     242                 :            :                         }
     243                 :            : 
     244 [ #  # ][ #  # ]:          0 :                 if ( ! IsIntegral(yes->Type()->Tag()) &&
         [ #  # ][ #  # ]
                 [ #  # ]
     245                 :            :                      ! IsBool(yes->Type()->Tag()) )
     246                 :            :                         {
     247                 :          0 :                         PrintHitMsg();
     248                 :          0 :                         debug_msg("Breakpoint condition should return an integral type");
     249                 :          0 :                         return bcHitAndDelete;
     250                 :            :                         }
     251                 :            : 
     252                 :          0 :                 yes->CoerceToInt();
     253         [ #  # ]:          0 :                 if ( yes->IsZero() )
     254                 :          0 :                         return bcNoHit;
     255                 :            :                 }
     256                 :            : 
     257                 :          0 :         int repcount = GetRepeatCount();
     258         [ #  # ]:          0 :         if ( repcount )
     259                 :            :                 {
     260         [ #  # ]:          0 :                 if ( ++hit_count == repcount )
     261                 :            :                         {
     262                 :          0 :                         hit_count = 0;
     263                 :          0 :                         PrintHitMsg();
     264                 :          0 :                         return bcHit;
     265                 :            :                         }
     266                 :            : 
     267                 :          0 :                 return bcNoHit;
     268                 :            :                 }
     269                 :            : 
     270                 :          0 :         PrintHitMsg();
     271                 :          0 :         return bcHit;
     272                 :            :         }
     273                 :            : 
     274                 :          0 : BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
     275                 :            :         {
     276         [ #  # ]:          0 :         if ( ! IsEnabled() )
     277                 :          0 :                 return bcNoHit;
     278                 :            : 
     279   [ #  #  #  # ]:          0 :         switch ( kind ) {
     280                 :            :         case BP_STMT:
     281                 :            :         case BP_FUNC:
     282         [ #  # ]:          0 :                 if ( at_stmt != s )
     283                 :          0 :                         return bcNoHit;
     284                 :          0 :                 break;
     285                 :            : 
     286                 :            :         case BP_LINE:
     287 [ #  # ][ #  # ]:          0 :                 assert(s->GetLocationInfo()->first_line <= source_line &&
                 [ #  # ]
     288                 :            :                        s->GetLocationInfo()->last_line >= source_line);
     289                 :          0 :                 break;
     290                 :            : 
     291                 :            :         case BP_TIME:
     292                 :          0 :                 assert(false);
     293                 :            : 
     294                 :            :         default:
     295                 :          0 :                 internal_error("Invalid breakpoint type in DbgBreakpoint::ShouldBreak");
     296                 :            :         }
     297                 :            : 
     298                 :            :         // If we got here, that means that the breakpoint could hit,
     299                 :            :         // except potentially if it has a special condition or a repeat count.
     300                 :            : 
     301                 :          0 :         BreakCode code = HasHit();
     302         [ #  # ]:          0 :         if ( code )
     303                 :          0 :                 g_debugger_state.BreakBeforeNextStmt(true);
     304                 :            : 
     305                 :          0 :         return code;
     306                 :            :         }
     307                 :            : 
     308                 :            : 
     309                 :          0 : BreakCode DbgBreakpoint::ShouldBreak(double t)
     310                 :            :         {
     311         [ #  # ]:          0 :         if ( kind != BP_TIME )
     312                 :          0 :                 internal_error("Calling ShouldBreak(time) on a non-time breakpoint");
     313                 :            : 
     314         [ #  # ]:          0 :         if ( t < at_time )
     315                 :          0 :                 return bcNoHit;
     316                 :            : 
     317         [ #  # ]:          0 :         if ( ! IsEnabled() )
     318                 :          0 :                 return bcNoHit;
     319                 :            : 
     320                 :          0 :         BreakCode code = HasHit();
     321         [ #  # ]:          0 :         if ( code )
     322                 :          0 :                 g_debugger_state.BreakBeforeNextStmt(true);
     323                 :            : 
     324                 :          0 :         return code;
     325                 :            :         }
     326                 :            : 
     327                 :          0 : void DbgBreakpoint::PrintHitMsg()
     328                 :            :         {
     329      [ #  #  # ]:          0 :         switch ( kind ) {
     330                 :            :         case BP_STMT:
     331                 :            :         case BP_FUNC:
     332                 :            :         case BP_LINE:
     333                 :            :                 {
     334                 :          0 :                 ODesc d;
     335                 :          0 :                 Frame* f = g_frame_stack.back();
     336                 :          0 :                 const BroFunc* func = f->GetFunction();
     337                 :            : 
     338         [ #  # ]:          0 :                 if ( func )
     339                 :          0 :                         func->DescribeDebug (&d, f->GetFuncArgs());
     340                 :            : 
     341                 :          0 :                 const Location* loc = at_stmt->GetLocationInfo();
     342                 :            : 
     343                 :            :                 debug_msg("Breakpoint %d, %s at %s:%d\n",
     344                 :            :                          GetID(), d.Description(),
     345                 :          0 :                          loc->filename, loc->first_line);
     346                 :            :                 }
     347                 :            :                 return;
     348                 :            : 
     349                 :            :         case BP_TIME:
     350                 :          0 :                 assert(false);
     351                 :            : 
     352                 :            :         default:
     353                 :          0 :                 internal_error("Missed a case in DbgBreakpoint::PrintHitMsg\n");
     354                 :            :         }
     355 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8