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

Debug.cc File Reference

#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#include <string>
#include "util.h"
#include "Debug.h"
#include "DebugCmds.h"
#include "DbgBreakpoint.h"
#include "Stmt.h"
#include "Func.h"
#include "Scope.h"
#include "PolicyFile.h"

Include dependency graph for Debug.cc:

Include dependency graph

Go to the source code of this file.

Typedefs

typedef yy_buffer_stateYY_BUFFER_STATE

Functions

 PDict (Filemap) g_dbgfilemaps
int debug_msg (const char *fmt,...)
void get_first_statement (Stmt *list, Stmt *&first, Location &loc)
void parse_function_name (vector< ParseLocationRec > &result, ParseLocationRec &plr, const string &s)
vector< ParseLocationRecparse_location_string (const string &s)
int dbg_dispatch_cmd (DebugCmd cmd_code, const vector< string > &args)
void break_signal (int)
int dbg_init_debugger (const char *cmdfile)
int dbg_shutdown_debugger ()
void tokenize (const char *cstr, string &operation, vector< string > &arguments)
int dbg_execute_command (const char *cmd)
char * get_prompt (bool reset_counter=false)
string get_context_description (const Stmt *stmt, const Frame *frame)
int dbg_handle_debug_input ()
bool pre_execute_stmt (Stmt *stmt, Frame *f)
bool post_execute_stmt (Stmt *stmt, Frame *f, Val *result, stmt_flow_type *flow)
YY_BUFFER_STATE bro_scan_string (const char *)
Valdbg_eval_expr (const char *expr)

Variables

bool g_policy_debug = false
DebuggerState g_debugger_state
TraceState g_trace_state
bool step_or_next_pending = false
Framelast_frame
Exprg_curr_debug_expr = 0
YYLTYPE yylloc
int line_number
const char * filename


Typedef Documentation

typedef struct yy_buffer_state* YY_BUFFER_STATE
 

Definition at line 918 of file Debug.cc.


Function Documentation

void break_signal int   ) 
 

Definition at line 422 of file Debug.cc.

References DebuggerState::BreakBeforeNextStmt(), DebuggerState::BreakFromSignal(), and g_debugger_state.

Referenced by dbg_handle_debug_input(), and dbg_init_debugger().

00423         {
00424         g_debugger_state.BreakBeforeNextStmt(true);
00425         g_debugger_state.BreakFromSignal(true);
00426         }

YY_BUFFER_STATE bro_scan_string const char *   ) 
 

Referenced by dbg_eval_expr().

int dbg_dispatch_cmd DebugCmd  cmd_code,
const vector< string > &  args
[static]
 

Definition at line 612 of file Debug.cc.

References args, DebuggerState::BreakBeforeNextStmt(), 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(), dcBacktrace, dcBreak, dcBreakCondition, dcClearBreak, dcContinue, dcDeleteBreak, dcDisableBreak, dcDisplay, dcDown, dcEnableBreak, dcFinish, dcFrame, dcHelp, dcIgnoreBreak, dcInfo, dcList, dcNext, dcPrint, dcQuit, dcStep, dcTrace, dcUndisplay, dcUp, debug_msg(), g_debugger_state, g_frame_stack, last_frame, and step_or_next_pending.

Referenced by dbg_execute_command().

