Exemple #1
0
void Runtime::Debugger::EvaluateReference(Reference* &reference, MemoryContext context) {
  StackMethod* method = cur_frame->method;
  //
  // instance reference
  //
  if(context != LOCL) {
    if(ref_mem && ref_klass) {
      // check reference name
      bool found;
      StackDclr dclr_value;
      if(context == INST) {
        found = ref_klass->GetInstanceDeclaration(reference->GetVariableName(), dclr_value);
      }
      else {
        found = ref_klass->GetClassDeclaration(reference->GetVariableName(), dclr_value);	
      }

      // set reference
      if(found) {
        reference->SetDeclaration(dclr_value);
        switch(dclr_value.type) {
        case CHAR_PARM:
        case INT_PARM:
          reference->SetIntValue(ref_mem[dclr_value.id]);
          break;

        case FUNC_PARM:
          reference->SetIntValue(ref_mem[dclr_value.id]);
          reference->SetIntValue2(ref_mem[dclr_value.id + 1]);
          break;

        case FLOAT_PARM: {
          FLOAT_VALUE value;
          memcpy(&value, &ref_mem[dclr_value.id], sizeof(FLOAT_VALUE));
          reference->SetFloatValue(value);
				}
					break;

        case OBJ_PARM:
          EvaluateInstanceReference(reference, dclr_value.id);
          break;

        case BYTE_ARY_PARM:
          EvaluateByteReference(reference, dclr_value.id);
          break;

        case CHAR_ARY_PARM:
          EvaluateCharReference(reference, dclr_value.id);
          break;

        case INT_ARY_PARM:
          EvaluateIntFloatReference(reference, dclr_value.id, false);
          break;

        case OBJ_ARY_PARM:
          EvaluateIntFloatReference(reference, dclr_value.id, false);
          break;

        case FLOAT_ARY_PARM:
          EvaluateIntFloatReference(reference, dclr_value.id, true);
          break;
        }
      }
      else {
        wcout << L"unknown variable (or no debug information available)." << endl;
        is_error = true;
      }
    }
    else {
      wcout << L"unable to find reference." << endl;
      is_error = true;
    }
  }
  //
  // method reference
  //
  else {
    ref_mem = cur_frame->mem;
    if(ref_mem) {
      StackDclr dclr_value;

      // process explicit '@self' reference
      if(reference->IsSelf()) {
        dclr_value.name = L"@self";
        dclr_value.type = OBJ_PARM;
        reference->SetDeclaration(dclr_value);
        EvaluateInstanceReference(reference, 0);
      }
      // process method reference
      else {
        // check reference name
        bool found = method->GetLocalDeclaration(reference->GetVariableName(), dclr_value);
        reference->SetDeclaration(dclr_value);
        if(found) {
          if(method->HasAndOr()) {
            dclr_value.id++;
          }

          switch(dclr_value.type) {
          case CHAR_PARM:
          case INT_PARM:
            reference->SetIntValue(ref_mem[dclr_value.id + 1]);
            break;

          case FUNC_PARM:
            reference->SetIntValue(ref_mem[dclr_value.id + 1]);
            reference->SetIntValue2(ref_mem[dclr_value.id + 2]);
            break;

          case FLOAT_PARM: {
            FLOAT_VALUE value;
            memcpy(&value, &ref_mem[dclr_value.id + 1], sizeof(FLOAT_VALUE));
            reference->SetFloatValue(value);
					}
						break;

          case OBJ_PARM:
            EvaluateInstanceReference(reference, dclr_value.id + 1);
            break;

          case BYTE_ARY_PARM:
            EvaluateByteReference(reference, dclr_value.id + 1);
            break;

          case CHAR_ARY_PARM:
            EvaluateCharReference(reference, dclr_value.id + 1);
            break;

          case INT_ARY_PARM:
            EvaluateIntFloatReference(reference, dclr_value.id + 1, false);
            break;

          case OBJ_ARY_PARM:
            EvaluateIntFloatReference(reference, dclr_value.id + 1, false);
            break;

          case FLOAT_ARY_PARM:
            EvaluateIntFloatReference(reference, dclr_value.id + 1, true);
            break;
          }
        }
        else {
          // class for class reference
          StackClass* klass = cur_program->GetClass(reference->GetVariableName());
          if(klass) {
            dclr_value.name = klass->GetName();
            dclr_value.type = OBJ_PARM;
            reference->SetDeclaration(dclr_value);
            EvaluateClassReference(reference, klass, 0);
          }
          else {
            // process implicit '@self' reference
            Reference* next_reference = TreeFactory::Instance()->MakeReference();
            next_reference->SetReference(reference);
            reference = next_reference;
            // set declaration
            dclr_value.name = L"@self";
            dclr_value.type = OBJ_PARM;
            reference->SetDeclaration(dclr_value);
            EvaluateInstanceReference(reference, 0);
          }
        }
      }
    }
    else {
      wcout << L"unable to de-reference empty frame." << endl;
      is_error = true;
    }
  }
}
Exemple #2
0
void Runtime::Debugger::ProcessInfo(Info* info) {
  const wstring &cls_name = info->GetClassName();
  const wstring &mthd_name = info->GetMethodName();

#ifdef _DEBUG
  wcout << L"--- info class=" << cls_name << L", method=" << mthd_name << L" ---" << endl;
#endif

  if(interpreter) {
    // method info
    if(cls_name.size() > 0 && mthd_name.size() > 0) {
      StackClass* klass = cur_program->GetClass(cls_name);
      if(klass && klass->IsDebug()) {
        vector<StackMethod*> methods = klass->GetMethods(mthd_name);
        if(methods.size() > 0) {
          for(size_t i = 0; i < methods.size(); i++) {
            StackMethod* method = methods[i];
            wcout << L"  class: type=" << klass->GetName() << L", method="
									<< PrintMethod(method) << endl;
						if(method->GetNumberDeclarations() > 0) {
							wcout << L"  parameters:" << endl;
							PrintDeclarations(method->GetDeclarations(), method->GetNumberDeclarations());
						}
          }
        }
        else {
          wcout << L"unable to find method." << endl;
          is_error = true;
        }
      }
      else {
        wcout << L"unable to find class." << endl;
        is_error = true;
      }
    }
    // class info
    else if(cls_name.size() > 0) {
      StackClass* klass = cur_program->GetClass(cls_name);
      if(klass && klass->IsDebug()) {
        wcout << L"  class: type=" << klass->GetName() << endl;
        // print
        wcout << L"  parameters:" << endl;
				if(klass->GetNumberInstanceDeclarations() > 0) {
					PrintDeclarations(klass->GetInstanceDeclarations(), klass->GetNumberInstanceDeclarations());
				}
      }
      else {
        wcout << L"unable to find class." << endl;
        is_error = true;
      }
    }
    // general info
    else {
      wcout << L"general info:" << endl;
      wcout << L"  program executable: file='" << program_file << L"'" << endl;

      // parse method and class names
      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);

      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);

      // print
      wcout << L"  current file='" << cur_file_name << L":" << cur_line_num << L"', method='"
						<< cls_name << L"->" << mthd_name << L"(..)'" << endl;
    }
  }
  else {
    wcout << L"program is not running." << endl;
  }
}
Exemple #3
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;
}
Exemple #4
0
int main(const int argc, const char* argv[])
{
  const char* prgm_path = FCGX_GetParam("PROGRAM_PATH", environ);
  if(!prgm_path) {
    cerr << "Unable to find program, please ensure the 'PROGRAM_PATH' variable has been set correctly." << endl;
    exit(1);
  }
  
  // load program
  srand(time(NULL)); rand();
  Loader loader(prgm_path);
  loader.Load();

  // ignore web applications
  if(!loader.IsWeb()) {
    cerr << "Please recompile the code to be a web application." << endl;
    exit(1);
  }
  
#ifdef _TIMING
  clock_t start = clock();
#endif
  
  // locate starting class and method
  StackMethod* mthd = loader.GetStartMethod();
  if(!mthd) {
    cerr << "Unable to locate the 'Request(args)' function." << endl;
    exit(1);
  }
  
#ifdef _DEBUG
  cerr << "### Loaded method: " << mthd->GetName() << " ###" << endl;
#endif
  
  Runtime::StackInterpreter intpr(Loader::GetProgram());
  
  // go into accept loop...
  FCGX_Stream*in;
  FCGX_Stream* out;
  FCGX_Stream* err;
  FCGX_ParamArray envp;
  
  while(mthd && (FCGX_Accept(&in, &out, &err, &envp) >= 0)) {    
    // execute method
    long* op_stack = new long[CALC_STACK_SIZE];
    long* stack_pos = new long;
    
    // create request
    long* req_obj = MemoryManager::Instance()->AllocateObject("FastCgi.Request", 
							      op_stack, *stack_pos, false);
    if(req_obj) {
      req_obj[0] = (long)in;
      req_obj[1] = (long)envp;
      
      // create response
      long* res_obj = MemoryManager::Instance()->AllocateObject("FastCgi.Response", 
								op_stack, *stack_pos, false);
      if(res_obj) { 	
	res_obj[0] = (long)out;
	res_obj[1] = (long)err;
	
	// set calling parameters
	op_stack[0] = (long)req_obj;
	op_stack[1] = (long)res_obj;
	*stack_pos = 2;
 	
	// execute method
	intpr.Execute((long*)op_stack, (long*)stack_pos, 0, mthd, NULL, false);
      }
      else {
	cerr << ">>> DLL call: Unable to allocate object FastCgi.Response <<" << endl;
	// TODO: error
	return 1;
      }
    }
    else {
      cerr << ">>> DLL call: Unable to allocate object FastCgi.Request <<<" << endl;
      // TODO: error
      return 1;
    }
    
#ifdef _DEBUG
    cout << "# final stack: pos=" << (*stack_pos) << " #" << endl;
    if((*stack_pos) > 0) {
      for(int i = 0; i < (*stack_pos); i++) {
	cout << "dump: value=" << (void*)(*stack_pos) << endl;
      } 
    }
#endif
    
    // clean up
    delete[] op_stack;
    op_stack = NULL;

    delete stack_pos;
    stack_pos = NULL;
    
#ifdef _DEBUG
    PrintEnv(out, "Request environment", envp);
    PrintEnv(out, "Initial environment", environ);
#endif
  }
  
  return 0;
}
Exemple #5
0
uintptr_t WINAPI MemoryManager::CheckPdaRoots(void* arg)
{
#ifndef _GC_SERIAL
  EnterCriticalSection(&pda_frame_cs);
#endif

#ifdef _DEBUG
  wcout << L"----- PDA frames(s): num=" << pda_frames.size() 
        << L"; thread=" << GetCurrentThread()<< L" -----" << endl;
  wcout << L"memory types:" <<  endl;
#endif
  
  set<StackFrame**, StackFrame**>::iterator iter;
  for(iter = pda_frames.begin(); iter != pda_frames.end(); ++iter) {
    StackFrame** frame = *iter;
    StackMethod* mthd = (*frame)->method;
    long* mem = (*frame)->mem;
    
#ifdef _DEBUG
    wcout << L"\t===== PDA method: name=" << mthd->GetName() << L", addr="
          << mthd << L", num=" << mthd->GetNumberDeclarations() << L" =====" << endl;
#endif
    
    // mark self
    CheckObject((long*)(*mem), true, 1);
    
    if(mthd->HasAndOr()) {
      mem += 2;
    } 
    else {
      mem++;
    }
    
    // mark rest of memory
    CheckMemory(mem, mthd->GetDeclarations(), mthd->GetNumberDeclarations(), 0);
  }
#ifndef _GC_SERIAL
  LeaveCriticalSection(&pda_frame_cs);
#endif 
  
#ifndef GC_SERIAL
  EnterCriticalSection(&pda_monitor_cs);
#endif

#ifdef _DEBUG
  wcout << L"----- PDA method root(s): num=" << pda_monitors.size() 
    << L"; thread=" << GetCurrentThread()<< L" -----" << endl;
  wcout << L"memory types:" <<  endl;
#endif
  // look at pda methods
  unordered_map<StackFrameMonitor*, StackFrameMonitor*>::iterator pda_iter;
  for(pda_iter = pda_monitors.begin(); pda_iter != pda_monitors.end(); ++pda_iter) {
    // gather stack frames
    StackFrameMonitor* monitor = pda_iter->first;
    long call_stack_pos = *(monitor->call_stack_pos);
    
    if (call_stack_pos > 0) {
      StackFrame** call_stack = monitor->call_stack;
      StackFrame* cur_frame = *(monitor->cur_frame);

      // copy frames locally
      vector<StackFrame*> frames;
      frames.push_back(cur_frame);
      while (--call_stack_pos > -1) {
        frames.push_back(call_stack[call_stack_pos]);
      }

      for (size_t i = 0; i < frames.size(); ++i) {
        StackMethod* mthd = frames[i]->method;
        long* mem = frames[i]->mem;

#ifdef _DEBUG
        wcout << L"\t===== PDA method: name=" << mthd->GetName() << L", addr="
          << mthd << L", num=" << mthd->GetNumberDeclarations() << L" =====" << endl;
#endif

        // mark self
        CheckObject((long*)(*mem), true, 1);

        if (mthd->HasAndOr()) {
          mem += 2;
        }
        else {
          mem++;
        }

        // mark rest of memory
        CheckMemory(mem, mthd->GetDeclarations(), mthd->GetNumberDeclarations(), 0);
      }
    }
  }
#ifndef GC_SERIAL
  LeaveCriticalSection(&pda_monitor_cs);
#endif

  return 0;
}
Exemple #6
0
uintptr_t WINAPI MemoryManager::CheckJitRoots(void* arg)
{
#ifndef GC_SERIAL
  EnterCriticalSection(&jit_cs);
#endif  

#ifdef _DEBUG
  wcout << L"---- Marking JIT method root(s): num=" << jit_roots.size() 
    << L"; thread=" << GetCurrentThread() << L" ------" << endl;
  wcout << L"memory types: " << endl;
#endif

  unordered_map<long*, ClassMethodId*>::iterator jit_iter;
  for(jit_iter = jit_roots.begin(); jit_iter != jit_roots.end(); ++jit_iter) {
    ClassMethodId* id = jit_iter->second;
    long* mem = id->mem;
    StackMethod* mthd = prgm->GetClass(id->cls_id)->GetMethod(id->mthd_id);
    const long dclrs_num = mthd->GetNumberDeclarations();

#ifdef _DEBUG
    wcout << L"\t===== JIT method: name=" << mthd->GetName() << L", id=" << id->cls_id << L"," 
      << id->mthd_id << L"; addr=" << mthd << L"; num=" << mthd->GetNumberDeclarations() 
      << L" =====" << endl;
#endif

    // check self
    CheckObject(id->self, true, 1);

    StackDclr** dclrs = mthd->GetDeclarations();
    for(int j = dclrs_num - 1; j > -1; j--) {
      // update address based upon type
      switch(dclrs[j]->type) {
      case FUNC_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": FUNC_PARM: value=" << (*mem) 
          << L"," << *(mem + 1) << endl;
#endif
        // update
        mem += 2;
        break;

	  case CHAR_PARM:
      case INT_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": CHAR_PARM/INT_PARM: value=" << (*mem) << endl;
#endif
        // update
        mem++;
        break;

      case FLOAT_PARM: {
#ifdef _DEBUG
        FLOAT_VALUE value;
        memcpy(&value, mem, sizeof(FLOAT_VALUE));
        wcout << L"\t" << j << L": FLOAT_PARM: value=" << value << endl;
#endif
        // update
        mem += 2;
                       }
                       break;

      case BYTE_ARY_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": BYTE_ARY_PARM: addr=" 
          << (long*)(*mem) << L"(" << (long)(*mem) 
          << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0)
          << L" byte(s)" << endl;
#endif
        // mark data
        MarkMemory((long*)(*mem));
        // update
        mem++;
        break;

      case CHAR_ARY_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": CHAR_ARY_PARM: addr=" << (long*)(*mem) << L"(" << (long)(*mem) 
          << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0)
          << L" byte(s)" << endl;
#endif
        // mark data
        MarkMemory((long*)(*mem));
        // update
        mem++;
        break;

      case INT_ARY_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": INT_ARY_PARM: addr=" << (long*)(*mem)
          << L"(" << (long)(*mem) << L"), size=" 
          << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) 
          << L" byte(s)" << endl;
#endif
        // mark data
        MarkMemory((long*)(*mem));
        // update
        mem++;
        break;

      case FLOAT_ARY_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": FLOAT_ARY_PARM: addr=" << (long*)(*mem)
          << L"(" << (long)(*mem) << L"), size=" << L" byte(s)" 
          << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) << endl;
