Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

Debug.h File Reference

#include <vector>
#include <map>
#include <string>
#include "Expr.h"
#include "Var.h"
#include "Frame.h"
#include "Queue.h"
#include "Dict.h"
#include "StmtEnums.h"
#include "DbgBreakpoint.h"

Include dependency graph for Debug.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Classes

class  DebuggerState
struct  ParseLocationRec
class  StmtLocMapping
class  TraceState

Typedefs

typedef map< int, DbgBreakpoint * > BPIDMapType
typedef multimap< const Stmt *,
DbgBreakpoint * > 
BPMapType

Enumerations

enum  ParseLocationRecType { plrUnknown, plrFileAndLine, plrFunction }

Functions

 declare (PQueue, StmtLocMapping)
typedef PQueue (StmtLocMapping) Filemap
 declare (PDict, Filemap)
vector< ParseLocationRecparse_location_string (const string &s)
bool pre_execute_stmt (Stmt *stmt, Frame *f)
bool post_execute_stmt (Stmt *stmt, Frame *f, Val *result, stmt_flow_type *flow)
int dbg_init_debugger (const char *cmdfile=0)
int dbg_shutdown_debugger ()
int dbg_handle_debug_input ()
int dbg_execute_command (const char *cmd)
Valdbg_eval_expr (const char *expr)
int dbg_read_internal_state ()
string get_context_description (const Stmt *stmt, const Frame *frame)
 PDict (Filemap) g_dbgfilemaps
