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

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

Go to the source code of this file.
|
|
|
|
|
|
|
|
Definition at line 17 of file Debug.h.
00017 { plrUnknown, plrFileAndLine, plrFunction };
|
|
|
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 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 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 }
|
|
|
|
|
||||||||||||||||||||
|
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 }
|
|
|
|
|
||||||||||||
|
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 }
|
|
|
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(). |
|
|
|
|
|
|
Definition at line 127 of file Debug.h. Referenced by dbg_init_debugger(), main(), and pre_execute_stmt(). |
|
|
Definition at line 66 of file Debug.h. Referenced by BroFunc::Call(), BuiltinFunc::Call(), dbg_cmd_trace(), main(), and pre_execute_stmt(). |
1.3.5