void BreakpointListView::updateBreakpoint(DebuggerBreakpoint* bp)
{
  BreakpointListViewItem*  item = findBreakpoint(bp);
  if(item)
  {
    item->setBreakpoint(bp);
  }
}
void BreakpointListView::toggleBreakpoint(const QString& filePath, int line)
{
  BreakpointListViewItem*  item = findBreakpoint(filePath, line);
  if(item) {
    removeBreakpoint(item->breakpoint());
  } else {
    addBreakpoint(filePath, line);
  }
}
void BreakpointListView::slotBreakpointUnmarked(QString filePath, int line) {
  //note: TextEditor lines are 0 based
  BreakpointListViewItem*  item = findBreakpoint(filePath, line+1);

  if(item) {
   takeItem(item);
  }
  emit sigBreakpointRemoved(item->breakpoint());
  delete item;
}
void BreakpointListView::removeBreakpoint(DebuggerBreakpoint* bp)
{
  BreakpointListViewItem*  item = findBreakpoint(bp);

  if(item) {
   takeItem(item);
  }
  emit sigBreakpointRemoved(bp);
  delete item;
}
void BreakpointListView::toggleBreakpoint(const KURL& url, int line, bool enabled)
{
  BreakpointListViewItem*  item = findBreakpoint(url, line);
  if(item)
  {
    removeBreakpoint(item->breakpoint());
  }
  else
  {
    addBreakpoint(url, line, enabled);
  }
}
// fixBreakpoint is going to clean up the mess we made in breakpoint().
// What we are cleaning up is determined by step:
//
// Step = 0: We will restore our OpCode and do nothing else! This will
// prove useful if we ever implement the ability to disable a breakpoint.
// This also allows us to use whereAmI() without having to guess if we
// are after INT 3 or at a valid instruction.
//
// Step = 1 we will be single stepping and then resetting the break.
void fixBreakpoint(unsigned int step){
	if(!step){
		unsigned long breakIndex = findBreakpoint(AFTER_BREAKPOINT);
		unsigned long breakAddress = breakpoints[breakIndex][0];
		unsigned long opCode = breakpoints[breakIndex][1];
		int i = 0;
		ptrace(PTRACE_POKETEXT,child,breakAddress,opCode);	// And now it is restored

		struct user_regs_struct regs;
		ptrace(PTRACE_GETREGS,child,NULL,&regs);
		--regs.eip;
		ptrace(PTRACE_SETREGS,child,NULL,&regs);
	}
	else{
		unsigned long breakIndex = findBreakpoint(AT_BREAKPOINT);
		if(ptrace(PTRACE_SINGLESTEP,child,NULL,NULL) != 0)
			printf("ptrace error\n");			// Execute this one instruction
		wait(&status);

		unsigned long opCode = (breakpoints[breakIndex][1] & ~0xFF) | 0xCC;
		unsigned long address = breakpoints[breakIndex][0];
		ptrace(PTRACE_POKETEXT,child,address,opCode);		// And now it is reset
	}
}
Exemplo n.º 7
0
void ScriptMachine::executeThread(SCMThread &t, int msPassed)
{
	if( t.wakeCounter > 0 ) {
		t.wakeCounter = std::max( t.wakeCounter - msPassed, 0 );
	}
	if( t.wakeCounter > 0 ) return;
	
	bool hasDebugging = !! bpHandler;
	
    while( t.wakeCounter == 0 ) {
        auto pc = t.programCounter;
        auto opcode = _file->read<SCMOpcode>(pc);

		bool isNegatedConditional = ((opcode & SCM_NEGATE_CONDITIONAL_MASK) == SCM_NEGATE_CONDITIONAL_MASK);
		opcode = opcode & ~SCM_NEGATE_CONDITIONAL_MASK;

		ScriptFunctionMeta* foundcode;
		if( ! _ops->findOpcode(opcode, &foundcode) )
		{
            throw IllegalInstruction(opcode, pc, t.name);
		}
		ScriptFunctionMeta& code = *foundcode;

        pc += sizeof(SCMOpcode);

		SCMParams parameters;
		
		bool hasExtraParameters = code.arguments < 0;
		auto requiredParams = std::abs(code.arguments);

		for( int p = 0; p < requiredParams || hasExtraParameters; ++p ) {
            auto type_r = _file->read<SCMByte>(pc);
			auto type = static_cast<SCMType>(type_r);

			if( type_r > 42 ) {
				// for implicit strings, we need the byte we just read.
				type = TString;
			}
			else {
                pc += sizeof(SCMByte);
			}

			parameters.push_back(SCMOpcodeParameter { type, { 0 } });
			switch(type) {
			case EndOfArgList:
				hasExtraParameters = false;
				break;
			case TInt8:
                parameters.back().integer = _file->read<std::uint8_t>(pc);
                pc += sizeof(SCMByte);
				break;
			case TInt16:
                parameters.back().integer = _file->read<std::int16_t>(pc);
                pc += sizeof(SCMByte) * 2;
				break;
			case TGlobal: {
				auto v = _file->read<std::uint16_t>(pc);
				parameters.back().globalPtr = globalData.data() + v; //* SCM_VARIABLE_SIZE;
				if( v >= _file->getGlobalsSize() )
				{
					state->world->logger->error("SCM", "Global Out of bounds! "+ std::to_string(v) + " " + std::to_string(_file->getGlobalsSize()));
				}
                pc += sizeof(SCMByte) * 2;
			}
				break;
			case TLocal: {
				auto v = _file->read<std::uint16_t>(pc);
				parameters.back().globalPtr = t.locals.data() + v * SCM_VARIABLE_SIZE;
				if( v >= SCM_THREAD_LOCAL_SIZE )
				{
					state->world->logger->error("SCM", "Local Out of bounds!");
				}
                pc += sizeof(SCMByte) * 2;
			}
				break;
			case TInt32:
                parameters.back().integer = _file->read<std::uint32_t>(pc);
                pc += sizeof(SCMByte) * 4;
				break;
			case TString:
                std::copy(_file->data()+pc, _file->data()+pc+8,
						  parameters.back().string);
                pc += sizeof(SCMByte) * 8;
				break;
			case TFloat16:
                parameters.back().real = _file->read<std::int16_t>(pc) / 16.f;
                pc += sizeof(SCMByte) * 2;
				break;
			default:
                throw UnknownType(type, pc, t.name);
				break;
			};
		}

        ScriptArguments sca(&parameters, &t, this);

        if( hasDebugging )
        {
			auto activeBreakpoint = findBreakpoint(t, pc);
			if( activeBreakpoint || interupt )
			{
                interupt = false;
                SCMBreakpoint bp;
                bp.pc = t.programCounter;
                bp.thread = &t;
                bp.vm = this;
                bp.function = &code;
                bp.args = &sca;
                bpHandler(bp);
            }
        }

#if RW_SCRIPT_DEBUG
		if (strcmp(t.name, "EIGHT") == 0)
		{
			printf("% 8s  %04x %04x % 25s", t.name, t.programCounter, opcode, code.signature.c_str());
			for (auto& a : sca.getParameters())
			{
				printf(" %08x", a.integerValue());
			}
			printf("\n");
		}
#endif

        // After debugging has been completed, update the program counter
        t.programCounter = pc;

		if(code.function)
        {
			code.function(sca);
		}

		if(isNegatedConditional) {
			t.conditionResult = !t.conditionResult;
		}

		// Handle conditional results for IF statements.
		if( t.conditionCount > 0 && opcode != 0x00D6 ) /// @todo add conditional flag to opcodes instead of checking for 0x00D6
		{
			--t.conditionCount;
			if ( t.conditionAND )
			{
				if ( t.conditionResult == false ) 
				{
					t.conditionMask = 0;
				}
				else
				{
					// t.conditionMask is already set to 0xFF by the if and opcode.
				}
			}
			else
			{
				t.conditionMask = t.conditionMask || t.conditionResult;
			}
			
			t.conditionResult = (t.conditionMask != 0);
		}
    }
	
	SCMOpcodeParameter p;
	p.globalPtr = (t.locals.data() + 16 * sizeof ( SCMByte ) * 4);
	*p.globalInteger += msPassed;
	p.globalPtr = (t.locals.data() + 17 * sizeof ( SCMByte ) * 4);
	*p.globalInteger += msPassed;
	
	if( t.wakeCounter == -1 ) {
		t.wakeCounter = 0;
	}
}
void debugger(){
	int hasStarted = 0;
	int hasContinued = 0;
	while(1){
		//wait for a signal
		wait(&status);
		//if the program exited, just return
		if (WIFEXITED( status )){
			printf("\nthe program terminated\n");
			return;
	 	}

		// Quick overview of what's going on here:
		// **Variable 'done': Done will keep us within this while loop. If it is
		//   set to 1 that means we issued the "continue" command.
		//
		// **Variable 'hasContinued': In the event that we stop at a breakpoint
		//   and issue a command other than "continue", we will end up calling
		//   fixBreakpoint a second time. hasContinued will tell the loop
		//   to pump the breaks, we haven't moved on yet!
		int done = 0;
	 	while(!done){
	    		//get user input, what should we do?
			if((breakpointCount > 0) && hasStarted && hasContinued){
				printf("breakpoint %d hit\n",findBreakpoint(AFTER_BREAKPOINT));
				fixBreakpoint(0);	// Restore our opcode and registers
				hasContinued = 0;
			}

	    		user_command * cmd = debugger_interface_get_cmd();
	    		if (cmd){
				//now handle the input
				switch(cmd->command_type){
				case CMD_TYPE_BREAKPOINT:
					if(breakpoint(cmd->value.line_number)){
						printf("Could not set breakpoint at line %d.\n",cmd->value.line_number);
					}
					break;
				case CMD_TYPE_STACKTRACE:
					stacktrace();
					break;
				case CMD_TYPE_PRINT:
					printVariable(cmd->value.var.format,cmd->value.var.name,0);
					break;
				case CMD_TYPE_PRINT_GEN:
					printVariable(cmd->value.var.format,cmd->value.var.name,1);
					break;
				case CMD_TYPE_CONTINUE:
					if(!hasStarted){
						// If we are here, that means we are just starting to run the
						// program, so nothing special.
						hasStarted = 1;
					}
					else{
						// However, if we are here that means we were "interuptted"
						// by a break. We fixed the breakpoint and altered our registers
						// At the beginning of the parent while loop, so now we want
						// to use SINGLE_STEP and then reset the breakpoint that we just
						// fixed.
						fixBreakpoint(1);
					}
					done = 1;
					hasContinued = 1;
					break;
				case CMD_TYPE_WHERE:
					whereAmI();
					break;
				}
			}
		}
		ptrace( PTRACE_CONT, child, NULL, NULL );
	}
}