int debug_msg (const char *fmt,...) __attribute__((format(printf

Variables

string current_module
TraceState g_trace_state
bool g_policy_debug
DebuggerState g_debugger_state
Frameg_dbg_locals


Typedef Documentation

typedef map<int, DbgBreakpoint*> BPIDMapType
 

Definition at line 43 of file Debug.h.

typedef multimap<const Stmt*, DbgBreakpoint*> BPMapType
 

Definition at line 44 of file Debug.h.


Enumeration Type Documentation

enum ParseLocationRecType
 

Enumeration values:
plrUnknown 
plrFileAndLine 
plrFunction 

Definition at line 17 of file Debug.h.


Function Documentation

Val* dbg_eval_expr const char *  expr  ) 
 

Definition at line 925 of file Debug.cc.

References bro_scan_string(), DebuggerState::curr_frame_idx, Expr::Eval(), filename, YYLTYPE::first_line, func, g_curr_debug_expr, g_debugger_state, g_frame_stack, Frame::GetFunction(), internal_error(), YYLTYPE::last_line, line_number, pop_scope(), push_existing_scope(), string, yylloc, and yyparse.

Referenced by dbg_cmd_print(), and DbgBreakpoint::HasHit().

00926         {
00927         // Push the current frame's associated scope.
00928         // Note: g_debugger_state.curr_frame_idx is the user-visible number,
00929         //       while the array index goes in the opposite direction
00930         int frame_idx =
00931                 (g_frame_stack.size() - 1) - g_debugger_state.curr_frame_idx;
00932 
00933         if ( ! (frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size())  )
00934                 internal_error("Assertion failed: %s", "frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size()");
00935 
00936         Frame* frame = g_frame_stack[frame_idx];
00937         if ( ! (frame)  )
00938                 internal_error("Assertion failed: %s", "frame");
00939 
00940         const BroFunc* func = frame->GetFunction();
00941         if ( func )
00942                 push_existing_scope(func->GetScope());
00943 
00944         // ### Possibly push a debugger-local scope?
00945 
00946         // Set up the lexer to read from the string.
00947         string parse_string = string("@DEBUG ") + expr;
00948         bro_scan_string(parse_string.c_str());
00949 
00950         // Fix filename and line number for the lexer/parser, which record it.
00951         filename = "<interactive>";
00952         line_number = 1;
00953         yylloc.filename = filename;
00954         yylloc.first_line = yylloc.last_line = line_number = 1;
00955 
00956         // Parse the thing into an expr.
00957         Val* result = 0;
00958         if ( yyparse() )
00959                 {
00960                 if ( g_curr_debug_expr )
00961                         {
00962                         delete g_curr_debug_expr;
00963                         g_curr_debug_expr = 0;
00964                         }
00965                 }
00966         else
00967                 result = g_curr_debug_expr->Eval(frame);
00968 
00969         if ( func )
00970                 pop_scope();
00971 
00972         delete g_curr_debug_expr;
00973         g_curr_debug_expr = 0;
00974 
00975         return result;
00976         }

int dbg_execute_command const char *  cmd  ) 
 

Definition at line 516 of file Debug.cc.

References add_history(), copy_string(), _hist_entry::data, dbg_dispatch_cmd(), dcInvalid, debug_msg(), DebugCmd, find_all_matching_cmds(), get_debug_cmd_info(), HIST_ENTRY, history_get(), history_length, int, internal_error(), _hist_entry::line, num_debug_cmds, DebugCmdInfo::Repeatable(), DebugCmdInfo::ResumeExecution(), streq(), string, and tokenize().

Referenced by dbg_handle_debug_input().

00517         {
00518         bool matched_history = false;
00519 
00520         if ( ! cmd )
00521                 return 0;
00522 
00523         if ( streq(cmd, "") ) // do the GDB command completion
00524                 {
00525 #ifdef HAVE_READLINE
00526                 int i;
00527                 for ( i = history_length; i >= 1; --i )
00528                         {
00529                         HIST_ENTRY* entry = history_get(i);
00530                         if ( ! entry )
00531                                 return 0;
00532 
00533                         const DebugCmdInfo* info =
00534                                 (const DebugCmdInfo*) entry->data;
00535 
00536                         if ( info && info->Repeatable() )
00537                                 {
00538                                 cmd = entry->line;
00539                                 matched_history = true;
00540                                 break;
00541                                 }
00542                         }
00543 #endif
00544 
00545                 if ( ! matched_history )
00546                         return 0;
00547                 }
00548 
00549         char* localcmd = copy_string(cmd);
00550 
00551         string opstring;
00552         vector<string> arguments;
00553         tokenize(localcmd, opstring, arguments);
00554 
00555         delete [] localcmd;
00556 
00557         // Make sure we know this op name.
00558         const char* matching_cmds[num_debug_cmds()];
00559         int num_matches = find_all_matching_cmds(opstring, matching_cmds);
00560 
00561         if ( ! num_matches )
00562                 {
00563                 debug_msg("No Matching command for '%s'.\n", opstring.c_str());
00564                 return 0;
00565                 }
00566 
00567         if ( num_matches > 1 )
00568                 {
00569                 debug_msg("Ambiguous command; could be\n");
00570 
00571                 for ( int i = 0; i < num_debug_cmds(); ++i )
00572                         if ( matching_cmds[i] )
00573                                 debug_msg("\t%s\n", matching_cmds[i]);
00574 
00575                 return 0;
00576                 }
00577 
00578         // Matched exactly one command: find out which one.
00579         DebugCmd cmd_code = dcInvalid;
00580         for ( int i = 0; i < num_debug_cmds(); ++i )
00581                 if ( matching_cmds[i] )
00582                         {
00583                         cmd_code = (DebugCmd) i;
00584                         break;
00585                         }
00586 
00587 #ifdef HAVE_READLINE
00588         // Insert command into history.
00589         if ( ! matched_history && cmd && *cmd )
00590                 add_history(cmd, (void *) get_debug_cmd_info(cmd_code));
00591 #endif
00592 
00593         if ( int(cmd_code) >= num_debug_cmds() )
00594                 internal_error("Assertion failed: %s", "int(cmd_code) < num_debug_cmds()");
00595 
00596         // Dispatch to the op-specific handler (with args).
00597         int retcode = dbg_dispatch_cmd(cmd_code, arguments);
00598         if ( retcode < 0 )
00599                 return retcode;
00600 
00601         const DebugCmdInfo* info = get_debug_cmd_info(cmd_code);
00602         if ( ! info  )
00603                 internal_error("Assertion failed: %s", "info");
00604 
00605         if ( ! info )
00606                 return -2;      // ### yuck, why -2?
00607 
00608         return info->ResumeExecution();
00609         }

int dbg_handle_debug_input  ) 
 

