예제 #1
0
void ScriptDebuggerLocal::debug(ScriptLanguage *p_script, bool p_can_continue) {

	print_line("Debugger Break, Reason: '" + p_script->debug_get_error() + "'");
	print_line("*Frame " + itos(0) + " - " + p_script->debug_get_stack_level_source(0) + ":" + itos(p_script->debug_get_stack_level_line(0)) + " in function '" + p_script->debug_get_stack_level_function(0) + "'");
	print_line("Enter \"help\" for assistance.");
	int current_frame = 0;
	int total_frames = p_script->debug_get_stack_level_count();
	while (true) {

		OS::get_singleton()->print("debug> ");
		String line = OS::get_singleton()->get_stdin_string().strip_edges();

		if (line == "") {
			print_line("Debugger Break, Reason: '" + p_script->debug_get_error() + "'");
			print_line("*Frame " + itos(current_frame) + " - " + p_script->debug_get_stack_level_source(current_frame) + ":" + itos(p_script->debug_get_stack_level_line(current_frame)) + " in function '" + p_script->debug_get_stack_level_function(current_frame) + "'");
			print_line("Enter \"help\" for assistance.");
		} else if (line == "c" || line == "continue")
			break;
		else if (line == "bt" || line == "breakpoint") {

			for (int i = 0; i < total_frames; i++) {

				String cfi = (current_frame == i) ? "*" : " "; //current frame indicator
				print_line(cfi + "Frame " + itos(i) + " - " + p_script->debug_get_stack_level_source(i) + ":" + itos(p_script->debug_get_stack_level_line(i)) + " in function '" + p_script->debug_get_stack_level_function(i) + "'");
			}

		} else if (line.begins_with("fr") || line.begins_with("frame")) {

			if (line.get_slice_count(" ") == 1) {
				print_line("*Frame " + itos(current_frame) + " - " + p_script->debug_get_stack_level_source(current_frame) + ":" + itos(p_script->debug_get_stack_level_line(current_frame)) + " in function '" + p_script->debug_get_stack_level_function(current_frame) + "'");
			} else {
				int frame = line.get_slicec(' ', 1).to_int();
				if (frame < 0 || frame >= total_frames) {
					print_line("Error: Invalid frame.");
				} else {
					current_frame = frame;
					print_line("*Frame " + itos(frame) + " - " + p_script->debug_get_stack_level_source(frame) + ":" + itos(p_script->debug_get_stack_level_line(frame)) + " in function '" + p_script->debug_get_stack_level_function(frame) + "'");
				}
			}

		} else if (line == "lv" || line == "locals") {

			List<String> locals;
			List<Variant> values;
			p_script->debug_get_stack_level_locals(current_frame, &locals, &values);
			List<Variant>::Element *V = values.front();
			for (List<String>::Element *E = locals.front(); E; E = E->next()) {
				print_line(E->get() + ": " + String(V->get()));
				V = V->next();
			}

		} else if (line == "gv" || line == "globals") {

			List<String> locals;
			List<Variant> values;
			p_script->debug_get_globals(&locals, &values);
			List<Variant>::Element *V = values.front();
			for (List<String>::Element *E = locals.front(); E; E = E->next()) {
				print_line(E->get() + ": " + String(V->get()));
				V = V->next();
			}

		} else if (line == "mv" || line == "members") {

			List<String> locals;
			List<Variant> values;
			p_script->debug_get_stack_level_members(current_frame, &locals, &values);
			List<Variant>::Element *V = values.front();
			for (List<String>::Element *E = locals.front(); E; E = E->next()) {
				print_line(E->get() + ": " + String(V->get()));
				V = V->next();
			}

		} else if (line.begins_with("p") || line.begins_with("print")) {

			if (line.get_slice_count(" ") <= 1) {
				print_line("Usage: print <expre>");
			} else {

				String expr = line.get_slicec(' ', 2);
				String res = p_script->debug_parse_stack_level_expression(current_frame, expr);
				print_line(res);
			}

		} else if (line == "s" || line == "step") {

			set_depth(-1);
			set_lines_left(1);
			break;
		} else if (line.begins_with("n") || line.begins_with("next")) {

			set_depth(0);
			set_lines_left(1);
			break;
		} else if (line.begins_with("br") || line.begins_with("break")) {

			if (line.get_slice_count(" ") <= 1) {
				//show breakpoints
			} else {

				String bppos = line.get_slicec(' ', 1);
				String source = bppos.get_slicec(':', 0).strip_edges();
				int line = bppos.get_slicec(':', 1).strip_edges().to_int();

				source = breakpoint_find_source(source);

				insert_breakpoint(line, source);

				print_line("BreakPoint at " + source + ":" + itos(line));
			}

		} else if (line.begins_with("delete")) {

			if (line.get_slice_count(" ") <= 1) {
				clear_breakpoints();
			} else {

				String bppos = line.get_slicec(' ', 1);
				String source = bppos.get_slicec(':', 0).strip_edges();
				int line = bppos.get_slicec(':', 1).strip_edges().to_int();

				source = breakpoint_find_source(source);

				remove_breakpoint(line, source);

				print_line("Removed BreakPoint at " + source + ":" + itos(line));
			}

		} else if (line == "h" || line == "help") {

			print_line("Built-In Debugger command list:\n");
			print_line("\tc,continue :\t\t Continue execution.");
			print_line("\tbt,backtrace :\t\t Show stack trace (frames).");
			print_line("\tfr,frame <frame>:\t Change current frame.");
			print_line("\tlv,locals :\t\t Show local variables for current frame.");
			print_line("\tmv,members :\t\t Show member variables for \"this\" in frame.");
			print_line("\tgv,globals :\t\t Show global variables.");
			print_line("\tp,print <expr> :\t Execute and print variable in expression.");
			print_line("\ts,step :\t\t Step to next line.");
			print_line("\tn,next :\t\t Next line.");
			print_line("\tbr,break source:line :\t Place a breakpoint.");
			print_line("\tdelete [source:line]:\t\t Delete one/all breakpoints.");
		} else {
			print_line("Error: Invalid command, enter \"help\" for assistance.");
		}
	}
}
예제 #2
0
void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue) {

	//this function is called when there is a debugger break (bug on script)
	//or when execution is paused from editor

	if (!tcp_client->is_connected_to_host()) {
		ERR_EXPLAIN("Script Debugger failed to connect, but being used anyway.");
		ERR_FAIL();
	}

	packet_peer_stream->put_var("debug_enter");
	packet_peer_stream->put_var(2);
	packet_peer_stream->put_var(p_can_continue);
	packet_peer_stream->put_var(p_script->debug_get_error());

	skip_profile_frame = true; // to avoid super long frame time for the frame

	Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
	if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
		Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);

	while (true) {

		_get_output();

		if (packet_peer_stream->get_available_packet_count() > 0) {

			Variant var;
			Error err = packet_peer_stream->get_var(var);
			ERR_CONTINUE(err != OK);
			ERR_CONTINUE(var.get_type() != Variant::ARRAY);

			Array cmd = var;

			ERR_CONTINUE(cmd.size() == 0);
			ERR_CONTINUE(cmd[0].get_type() != Variant::STRING);

			String command = cmd[0];

			if (command == "get_stack_dump") {

				packet_peer_stream->put_var("stack_dump");
				int slc = p_script->debug_get_stack_level_count();
				packet_peer_stream->put_var(slc);

				for (int i = 0; i < slc; i++) {

					Dictionary d;
					d["file"] = p_script->debug_get_stack_level_source(i);
					d["line"] = p_script->debug_get_stack_level_line(i);
					d["function"] = p_script->debug_get_stack_level_function(i);
					//d["id"]=p_script->debug_get_stack_level_
					d["id"] = 0;

					packet_peer_stream->put_var(d);
				}

			} else if (command == "get_stack_frame_vars") {

				cmd.remove(0);
				ERR_CONTINUE(cmd.size() != 1);
				int lv = cmd[0];

				List<String> members;
				List<Variant> member_vals;

				p_script->debug_get_stack_level_members(lv, &members, &member_vals);

				ERR_CONTINUE(members.size() != member_vals.size());

				List<String> locals;
				List<Variant> local_vals;

				p_script->debug_get_stack_level_locals(lv, &locals, &local_vals);

				ERR_CONTINUE(locals.size() != local_vals.size());

				packet_peer_stream->put_var("stack_frame_vars");
				packet_peer_stream->put_var(2 + locals.size() * 2 + members.size() * 2);

				{ //members
					packet_peer_stream->put_var(members.size());

					List<String>::Element *E = members.front();
					List<Variant>::Element *F = member_vals.front();

					while (E) {

						_put_variable(E->get(), F->get());

						E = E->next();
						F = F->next();
					}
				}

				{ //locals
					packet_peer_stream->put_var(locals.size());

					List<String>::Element *E = locals.front();
					List<Variant>::Element *F = local_vals.front();

					while (E) {
						_put_variable(E->get(), F->get());

						E = E->next();
						F = F->next();
					}
				}

			} else if (command == "step") {

				set_depth(-1);
				set_lines_left(1);
				break;
			} else if (command == "next") {

				set_depth(0);
				set_lines_left(1);
				break;

			} else if (command == "continue") {

				set_depth(-1);
				set_lines_left(-1);
				OS::get_singleton()->move_window_to_foreground();
				break;
			} else if (command == "break") {
				ERR_PRINT("Got break when already broke!");
				break;
			} else if (command == "request_scene_tree") {

				if (request_scene_tree)
					request_scene_tree(request_scene_tree_ud);

			} else if (command == "request_video_mem") {

				_send_video_memory();
			} else if (command == "inspect_object") {

				ObjectID id = cmd[1];
				_send_object_id(id);
			} else if (command == "set_object_property") {

				_set_object_property(cmd[1], cmd[2], cmd[3]);

			} else if (command == "reload_scripts") {
				reload_all_scripts = true;
			} else if (command == "breakpoint") {

				bool set = cmd[3];
				if (set)
					insert_breakpoint(cmd[2], cmd[1]);
				else
					remove_breakpoint(cmd[2], cmd[1]);

			} else {
				_parse_live_edit(cmd);
			}

		} else {
			OS::get_singleton()->delay_usec(10000);
		}
	}

	packet_peer_stream->put_var("debug_exit");
	packet_peer_stream->put_var(0);

	if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
		Input::get_singleton()->set_mouse_mode(mouse_mode);
}
예제 #3
0
void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {

	if (!tcp_client->is_connected()) {
		ERR_EXPLAIN("Script Debugger failed to connect, but being used anyway.");
		ERR_FAIL();
	}

	packet_peer_stream->put_var("debug_enter");
	packet_peer_stream->put_var(2);
	packet_peer_stream->put_var(p_can_continue);
	packet_peer_stream->put_var(p_script->debug_get_error());


	while(true) {

		_get_output();

		if (packet_peer_stream->get_available_packet_count()>0) {

			Variant var;
			Error err = packet_peer_stream->get_var(var);
			ERR_CONTINUE( err != OK);
			ERR_CONTINUE( var.get_type()!=Variant::ARRAY );

			Array cmd = var;

			ERR_CONTINUE( cmd.size()==0);
			ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );

			String command = cmd[0];
			cmd.remove(0);


			if (command=="get_stack_dump") {

				packet_peer_stream->put_var("stack_dump");
				int slc = p_script->debug_get_stack_level_count();
				packet_peer_stream->put_var( slc );

				for(int i=0;i<slc;i++) {

					Dictionary d;
					d["file"]=p_script->debug_get_stack_level_source(i);
					d["line"]=p_script->debug_get_stack_level_line(i);
					d["function"]=p_script->debug_get_stack_level_function(i);
					//d["id"]=p_script->debug_get_stack_level_
					d["id"]=0;

					packet_peer_stream->put_var( d );
				}

			} else if (command=="get_stack_frame_vars") {


				ERR_CONTINUE( cmd.size()!=1 );
				int lv = cmd[0];

				List<String> members;
				List<Variant> member_vals;

				p_script->debug_get_stack_level_members(lv,&members,&member_vals);



				ERR_CONTINUE( members.size() !=member_vals.size() );

				List<String> locals;
				List<Variant> local_vals;

				p_script->debug_get_stack_level_locals(lv,&locals,&local_vals);

				ERR_CONTINUE( locals.size() !=local_vals.size() );

				packet_peer_stream->put_var("stack_frame_vars");
				packet_peer_stream->put_var(2+locals.size()*2+members.size()*2);

				{ //members
					packet_peer_stream->put_var(members.size());

					List<String>::Element *E=members.front();
					List<Variant>::Element *F=member_vals.front();

					while(E) {

						if (F->get().get_type()==Variant::OBJECT) {
							packet_peer_stream->put_var("*"+E->get());
							packet_peer_stream->put_var(safe_get_instance_id(F->get()));
						} else {
							packet_peer_stream->put_var(E->get());
							packet_peer_stream->put_var(F->get());
						}

						E=E->next();
						F=F->next();
					}

				}


				{ //locals
					packet_peer_stream->put_var(locals.size());

					List<String>::Element *E=locals.front();
					List<Variant>::Element *F=local_vals.front();

					while(E) {

						if (F->get().get_type()==Variant::OBJECT) {
							packet_peer_stream->put_var("*"+E->get());
							packet_peer_stream->put_var(safe_get_instance_id(F->get()));
						} else {
							packet_peer_stream->put_var(E->get());
							packet_peer_stream->put_var(F->get());
						}

						E=E->next();
						F=F->next();
					}

				}



			} else if (command=="step") {

				set_depth(-1);
				set_lines_left(1);
				break;
			} else if (command=="next") {

				set_depth(0);
				set_lines_left(1);
				break;

			} else if (command=="continue") {

				set_depth(-1);
				set_lines_left(-1);
				break;
			} else if (command=="break") {
				ERR_PRINT("Got break when already broke!");
				break;
			} else if (command=="request_scene_tree") {

				if (request_scene_tree)
					request_scene_tree(request_scene_tree_ud);
			}



		} else {
			OS::get_singleton()->delay_usec(10000);
		}

	}

	packet_peer_stream->put_var("debug_exit");
	packet_peer_stream->put_var(0);

}