00613         {
00614         switch ( cmd_code ) {
00615         case dcHelp:
00616                 dbg_cmd_help(cmd_code, args);
00617                 break;
00618 
00619         case dcQuit:
00620                 debug_msg("Program Terminating\n");
00621                 exit(0);
00622 
00623         case dcNext:
00624                 g_frame_stack.back()->BreakBeforeNextStmt(true);
00625                 step_or_next_pending = true;
00626                 last_frame = g_frame_stack.back();
00627                 break;
00628 
00629         case dcStep:
00630                 g_debugger_state.BreakBeforeNextStmt(true);
00631                 step_or_next_pending = true;
00632                 last_frame = g_frame_stack.back();
00633                 break;
00634 
00635         case dcContinue:
00636                 g_debugger_state.BreakBeforeNextStmt(false);
00637                 debug_msg("Continuing.\n");
00638                 break;
00639 
00640         case dcFinish:
00641                 g_frame_stack.back()->BreakOnReturn(true);
00642                 g_debugger_state.BreakBeforeNextStmt(false);
00643                 break;
00644 
00645         case dcBreak:
00646                 dbg_cmd_break(cmd_code, args);
00647                 break;
00648 
00649         case dcBreakCondition:
00650                 dbg_cmd_break_condition(cmd_code, args);
00651                 break;
00652 
00653         case dcDeleteBreak:
00654         case dcClearBreak:
00655         case dcDisableBreak:
00656         case dcEnableBreak:
00657         case dcIgnoreBreak:
00658                 dbg_cmd_break_set_state(cmd_code, args);
00659                 break;
00660 
00661         case dcPrint:
00662                 dbg_cmd_print(cmd_code, args);
00663                 break;
00664 
00665         case dcBacktrace:
00666                 return dbg_cmd_backtrace(cmd_code, args);
00667 
00668         case dcFrame:
00669         case dcUp:
00670         case dcDown:
00671                 return dbg_cmd_frame(cmd_code, args);
00672 
00673         case dcInfo:
00674                 return dbg_cmd_info(cmd_code, args);
00675 
00676         case dcList:
00677                 return dbg_cmd_list(cmd_code, args);
00678 
00679         case dcDisplay:
00680         case dcUndisplay:
00681                 debug_msg("Command not yet implemented.\n");
00682                 break;
00683 
00684         case dcTrace:
00685                 return dbg_cmd_trace(cmd_code, args);
00686 
00687         default:
00688                 debug_msg("INTERNAL ERROR: "
00689                 "Got an unknown debugger command in DbgDispatchCmd: %d\n",
00690                 cmd_code);
00691                 return 0;
00692         }
00693 
00694         return 0;
00695         }

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  ) 
 

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_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,
... 
 

Definition at line 65 of file Debug.cc.

References args, and fmt.

00066         {
00067         va_list args;
00068         int retval;
00069 
00070         va_start(args, fmt);
00071         retval = vfprintf(stderr, fmt, args);
00072         va_end(args);
00073 
00074         return retval;
00075         }

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         }

void get_first_statement Stmt list,
Stmt *&  first,
Location loc
 

Definition at line 164 of file Debug.cc.

References Stmt::AsStmtList(), BroObj::GetLocationInfo(), STMT_LIST, StmtList::Stmts(), and Stmt::Tag().

Referenced by parse_function_name().

00165         {
00166         if ( ! list )
00167                 {
00168                 first = 0;
00169                 return;
00170                 }
00171 
00172         first = list;
00173         while ( first->Tag() == STMT_LIST )
00174                 {
00175                 if ( first->AsStmtList()->Stmts()[0] )
00176                         first = first->AsStmtList()->Stmts()[0];
00177                 else
00178                         break;
00179                 }
00180 
00181         loc = *first->GetLocationInfo();
00182         }

char* get_prompt bool  reset_counter = false  )  [static]
 

Definition at line 697 of file Debug.cc.

References safe_snprintf().

Referenced by dbg_handle_debug_input().

00698         {
00699         static char prompt[512];
00700         static int counter = 0;
00701 
00702         if ( reset_counter )
00703                 counter = 0;
00704 
00705         safe_snprintf(prompt, sizeof(prompt), "(Bro [%d]) ", counter++);
00706 
00707         return prompt;
00708         }

void parse_function_name vector< ParseLocationRec > &  result,
ParseLocationRec plr,
const string &  s
[static]
 

Definition at line 184 of file Debug.cc.