Definition at line 736 of file Debug.cc.

References DebuggerState::already_did_list, break_signal(), DebuggerState::BreakFromSignal(), DebuggerState::curr_frame_idx, current_module, dbg_execute_command(), debug_msg(), Location::filename, Location::first_line, func, g_debugger_state, g_frame_stack, get_context_description(), get_prompt(), Frame::GetFunction(), BroObj::GetLocationInfo(), Frame::GetNextStmt(), GLOBAL_MODULE_NAME, internal_error(), last_frame, Location::last_line, DebuggerState::last_loc, printf(), PrintLines(), readline(), safe_malloc(), signal, step_or_next_pending, and string.

Referenced by pre_execute_stmt().

00737         {
00738         static char* input_line = 0;
00739         int status = 0;
00740 
00741         if ( g_debugger_state.BreakFromSignal() )
00742                 {
00743                 debug_msg("Program received signal SIGINT: entering debugger\n");
00744 
00745                 g_debugger_state.BreakFromSignal(false);
00746                 }
00747 
00748         Frame* curr_frame = g_frame_stack.back();
00749         const BroFunc* func = curr_frame->GetFunction();
00750         if ( func )
00751                 current_module = func->GetID()->ModuleName();
00752         else
00753                 current_module = GLOBAL_MODULE_NAME;
00754 
00755         const Stmt* stmt = curr_frame->GetNextStmt();
00756         if ( ! stmt )
00757                 internal_error("Assertion failed: %s", "stmt != 0");
00758 
00759         const Location loc = *stmt->GetLocationInfo();
00760 
00761         if ( ! step_or_next_pending || g_frame_stack.back() != last_frame )
00762                 {
00763                 string context =
00764                         get_context_description(stmt, g_frame_stack.back());
00765                 debug_msg("%s\n", context.c_str());
00766                 }
00767 
00768         step_or_next_pending = false;
00769 
00770         PrintLines(loc.filename, loc.first_line,
00771                         loc.last_line - loc.first_line + 1, true);
00772         g_debugger_state.last_loc = loc;
00773 
00774         do
00775                 {
00776                 // readline returns a pointer to a buffer it allocates; it's
00777                 // freed at the bottom.
00778 #ifdef HAVE_READLINE
00779                 input_line = readline(get_prompt());
00780 #else
00781                 printf ("%s", get_prompt());
00782 
00783                 // readline uses malloc, and we want to be consistent
00784                 // with it.
00785                 input_line = (char*) safe_malloc(1024);
00786                 input_line[1023] = 0;
00787                 // ### Maybe it's not always stdin.
00788                 fgets(input_line, sizeof(input_line) - 1, stdin);
00789 #endif
00790 
00791                 // ### Maybe not stdin; maybe do better cleanup.
00792                 if ( feof(stdin) )
00793                         exit(0);
00794 
00795                 status = dbg_execute_command(input_line);
00796 
00797                 if ( input_line )
00798                         {
00799                         free(input_line);       // this was malloc'ed
00800                         input_line = 0;
00801                         }
00802                 else
00803                         exit(0);
00804                 }
00805         while ( status == 0 );
00806 
00807         // Clear out some state. ### Is there a better place?
00808         g_debugger_state.curr_frame_idx = 0;
00809         g_debugger_state.already_did_list = false;
00810 
00811         signal(SIGINT, &break_signal);
00812         signal(SIGTERM, &break_signal);
00813 
00814         return 0;
00815         }

int dbg_init_debugger const char *  cmdfile = 0  ) 
 

Definition at line 428 of file Debug.cc.

References break_signal(), DebuggerState::BreakBeforeNextStmt(), debug_msg(), g_debugger_state, g_policy_debug, init_global_dbg_constants(), and signal.

Referenced by main().

00429         {
00430         if ( ! g_policy_debug )
00431                 return 0;       // probably shouldn't have been called
00432 
00433         init_global_dbg_constants();
00434 
00435         // Hit the debugger before running anything.
00436         g_debugger_state.BreakBeforeNextStmt(true);
00437 
00438         if ( cmdfile )
00439                 // ### Implement this
00440                 debug_msg("Command files not supported. Using interactive mode.\n");
00441 
00442         // ### if ( interactive ) (i.e., not reading cmds from a file)
00443 #ifdef HAVE_READLINE
00444         init_readline();
00445 #endif
00446 
00447         signal(SIGINT, &break_signal);
00448         signal(SIGTERM, break_signal);
00449 
00450         return 1;
00451         }

