#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:

Go to the source code of this file.
Typedefs | |
| typedef yy_buffer_state * | YY_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< ParseLocationRec > | parse_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 *) |
| Val * | dbg_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 |
| Frame * | last_frame |
| Expr * | g_curr_debug_expr = 0 |
| YYLTYPE | yylloc |
| int | line_number |
| const char * | filename |
|
|
|
|
|
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 }
|
|
|
Referenced by dbg_eval_expr(). |
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 453 of file Debug.cc.
00454 {
00455 // ### TODO: Remove signal handlers
00456 return 1;
00457 }
|
|
||||||||||||
|
Definition at line 65 of file Debug.cc.
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
Definition at line 468 of file Debug.cc. 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 }
|
|
|
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(). |
|
|
Definition at line 914 of file Debug.cc. Referenced by dbg_eval_expr(), and yyparse(). |
|
|
|
Definition at line 26 of file Debug.cc. Referenced by dbg_init_debugger(), main(), and pre_execute_stmt(). |
|
|
Definition at line 28 of file Debug.cc. Referenced by BuiltinFunc::Call(), BroFunc::Call(), dbg_cmd_trace(), main(), and pre_execute_stmt(). |
|
|
Definition at line 35 of file Debug.cc. Referenced by dbg_dispatch_cmd(), and dbg_handle_debug_input(). |
|
|
|
|
|
Definition at line 34 of file Debug.cc. Referenced by dbg_dispatch_cmd(), and dbg_handle_debug_input(). |
|
|
|
1.3.5