Ejemplo n.º 1
0
/**
 * Verify use of "debug" mode
 */
void textui_cmd_debug(void)
{
	/* Ask first time */
	if (!(player->noscore & NOSCORE_DEBUG)) {
		/* Mention effects */
		msg("You are about to use the dangerous, unsupported, debug commands!");
		msg("Your machine may crash, and your savefile may become corrupted!");
		event_signal(EVENT_MESSAGE_FLUSH);

		/* Verify request */
		if (!get_check("Are you sure you want to use the debug commands? "))
			return;

		/* Mark savefile */
		player->noscore |= NOSCORE_DEBUG;
	}

	/* Okay */
	get_debug_command();
}
Ejemplo n.º 2
0
void debuging::debug()
{
	fake * fk = m_fk;
	bool isend = false;
	int range = 0;
	int command = debug_next;
	std::vector<String> paramvec;
	const char * lastfunc = 0;
	breakpoint_list blist;
	int bindex = 0;
	int frame = 0;
	int lastrid = fkgetcurroutineid(fk);
	int rid = lastrid;
	std::vector<String> watchvec;
	bool firsttime = true;
	while (1)
	{
		show_watch_variant(fk, rid, frame, watchvec);
		check_show_func_header(fk, rid, frame, lastrid, lastfunc);
		show_debug_code(fk, rid, frame, range);
FAKEINPUT:
		get_debug_command(fk, command, paramvec);
		switch (command)
		{
		case debug_next:
			{		
				frame = 0;
				rid = fkgetcurroutineid(fk);
						
				if (firsttime)
				{
					if (check_trigger_breakpoint(fk, blist))
					{
						firsttime = false;
						break;
					}
				}
				firsttime = false;
				
				const char * lastfile = fkgetcurfile(fk);
				int lastline = fkgetcurline(fk);
				int laststacklength = fkgetcurcallstacklength(fk);
				int lastrid = rid;
				const char * curfile = fkgetcurfile(fk);
				int curline = fkgetcurline(fk);
				int curstacklength = fkgetcurcallstacklength(fk);
				int currid = rid;
				while (currid == lastrid && 
					(curstacklength > laststacklength || 
					(strcmp(lastfile, curfile) == 0 && lastline == curline)))
				{
					resume(isend);
					if (isend)
					{
						break;
					}
					curfile = fkgetcurfile(fk);
					curline = fkgetcurline(fk);
					curstacklength = fkgetcurcallstacklength(fk);
					currid = fkgetcurroutineid(fk);
					if (check_trigger_breakpoint(fk, blist))
					{
						break;
					}
				}
				
				rid = fkgetcurroutineid(fk);
			}
			break;
		case debug_step:
			{
				frame = 0;
				rid = fkgetcurroutineid(fk);
				
				if (firsttime)
				{
					if (check_trigger_breakpoint(fk, blist))
					{
						firsttime = false;
						break;
					}
				}
				firsttime = false;
				
				const char * lastfile = fkgetcurfile(fk);
				int lastline = fkgetcurline(fk);
				int lastrid = rid;
				const char * curfile = fkgetcurfile(fk);
				int curline = fkgetcurline(fk);
				int currid = rid;
				while (currid == lastrid &&
					(strcmp(lastfile, curfile) == 0 && lastline == curline))
				{
					resume(isend);
					if (isend)
					{
						break;
					}
					curfile = fkgetcurfile(fk);
					curline = fkgetcurline(fk);
					currid = fkgetcurroutineid(fk);
					if (check_trigger_breakpoint(fk, blist))
					{
						break;
					}
				}
				
				rid = fkgetcurroutineid(fk);
			}
			break;
		case debug_next_instruction:
			{
				frame = 0;
				rid = fkgetcurroutineid(fk);
				
				if (firsttime)
				{
					if (check_trigger_breakpoint(fk, blist))
					{
						firsttime = false;
						break;
					}
				}
				firsttime = false;
				
				int laststacklength = fkgetcurcallstacklength(fk);
				int lastrid = rid;
				int curstacklength = fkgetcurcallstacklength(fk);
				int currid = rid;
				do
				{
					resume(isend);
					if (isend)
					{
						break;
					}
					curstacklength = fkgetcurcallstacklength(fk);
					currid = fkgetcurroutineid(fk);
					if (check_trigger_breakpoint(fk, blist))
					{
						break;
					}
				}
				while (currid == lastrid &&
					curstacklength > laststacklength);
					
				rid = fkgetcurroutineid(fk);
			}
			break;
		case debug_step_instruction:
			{
				frame = 0;
				rid = fkgetcurroutineid(fk);
				
				if (firsttime)
				{
					if (check_trigger_breakpoint(fk, blist))
					{
						firsttime = false;
						break;
					}
				}
				firsttime = false;
				
				resume(isend);
				
				rid = fkgetcurroutineid(fk);
				if (check_trigger_breakpoint(fk, blist))
				{
					break;
				}
			}
			break;
		case debug_continue:
			{
				frame = 0;
				rid = fkgetcurroutineid(fk);

				if (firsttime)
				{
					if (check_trigger_breakpoint(fk, blist))
					{
						firsttime = false;
						break;
					}
				}
				firsttime = false;
				
				while (1)
				{
					resume(isend);
					rid = fkgetcurroutineid(fk);
					if (check_trigger_breakpoint(fk, blist))
					{
						break;
					}
					if (isend)
					{
						break;
					}
				}
			}
			break;
		case debug_breakpoint:
			{
				breakpoint tmp;
				if (paramvec.empty())
				{
					tmp.file = fkgetcurfilebyroutinebyframe(fk, rid, frame);
					tmp.line = fkgetcurlinebyroutinebyframe(fk, rid, frame);
				}
				else
				{
					String str = paramvec[0];
					int subpos = str.find(':');
					if (subpos != -1)
					{
						String filestr = str.substr(0, subpos);
						String linestr = str.substr(subpos + 1);
						
						tmp.file = filestr;
						tmp.line = fkatoi(&linestr);
					}
					else
					{
						bool isnumber = true;
						for (int i = 0; i < (int)str.size(); i++)
						{
							if (!isdigit(str[i]))
							{
								isnumber = false;
								break;
							}
						}

						if (isnumber)
						{
							tmp.file = fkgetcurfilebyroutinebyframe(fk, rid, frame);
							tmp.line = fkatoi(&str);
						}
						else 
						{
							if (!fkisfunc(fk, str.c_str()))
							{
								printf("%s is not func\n", str.c_str());
								continue;
							}
							
							tmp.file = fkgetfuncfile(fk, str.c_str());
							tmp.line = fkgetfuncstartline(fk, str.c_str());
						}
					}
				}
				tmp.enable = true;
				tmp.id = bindex;
				
				if ((int)tmp.file.find_last_of('/') != -1)
				{
					tmp.file = tmp.file.substr(tmp.file.find_last_of('/') + 1);
				}
				
				blist.push_back(tmp);
				bindex++;
				printf("Breakpoint %d at file %s, line %d total %d\n", tmp.id, tmp.file.c_str(), tmp.line, (int)blist.size());
			}
			break;
		case debug_enable:
			{
				if (paramvec.empty())
				{
					for (int i = 0;  i < (int)blist.size(); i++)
					{
						breakpoint & tmp = blist[i];
						tmp.enable = true;
					}
				}
				else
				{
					int id = atoi(paramvec[0].c_str());
					for (int i = 0;  i < (int)blist.size(); i++)
					{
						breakpoint & tmp = blist[i];
						if (tmp.id == id)
						{
							tmp.enable = true;
						}
					}
				}
			}
			break;
		case debug_disable:
			{
				if (paramvec.empty())
				{
					for (int i = 0;  i < (int)blist.size(); i++)
					{
						breakpoint & tmp = blist[i];
						tmp.enable = false;
					}
				}
				else
				{
					int id = fkatoi(&paramvec[0]);
					for (int i = 0;  i < (int)blist.size(); i++)
					{
						breakpoint & tmp = blist[i];
						if (tmp.id == id)
						{
							tmp.enable = false;
						}
					}
				}
			}
			break;
		case debug_delete:
			{
				if (paramvec.empty())
				{
					blist.clear();
					watchvec.clear();
					continue;
				}
				else
				{
					int id = fkatoi(&paramvec[0]);
					for (int i = 0;  i < (int)blist.size(); i++)
					{
						breakpoint & tmp = blist[i];
						if (tmp.id == id)
						{
							blist.erase(blist.begin() + i);
						}
					}
				}
			}
			break;
		case debug_info:
			{
				if (paramvec.empty())
				{
					printf("need arg, useage: i b, i r\n");
					continue;
				}

				if (paramvec[0] == "b")
				{
					printf("Id\tEnb\twhere\n");
					for (int i = 0;  i < (int)blist.size(); i++)
					{
						breakpoint & tmp = blist[i];
						printf("%d\t%s\tfile %s, line %d\n", tmp.id, tmp.enable ? "y" : "n", tmp.file.c_str(), tmp.line);
					}
				}
				else if (paramvec[0] == "r")
				{
					for (int i = 0;  i < (int)fkgetcurroutinenum(fk); i++)
					{
						printf("%s%s%s\n", fkgetroutineidbyindex(fk, i) == rid ? "*" : "", 
							fkgetroutineidbyindex(fk, i) == fkgetcurroutineid(fk) ? "->" : "", 
							fkgetcurroutinebyindex(fk, i));
					}
				}
				
				printf("\n");
			}
			break;
		case debug_finish:
			{
				frame = 0;
				rid = fkgetcurroutineid(fk);
				
				int laststacklength = fkgetcurcallstacklength(fk);
				int curstacklength = fkgetcurcallstacklength(fk);
				do
				{
					resume(isend);
					if (isend)
					{
						break;
					}
					curstacklength = fkgetcurcallstacklength(fk);
				}
				while (curstacklength >= laststacklength);
			}
			break;
		case debug_list:
			{
				int listrange = 3;
				if (!paramvec.empty())
				{
					listrange = fkatoi(&paramvec[0]);
				}
				show_debug_code(fk, rid, frame, listrange);
				goto FAKEINPUT;
			}
			break;
		case debug_print:
			{
				if (paramvec.empty())
				{
					printf("need arg, useage: p variant\n");
					continue;
				}

				String name = paramvec[0];
				printf("%s\n", fkgetcurvaiantbyroutinebyframe(fk, rid, frame, name.c_str()));
			}
			break;
		case debug_set:
			{
				if (paramvec.size() < 2)
				{
					printf("need arg, useage: set variant value\n");
					continue;
				}

				String name = paramvec[0];
				String value = paramvec[1];
				fksetcurvaiantbyroutinebyframe(fk, rid, frame, name.c_str(), value.c_str());
				printf("%s\n", fkgetcurvaiantbyroutinebyframe(fk, rid, frame, name.c_str()));
			}
			break;
		case debug_watch:
			{
				if (paramvec.empty())
				{
					printf("need arg, useage: wa variant\n");
					continue;
				}

				String name = paramvec[0];
				watchvec.push_back(name);
			}
			break;
		case debug_backtrace:
			{
				int length = fkgetcurcallstacklengthbyroutine(fk, rid);
				for (int i = 0; i < length; i++)
				{
					printf("%s%s\n", i == frame ? "*" : " ", fkgetcurcallstackbyroutinebyframe(fk, rid, i));
				}
				goto FAKEINPUT;
			}
			break;
		case debug_frame:
			{
				if (paramvec.empty())
				{
					frame = 0;
				}
				else
				{
					int theframe = fkatoi(&paramvec[0]);
					if (theframe < 0 || theframe >= fkgetcurcallstacklengthbyroutine(fk, rid))
					{
						printf("%d is invalid\n", theframe);
					}
					frame = theframe;
				}
			}
			break;
		case debug_disa:
			{
				int pos = fkgetcurbytecodeposbyroutine(fk, rid);
				const char * func = fkgetcurfuncbyroutinebyframe(fk, rid, frame);
				printf("%s\n", fkdumpfunc(fk, func, pos));
			}
			break;
		case debug_routine:
			{
				if (paramvec.empty())
				{
					printf("need arg, useage: r rid\n");
					continue;
				}

				int id = fkatoi(&paramvec[0]);
				if (!fkishaveroutine(fk, id))
				{
					printf("no routine %d\n", id);
					continue;
				}
				
				rid = id;
			}
			break;
		default:
			continue;
		}
		if (isend)
		{
			break;
		}
	}
	printf("end\n");

	// ret
	{
		fkpsclear(fk);
		variant * ret = 0;
		bool err = false;
		PS_PUSH_AND_GET(fk->ps, ret);
		*ret = m_ret;
		CHECK_ERR(err);
	}
}