int dbg_read_internal_state  ) 
 

int dbg_shutdown_debugger  ) 
 

Definition at line 453 of file Debug.cc.

00454         {
00455         // ### TODO: Remove signal handlers
00456         return 1;
00457         }

int debug_msg const char *  fmt,
... 
 

Referenced by EnumType::AddName(), choose_global_symbols_regex(), dbg_backtrace_internal(), dbg_cmd_backtrace(), dbg_cmd_break(), dbg_cmd_break_condition(), dbg_cmd_break_set_state(), dbg_cmd_frame(), dbg_cmd_help(), dbg_cmd_info(), dbg_cmd_list(), dbg_cmd_print(), dbg_cmd_trace(), dbg_dispatch_cmd(), dbg_execute_command(), dbg_handle_debug_input(), dbg_init_debugger(), NetSessions::DoNextPacket(), DbgBreakpoint::HasHit(), how_many_lines_in(), LoadPolicyFileText(), lookup_global_symbols_regex(), TCP_Connection::NextPacket(), parse_function_name(), parse_location_string(), post_execute_stmt(), DbgBreakpoint::PrintHitMsg(), PrintLines(), DbgBreakpoint::Reset(), and DbgBreakpoint::SetLocation().

declare PDict  ,
Filemap 
 

declare PQueue  ,
StmtLocMapping 
 

string get_context_description const Stmt stmt,
const Frame frame
 

Definition at line 710 of file Debug.cc.

References ODesc::Add(), ODesc::Description(), Location::filename, func, Frame::GetFuncArgs(), Frame::GetFunction(), BroObj::GetLocationInfo(), Location::last_line, safe_snprintf(), and string.

Referenced by dbg_backtrace_internal(), and dbg_handle_debug_input().

00711         {
00712         char buf[1024];
00713         ODesc d;
00714         const BroFunc* func = frame->GetFunction();
00715 
00716         if ( func )
00717                 func->DescribeDebug(&d, frame->GetFuncArgs());
00718         else
00719                 d.Add("<unknown function>", 0);
00720 
00721         Location loc;
00722         if ( stmt )
00723                 loc = *stmt->GetLocationInfo();
00724         else
00725                 {
00726                 loc.filename = "<no filename>";
00727                 loc.last_line = 0;
00728                 }
00729 
00730         safe_snprintf(buf, sizeof(buf), "In %s at %s:%d",
00731                       d.Description(), loc.filename, loc.last_line);
00732 
00733         return string(buf);
00734         }

vector<ParseLocationRec> parse_location_string const string &  s  ) 
 

Definition at line 310 of file Debug.cc.

References debug_msg(), ParseLocationRec::filename, filename, Location::filename, Location::first_line, g_debugger_state, how_many_lines_in(), internal_error(), Location::last_line, DebuggerState::last_loc, ParseLocationRec::line, StmtLocMapping::Loc(), loop_over_queue, parse_function_name(), plrFileAndLine, plrUnknown, search_for_file(), sscanf(), StmtLocMapping::Statement(), ParseLocationRec::stmt, string, and ParseLocationRec::type.

Referenced by dbg_cmd_break(), and dbg_cmd_list().

