Exemple #1
0
/********************************
 * Interactive command line
 * debugger
 ********************************/
void Runtime::Debugger::ProcessInstruction(StackInstr* instr, long ip, StackFrame** call_stack,
                                           long call_stack_pos, StackFrame* frame)
{
  if(frame->method->GetClass()) {
    const int line_num = instr->GetLineNumber();
    const wstring &file_name = frame->method->GetClass()->GetFileName();

    // wcout << L"### file=" << file_name << L", line=" << line_num << L" ###" << endl;
    
    if((line_num > -1 && (cur_line_num != line_num || cur_file_name != file_name)) &&
       // break point
       (FindBreak(line_num, file_name) ||
        // step command
        (is_next || (is_jmp_out && call_stack_pos < cur_call_stack_pos)) ||
        // next line
        (is_next_line && ((cur_frame && frame->method == cur_frame->method) ||
													(call_stack_pos < cur_call_stack_pos))))) {
      // set current line
      cur_line_num = line_num;
      cur_file_name = file_name;
      cur_frame = frame;
      cur_call_stack = call_stack;
      cur_call_stack_pos = call_stack_pos;
      is_jmp_out = is_next_line = false;

      // prompt for input
      const wstring &long_name = cur_frame->method->GetName();
      int end_index = long_name.find_last_of(':');
      const wstring &cls_mthd_name = long_name.substr(0, end_index);

      // show break info
      int mid_index = cls_mthd_name.find_last_of(':');
      const wstring &cls_name = cls_mthd_name.substr(0, mid_index);
      const wstring &mthd_name = cls_mthd_name.substr(mid_index + 1);
      wcout << L"break: file='" << file_name << L":" << line_num << L"', method='"
            << cls_name << L"->" << mthd_name << L"(..)'" << endl;

      // prompt for break command
      Command* command;
      wcout << L"> ";
      do {
				wstring line;
				getline(wcin, line);
				if(line.size() > 0) {
					command = ProcessCommand(line);
					wcout << L"> ";
				}
				else {
					command = NULL;
				}
      }
      while(!command || (command->GetCommandType() != CONT_COMMAND &&
												 command->GetCommandType() != NEXT_COMMAND &&
												 command->GetCommandType() != NEXT_LINE_COMMAND &&
												 command->GetCommandType() != JUMP_OUT_COMMAND));
    }
  }
}
Exemple #2
0
Command* Runtime::Debugger::ProcessCommand(const wstring &line) {
#ifdef _DEBUG
  wcout << L"input: |" << line << L"|" << endl;
#endif

  // parser input
  is_next = is_next_line = false;
  Parser parser;
  Command* command = parser.Parse(L"?" + line);
  if(command) {
    switch(command->GetCommandType()) {
    case EXE_COMMAND:
      ProcessExe(static_cast<Load*>(command));
      break;

    case SRC_COMMAND:
      ProcessSrc(static_cast<Load*>(command));
      break;

    case ARGS_COMMAND:
      ProcessArgs(static_cast<Load*>(command));
      break;

    case QUIT_COMMAND:
      ClearBreaks();
      ClearProgram();
      wcout << L"goodbye." << endl;
      exit(0);
      break;

    case LIST_COMMAND: {
      FilePostion* file_pos = static_cast<FilePostion*>(command);

      wstring file_name;
      if(file_pos->GetFileName().size() > 0) {
        file_name = file_pos->GetFileName();
      }
      else {
        file_name = cur_file_name;
      }

      int line_num;
      if(file_pos->GetLineNumber() > 0) {
        line_num = file_pos->GetLineNumber();
      }
      else {
        line_num = cur_line_num;
      }

      const wstring &path = base_path + file_name;
      if(FileExists(path) && line_num > 0) {
        SourceFile src_file(path, cur_line_num);
        if(!src_file.Print(line_num)) {
          wcout << L"invalid line number." << endl;
          is_error = true;
        }
      }
      else {
        wcout << L"source file or line number doesn't exist, ensure the program is running." << endl;
        is_error = true;
      }
    }
      break;

    case BREAK_COMMAND:
      ProcessBreak(static_cast<FilePostion*>(command));
      break;

    case BREAKS_COMMAND:
      ProcessBreaks();
      break;

    case PRINT_COMMAND:
      ProcessPrint(static_cast<Print*>(command));
      break;

    case RUN_COMMAND:
      if(!cur_program) {
        ProcessRun();
      }
      else {
        wcout << L"instance already running." << endl;
        is_error = true;
      }
      break;

    case CLEAR_COMMAND: {
      wcout << L"  are sure you want to clear all breakpoints? [y/n] ";
      wstring line;
      getline(wcin, line);
      if(line == L"y" || line == L"yes") {
        ClearBreaks();
      }
    }
      break;

    case DELETE_COMMAND:
      ProcessDelete(static_cast<FilePostion*>(command));
      break;

    case NEXT_COMMAND:
      if(interpreter) {
        is_next = true;
      }
      else {
        wcout << L"program is not running." << endl;
      }
      break;

    case NEXT_LINE_COMMAND:
      if(interpreter) {
        is_next_line = true;
      }
      else {
        wcout << L"program is not running." << endl;
      }
      break;

    case JUMP_OUT_COMMAND:
      if(interpreter) {
        is_jmp_out = true;
      }
      else {
        wcout << L"program is not running." << endl;
      }
      break;

    case CONT_COMMAND:
      if(!interpreter) {
        wcout << L"program is not running." << endl;
      }
      cur_line_num = -2;
      break;

    case INFO_COMMAND:
      ProcessInfo(static_cast<Info*>(command));
      break;

    case STACK_COMMAND:
      if(interpreter) {
        wcout << L"stack:" << endl;
        StackMethod* method = cur_frame->method;
        wcerr << L"  frame: pos=" << cur_call_stack_pos << L", class=" << method->GetClass()->GetName() 
							<< L", method=" << PrintMethod(method);
        const long ip = cur_frame->ip;
        if(ip > -1) {
          StackInstr* instr = cur_frame->method->GetInstruction(ip);
          wcerr << L", file=" << method->GetClass()->GetFileName() << L":" << instr->GetLineNumber() << endl;
        }
        else {
          wcerr << endl;
        }

        long pos = cur_call_stack_pos - 1;
        do {
          StackMethod* method = cur_call_stack[pos]->method;
          wcerr << L"  frame: pos=" << pos << L", class=" << method->GetClass()->GetName() 
								<< L", method=" << PrintMethod(method);
          const long ip = cur_call_stack[pos]->ip;
          if(ip > -1) {
            StackInstr* instr = cur_call_stack[pos]->method->GetInstruction(ip);
            wcerr << L", file=" << method->GetClass()->GetFileName() << L":" << instr->GetLineNumber() << endl;
          }
          else {
            wcerr << endl;
          }
        }
        while(--pos);
      }
      else {
        wcout << L"program is not running." << endl;
      }
      break;

    default:
      break;
    }

    is_error = false;
    ref_mem = NULL;
    return command;
  }
  else {
    wcout << L"-- Unable to process command --" << endl;
  }

  is_error = false;
  ref_mem = NULL;
  return NULL;
}