References current_module, debug_msg(), ParseLocationRec::filename, Location::filename, Location::first_line, func, get_first_statement(), id, Location::last_line, ParseLocationRec::line, lookup_ID(), make_full_var_name(), option, plrFunction, plrUnknown, ParseLocationRec::stmt, string, and ParseLocationRec::type.

Referenced by parse_location_string().

00186         { // function name
00187         ID* id = lookup_ID(s.c_str(), current_module.c_str());
00188         if ( ! id )
00189                 {
00190                 string fullname = make_full_var_name(current_module.c_str(), s.c_str());
00191                 debug_msg("Function %s not defined.\n", fullname.c_str());
00192                 plr.type = plrUnknown;
00193                 return;
00194                 }
00195 
00196         FuncType* ftype;
00197         if ( ! (ftype = id->Type()->AsFuncType()) )
00198                 {
00199                 debug_msg("Function %s not declared.\n", id->Name());
00200                 plr.type = plrUnknown;
00201                 return;
00202                 }
00203 
00204         if ( ! id->HasVal() )
00205                 {
00206                 debug_msg("Function %s declared but not defined.\n", id->Name());
00207                 plr.type = plrUnknown;
00208                 return;
00209                 }
00210 
00211         const Func* func = id->ID_Val()->AsFunc();
00212         const vector<Stmt*>& bodies = func->GetBodies();
00213 
00214         if ( bodies.size() == 0 )
00215                 {
00216                 debug_msg("Function %s is a built-in function\n", id->Name());
00217                 plr.type = plrUnknown;
00218                 return;
00219                 }
00220 
00221         Stmt* body = 0; // the particular body we care about; 0 = all
00222 
00223         if ( bodies.size() == 1 )
00224                 body = bodies[0];
00225         else
00226                 {
00227                 while ( 1 )
00228                         {
00229                         debug_msg("There are multiple definitions of that event handler.\n"
00230                                  "Please choose one of the following options:\n");
00231                         for ( unsigned int i = 0; i < bodies.size(); ++i )
00232                                 {
00233                                 Stmt* first;
00234                                 Location stmt_loc;
00235                                 get_first_statement(bodies[i], first, stmt_loc);
00236                                 debug_msg("[%d] %s:%d\n", i+1, stmt_loc.filename, stmt_loc.first_line);
00237                                 }
00238 
00239                         debug_msg("[a] All of the above\n");
00240                         debug_msg("[n] None of the above\n");
00241                         debug_msg("Enter your choice: ");
00242 
00243                         char charinput[256];
00244                         if ( ! fgets(charinput, sizeof(charinput) - 1, stdin) )
00245                                 {
00246                                 plr.type = plrUnknown;
00247                                 return;
00248                                 }
00249 
00250                         if ( charinput[strlen(charinput) - 1] == '\n' )
00251                                 charinput[strlen(charinput) - 1] = 0;
00252 
00253                         string input = charinput;
00254 
00255                         if ( input == "a" )
00256                                 break;
00257 
00258                         if ( input == "n" )
00259                                 {
00260                                 plr.type = plrUnknown;
00261                                 return;
00262                                 }
00263 
00264                         int option = atoi(input.c_str());
00265                         if ( option > 0 && option <= (int) bodies.size() )
00266                                 {
00267                                 body = bodies[option - 1];
00268                                 break;
00269                                 }
00270                         }
00271                 }
00272 
00273         plr.type = plrFunction;
00274 
00275         // Find first atomic (non-STMT_LIST) statement
00276         Stmt* first;
00277         Location stmt_loc;
00278 
00279         if ( body )
00280                 {
00281                 get_first_statement(body, first, stmt_loc);
00282                 if ( first )
00283                         {
00284                         plr.stmt = first;
00285                         plr.filename = stmt_loc.filename;
00286                         plr.line = stmt_loc.last_line;
00287                         }
00288                 }
00289 
00290         else
00291                 {
00292                 result.pop_back();
00293                 ParseLocationRec plr;
00294 
00295                 for ( unsigned int i = 0; i < bodies.size(); ++i )
00296                         {
00297                         get_first_statement(bodies[i], first, stmt_loc);
00298                         if ( ! first )
00299                                 continue;
00300 
00301                         plr.type = plrFunction;
00302                         plr.stmt = first;
00303                         plr.filename = stmt_loc.filename;
00304                         plr.line = stmt_loc.last_line;
00305                         result.push_back(plr);
00306                         }
00307                 }
00308         }