00311         {
00312         vector<ParseLocationRec> result;
00313         result.push_back(ParseLocationRec());
00314         ParseLocationRec& plr = result[0];
00315         const char* full_filename = 0;
00316 
00317         // If plrFileAndLine, set this to the filename you want; for
00318         // memory management reasons, the real filename is set when looking
00319         // up the line number to find the corresponding statement.
00320         const char* loc_filename = 0;
00321 
00322         if ( sscanf(s.c_str(), "%d", &plr.line) )
00323                 { // just a line number (implicitly referring to the current file)
00324                 loc_filename = g_debugger_state.last_loc.filename;
00325                 plr.type = plrFileAndLine;
00326                 }
00327 
00328         else
00329                 {
00330                 string::size_type pos_colon = s.find(':');
00331                 string::size_type pos_dblcolon = s.find("::");
00332 
00333                 if ( pos_colon == string::npos || pos_dblcolon != string::npos )
00334                         parse_function_name(result, plr, s);
00335                 else
00336                         { // file:line
00337                         string filename = s.substr(0, pos_colon);
00338                         string line_string = s.substr(pos_colon + 1, s.length() - pos_colon);
00339 
00340                         if ( ! sscanf(line_string.c_str(), "%d", &plr.line) )
00341                                 plr.type = plrUnknown;
00342 
00343                         FILE* throwaway = search_for_file(filename.c_str(), "bro",
00344                                                                 &full_filename);
00345                         if ( ! throwaway )
00346                                 {
00347                                 debug_msg("No such policy file: %s.\n", filename.c_str());
00348                                 plr.type = plrUnknown;
00349                                 return result;
00350                                 }
00351 
00352                         fclose(throwaway);
00353 
00354                         loc_filename = full_filename;
00355                         plr.type = plrFileAndLine;
00356                         }
00357                 }
00358 
00359         if ( plr.type == plrFileAndLine )
00360                 {
00361                 Filemap* map = g_dbgfilemaps.Lookup(loc_filename);
00362                 if ( ! map )
00363                         internal_error("Policy file %s should have been loaded\n",
00364                                         loc_filename);
00365 
00366                 if ( plr.line > how_many_lines_in(loc_filename) )
00367                         {
00368                         debug_msg("No line %d in %s.\n", plr.line, loc_filename);
00369                         delete [] full_filename;
00370                         plr.type = plrUnknown;
00371                         return result;
00372                         }
00373 
00374                 StmtLocMapping* hit = 0;
00375                 loop_over_queue(*map, i)
00376                         {
00377                         StmtLocMapping* entry = (*map)[i];
00378                         plr.filename = (*map)[i]->Loc().filename;
00379 
00380                         if ( entry->Loc().first_line > plr.line )
00381                                 break;
00382 
00383                         if ( plr.line >= entry->Loc().first_line &&
00384                              plr.line <= entry->Loc().last_line )
00385                                 {
00386                                 hit = (*map)[i];
00387                                 break;
00388                                 }
00389                         }
00390 
00391                 if ( hit )
00392                         plr.stmt = hit->Statement();
00393                 else
00394                         plr.stmt = 0;
00395                 }
00396 
00397         delete [] full_filename;
00398         return result;
00399         }

PDict Filemap   ) 
 

bool post_execute_stmt Stmt stmt,
Frame f,
Val result,
stmt_flow_type flow
 

Definition at line 884 of file Debug.cc.

References DebuggerState::BreakBeforeNextStmt(), Frame::BreakBeforeNextStmt(), Frame::BreakOnReturn(), debug_msg(), Val::Describe(), ODesc::Description(), FLOW_RETURN, and g_debugger_state.

Referenced by IfStmt::DoExec(), EventBodyList::Exec(), and StmtList::Exec().

00885         {
00886         // Handle the case where someone issues a "next" debugger command,
00887         // but we're at a return statement, so the next statement is in
00888         // some other function.
00889         if ( *flow == FLOW_RETURN && f->BreakBeforeNextStmt() )
00890                 g_debugger_state.BreakBeforeNextStmt(true);
00891 
00892         // Handle "finish" commands.
00893         if ( *flow == FLOW_RETURN && f->BreakOnReturn() )
00894                 {
00895                 if ( result )
00896                         {
00897                         ODesc d;
00898                         result->Describe(&d);
00899                         debug_msg("Return Value: '%s'\n", d.Description());
00900                         }
00901                 else
00902                         debug_msg("Return Value: <none>\n");
00903 
00904                 g_debugger_state.BreakBeforeNextStmt(true);
00905                 f->BreakOnReturn(false);
00906                 }
00907 
00908         return true;
00909         }

typedef PQueue StmtLocMapping   ) 
 

bool pre_execute_stmt Stmt stmt,
Frame f
 