#endif
        // mark data
        MarkMemory((long*)(*mem));
        // update
        mem++;
        break;

      case OBJ_PARM: {
#ifdef _DEBUG
        wcout << L"\t" << j << L": OBJ_PARM: addr=" << (long*)(*mem)
          << L"(" << (long)(*mem) << L"), id=";
        if(*mem) {
          StackClass* tmp = (StackClass*)((long*)(*mem))[SIZE_OR_CLS];
          wcout << L"'" << tmp->GetName() << L"'" << endl;
        }
        else {
          wcout << L"Unknown" << endl;
        }
#endif
        // check object
        CheckObject((long*)(*mem), true, 1);
        // update
        mem++;
                     }
                     break;

                     // TODO: test the code below
      case OBJ_ARY_PARM:
#ifdef _DEBUG
        wcout << L"\t" << j << L": OBJ_ARY_PARM: addr=" << (long*)(*mem) << L"("
          << (long)(*mem) << L"), size=" << ((*mem) ? ((long*)(*mem))[SIZE_OR_CLS] : 0) 
          << L" byte(s)" << endl;
#endif
        // mark data
        if(MarkValidMemory((long*)(*mem))) {
          long* array = (long*)(*mem);
          const long size = array[0];
          const long dim = array[1];
          long* objects = (long*)(array + 2 + dim);
          for(long k = 0; k < size; k++) {
            CheckObject((long*)objects[k], true, 2);
          }
        }
        // update
        mem++;
        break;

      default:
        break;
      }
    }

    // NOTE: this marks temporary variables that are stored in JIT memory
    // during some method calls. there are 3 integer temp addresses
    for(int i = 0; i < 8; i++) {
      CheckObject((long*)mem[i], false, 1);
    }
  }

#ifndef GC_SERIAL
  LeaveCriticalSection(&jit_cs);  
#endif

  return 0;
}