vector<ParseLocationRec> parse_location_string const string &  s  ) 
 

Definition at line 310 of file Debug.cc.

References debug_msg(), Location::filename, filename, ParseLocationRec::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 Frame::BreakBeforeNextStmt(), DebuggerState::BreakBeforeNextStmt(), Frame::BreakOnReturn(), debug_msg(), Val::Describe(), ODesc::Description(), FLOW_RETURN, and g_debugger_state.

Referenced by IfStmt::DoExec(), StmtList::Exec(), and EventBodyList::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         }

bool pre_execute_stmt Stmt stmt,
Frame f
 

Definition at line 819 of file Debug.cc.

References Stmt::BPCount(), DebuggerState::BreakBeforeNextStmt(), Frame::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(), StmtList::Exec(), and EventBodyList::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         }

void tokenize const char *  cstr,
string &  operation,
vector< string > &  arguments
 

Definition at line 468 of file Debug.cc.

References len, and string.

Referenced by dbg_execute_command().

00469         {
00470         int num_tokens = 0;
00471         char delim = '\0';
00472         const string str(cstr);
00473 
00474         for ( int i = 0; i < (signed int) str.length(); ++i )
00475                 {
00476                 while ( isspace((unsigned char) str[i]) )
00477                         ++i;
00478 
00479                 int start = i;
00480 
00481                 for ( ; str[i]; ++i )
00482                         {
00483                         if ( str[i] == '\\' )
00484                                 {
00485                                 if ( i < (signed int) str.length() )
00486                                         ++i;
00487                                 }
00488 
00489                         else if ( ! delim && (str[i] == '\'' || str[i] == '"') )
00490                                 delim = str[i];
00491 
00492                         else if ( delim && str[i] == delim )
00493                                 {
00494                                 delim = '\0';
00495                                 ++i;
00496                                 break;
00497                                 }
00498 
00499                         else if ( ! delim && isspace(str[i]) )
00500                                 break;
00501                         }
00502 
00503                 size_t len = i - start;
00504 
00505                 if ( ! num_tokens )
00506                         operation = string(str, start, len);
00507                 else
00508                         arguments.push_back(string(str, start, len));
00509 
00510                 ++num_tokens;
00511                 }
00512         }


Variable Documentation

const char* filename
 

Definition at line 923 of file Debug.cc.

Referenced by add_input_file(), compile(), dbg_eval_expr(), filename_completion_function(), open_file(), Output::Output(), parse_location_string(), pinpoint(), read_history(), search_for_file(), TraceState::SetTraceFile(), write_history(), yywrap(), and FileInfo::~FileInfo().

Expr* g_curr_debug_expr = 0
 

Definition at line 914 of file Debug.cc.

Referenced by dbg_eval_expr(), and yyparse().

DebuggerState g_debugger_state
 

Definition at line 27 of file Debug.cc.

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 = false
 

Definition at line 26 of file Debug.cc.

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

TraceState g_trace_state
 

Definition at line 28 of file Debug.cc.

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

Frame* last_frame [static]
 

Definition at line 35 of file Debug.cc.

Referenced by dbg_dispatch_cmd(), and dbg_handle_debug_input().

int line_number
 

Definition at line 922 of file Debug.cc.

bool step_or_next_pending = false [static]
 

Definition at line 34 of file Debug.cc.

Referenced by dbg_dispatch_cmd(), and dbg_handle_debug_input().

YYLTYPE yylloc
 

Definition at line 921 of file Debug.cc.


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