Definition at line 819 of file Debug.cc.

References Stmt::BPCount(), Frame::BreakBeforeNextStmt(), DebuggerState::BreakBeforeNextStmt(), DebuggerState::breakpoint_map, dbg_handle_debug_input(), Stmt::Describe(), ODesc::Description(), TraceState::DoTrace(), g_debugger_state, g_policy_debug, g_trace_state, internal_error(), len, TraceState::LogTrace(), p, STMT_LIST, and Stmt::Tag().

Referenced by IfStmt::DoExec(), EventBodyList::Exec(), and StmtList::Exec().

00820         {
00821         if ( ! g_policy_debug ||
00822              stmt->Tag() == STMT_LIST || stmt->Tag() == STMT_NULL )
00823                 return true;
00824 
00825         if ( g_trace_state.DoTrace() )
00826                 {
00827                 ODesc d;
00828                 stmt->Describe(&d);
00829 
00830                 const char* desc = d.Description();
00831                 const char* s = strchr(desc, '\n');
00832 
00833                 int len;
00834                 if ( s )
00835                         len = s - desc;
00836                 else
00837                         len = strlen(desc);
00838 
00839                 g_trace_state.LogTrace("%*s\n", len, desc);
00840                 }
00841 
00842         bool should_break = false;
00843 
00844         if ( g_debugger_state.BreakBeforeNextStmt() ||
00845              f->BreakBeforeNextStmt() )
00846                 {
00847                 if ( g_debugger_state.BreakBeforeNextStmt() )
00848                         g_debugger_state.BreakBeforeNextStmt(false);
00849 
00850                 if ( f->BreakBeforeNextStmt() )
00851                         f->BreakBeforeNextStmt(false);
00852 
00853                 should_break = true;
00854                 }
00855 
00856         if ( stmt->BPCount() )
00857                 {
00858                 pair<BPMapType::iterator, BPMapType::iterator> p;
00859 
00860                 p = g_debugger_state.breakpoint_map.equal_range(stmt);
00861 
00862                 if ( p.first == p.second )
00863                         internal_error("Breakpoint count nonzero, but no matching breakpoints");
00864 
00865                 for ( BPMapType::iterator i = p.first; i != p.second; ++i )
00866                         {
00867                         int break_code = i->second->ShouldBreak(stmt);
00868                         if ( break_code == 2 )  // ### 2?
00869                                 {
00870                                 i->second->SetEnable(false);
00871                                 delete i->second;
00872                                 }
00873 
00874                         should_break = should_break || break_code;
00875                         }
00876                 }
00877 
00878         if ( should_break )
00879                 dbg_handle_debug_input();
00880 
00881         return true;
00882         }


Variable Documentation

string current_module
 

Definition at line 46 of file Debug.h.

Referenced by dbg_handle_debug_input(), EventHandler::FType(), parse_function_name(), DbgBreakpoint::SetLocation(), yyparse(), and FileInfo::~FileInfo().

Frame* g_dbg_locals
 

Definition at line 181 of file Debug.h.

DebuggerState g_debugger_state
 

Definition at line 128 of file Debug.h.

Referenced by DbgBreakpoint::AddToGlobalMap(), break_signal(), dbg_cmd_break(), dbg_cmd_break_condition(), dbg_cmd_break_set_state(), dbg_cmd_frame(), dbg_cmd_info(), dbg_cmd_list(), dbg_dispatch_cmd(), dbg_eval_expr(), dbg_handle_debug_input(), dbg_init_debugger(), parse_location_string(), post_execute_stmt(), pre_execute_stmt(), DbgBreakpoint::RemoveFromGlobalMap(), and DbgBreakpoint::ShouldBreak().

bool g_policy_debug
 

Definition at line 127 of file Debug.h.

Referenced by dbg_init_debugger(), main(), and pre_execute_stmt().

TraceState g_trace_state
 

Definition at line 66 of file Debug.h.

Referenced by BroFunc::Call(), BuiltinFunc::Call(), dbg_cmd_trace(), main(), and pre_execute_stmt().


Generated on Wed Sep 14 02:58:43 2005 for bro_docs by doxygen 1.3.5