18 #include "../bscript/berror.h" 19 #include "../bscript/bobject.h" 20 #include "../bscript/bstruct.h" 21 #include "../bscript/eprog.h" 22 #include "../bscript/executor.h" 23 #include "../bscript/impstr.h" 24 #include "../clib/clib.h" 25 #include "../clib/compilerspecifics.h" 26 #include "../clib/esignal.h" 27 #include "../clib/rawtypes.h" 28 #include "../clib/refptr.h" 29 #include "../clib/sckutil.h" 30 #include "../clib/socketsvc.h" 31 #include "../clib/stlutil.h" 32 #include "../clib/strutil.h" 33 #include "../clib/weakptr.h" 34 #include "../clib/wnsckt.h" 35 #include "../plib/systemstate.h" 46 using namespace Bscript;
50 "graphic",
"serial",
"color",
"facing",
"height",
51 "weight",
"multi",
"realm",
"dirty"};
80 "resist_physical_mod"};
140 "resist_physical_mod"};
148 std::string prompt()
const;
150 bool process(
const std::string& cmd, Results& results );
151 bool done()
const {
return _done; }
154 std::string cmd_attach(
unsigned pid );
155 std::string cmd_kill(
unsigned pid );
156 std::string cmd_loadsym(
unsigned pid );
157 std::string cmd_detach();
158 std::string cmd_quit();
159 std::string cmd_start(
const std::string& rest );
160 std::string cmd_call(
const std::string& rest, Results& results );
161 std::string cmd_state();
162 std::string cmd_pc();
163 std::string cmd_ins( Results& results );
164 std::string cmd_instrace();
165 std::string cmd_stepinto();
166 std::string cmd_stepover();
167 std::string cmd_run();
168 std::string cmd_break();
169 std::string cmd_setbp(
const std::string& rest );
170 std::string cmd_clrbp(
const std::string& rest );
171 std::string cmd_clrallbp();
172 std::string cmd_fileline(
const std::string& rest );
173 std::string cmd_files( Results& results );
174 std::string cmd_stacktrace( Results& results );
175 std::string cmd_filecont(
const std::string& rest, Results& results );
176 std::string cmd_funcprof(
const std::string& rest, Results& results );
177 std::string cmd_localvars( Results& results );
178 std::string cmd_globalvars( Results& results );
179 std::string cmd_localvar(
const std::string& rest );
180 std::string cmd_localvarmembers(
const std::string& rest, Results& results );
181 std::string cmd_inslist(
const std::string& rest, Results& results );
182 std::string cmd_pidlist(
const std::string& rest, Results& results );
183 std::string cmd_getlocalpacked(
const std::string& rest );
184 std::string cmd_getglobalpacked(
const std::string& rest );
185 std::string cmd_setlocalpacked(
const std::string& rest );
186 std::string cmd_setglobalpacked(
const std::string& rest );
187 std::string cmd_scriptlist(
const std::string& rest, Results& results );
188 std::string cmd_scriptprofile(
const std::string& rest, Results& results );
189 std::string cmd_scriptins(
const std::string& rest, Results& results );
190 std::string cmd_scriptsrc(
const std::string& rest, Results& results );
191 std::string cmd_srcprof(
const std::string& rest, Results& results );
192 std::string cmd_setscript(
const std::string& rest, Results& results );
193 std::string cmd_funclist(
const std::string& rest, Results& results );
219 : DebugContextObjImpBase( &debugcontextobjimp_type, rcdctx )
224 return "DebugContext";
236 if ( stricmp( methodname,
"process" ) == 0 )
239 return new BError(
"Not enough parameters" );
243 std::vector<std::string> results;
245 std::unique_ptr<ObjArray> arr(
new ObjArray );
246 for (
unsigned i = 0; i < results.size(); ++i )
248 arr->addElement(
new String( results[i] ) );
250 return arr.release();
254 return new BError(
"Invalid parameter type" );
257 return new BError(
"undefined" );
261 if ( stricmp( membername,
"prompt" ) == 0 )
270 std::vector<std::string> tmp;
290 return "Authorization required.";
331 std::string cmd, rest;
335 if ( cmd ==
"password" )
338 results.push_back( std::string(
"Password" ) + (
_authorized ?
"" :
" not" ) +
344 if ( cmd ==
"attach" )
346 else if ( cmd ==
"stacktrace" )
348 else if ( cmd ==
"quit" )
350 else if ( cmd ==
"detach" )
352 else if ( cmd ==
"start" )
354 else if ( cmd ==
"call" )
356 else if ( cmd ==
"state" )
358 else if ( cmd ==
"pc" )
360 else if ( cmd ==
"ins" )
362 else if ( cmd ==
"instrace" )
364 else if ( cmd ==
"stepinto" )
366 else if ( cmd ==
"stepover" )
368 else if ( cmd ==
"run" )
370 else if ( cmd ==
"break" )
372 else if ( cmd ==
"setbp" )
374 else if ( cmd ==
"clrbp" )
376 else if ( cmd ==
"clrallbp" )
378 else if ( cmd ==
"fileline" )
380 else if ( cmd ==
"files" )
382 else if ( cmd ==
"filecont" )
384 else if ( cmd ==
"localvars" )
386 else if ( cmd ==
"globalvars" )
388 else if ( cmd ==
"localvar" )
390 else if ( cmd ==
"localvarmembers" )
392 else if ( cmd ==
"inslist" )
394 else if ( cmd ==
"pidlist" )
396 else if ( cmd ==
"scriptlist" )
398 else if ( cmd ==
"scriptprofile" )
400 else if ( cmd ==
"scriptins" )
402 else if ( cmd ==
"scriptsrc" )
404 else if ( cmd ==
"srcprof" )
406 else if ( cmd ==
"funclist" )
408 else if ( cmd ==
"setscript" )
410 else if ( cmd ==
"getlocalpacked" )
412 else if ( cmd ==
"getglobalpacked" )
414 else if ( cmd ==
"setlocalpacked" )
416 else if ( cmd ==
"setglobalpacked" )
418 else if ( cmd ==
"kill" )
419 result =
cmd_kill( atoi( rest.c_str() ) );
420 else if ( cmd ==
"loadsym" )
423 result =
"Command '" + cmdline +
"' not recognized.";
425 if ( !result.empty() )
427 results.push_back( result );
431 catch ( std::exception& ex )
433 std::string text =
"Exception thrown while processing command: ";
435 results.push_back( text );
443 return "No script attached.";
448 return "Script must be halted to retreive stack trace.";
455 return "No debugging information available.";
458 std::vector<BObjectRefVec*> upperLocals2 = exec->
upperLocals2;
467 stack.push_back( rc );
469 upperLocals2.push_back( exec->
Locals2 );
473 while ( !stack.empty() )
479 upperLocals2.pop_back();
483 size_t left = Locals2->size();
489 std::vector<std::string> results2;
493 while ( left <= prog->blocks[block].parentvariables )
495 block = prog->
blocks[block].parentblockidx;
500 BObjectImp* ptr = ( *Locals2 )[varidx]->impptr();
506 for ( std::vector<std::string>::iterator it = results2.begin(); it < results2.end(); ++it )
507 results.push_back( *it );
525 return "PID not found.";
536 return "Failed to load symbols.";
538 return "Loaded debug symbols.";
542 return "PID not found.";
556 return "PID not found.";
563 return "No script attached.";
582 std::string filename = rest;
584 if ( !sd.
config_nodie( filename,
nullptr,
"scripts/" ) )
585 return "Error in script name.";
587 return "Script " + sd.
name() +
" does not exist.";
590 if ( new_uoemod ==
nullptr )
592 return "Unable to start script";
604 std::string filename, parameters_packed;
608 if ( !sd.
config_nodie( filename,
nullptr,
"scripts/" ) )
609 return "Error in script name.";
611 return "Script " + sd.
name() +
" does not exist.";
617 if ( !parameters_packed.empty() )
622 return "Parameters must be an array.";
625 for (
int i = static_cast<int>( arr->
ref_arr.size() - 1 ); i >= 0; --i )
631 return "Return value packed: " + ret.
impptr()->
pack();
635 return "Exception calling script";
648 if ( strstr( name.c_str(), match.c_str() ) !=
nullptr )
662 const char* nm = ( ( *citr ).first ).c_str();
664 std::string scriptname = eprog->
name;
665 results.push_back( nm );
677 return "No such script.";
682 return "Failed to load symbols.";
691 return "use setscript first";
695 for (
unsigned i = 0; i <
_script->dbg_functions.size(); ++i )
699 unsigned int cycles = 0;
708 results.push_back( result );
717 return "use setscript first";
720 int fileno = atoi( rest.c_str() );
722 typedef std::map<unsigned int, unsigned int> Cycles;
727 for (
size_t i = 0; i <
count; ++i )
729 int filenum =
_script->dbg_filenum[i];
730 if ( filenum == fileno )
732 int linenum =
_script->dbg_linenum[i];
734 cycle_counts[linenum] += ins.
cycles;
738 for ( Cycles::iterator itr = cycle_counts.begin(); itr != cycle_counts.end(); ++itr )
740 unsigned int linenum = ( *itr ).first;
741 unsigned int cycles = ( *itr ).second;
743 results.push_back( result );
752 return "use setscript first";
761 return "No such script.";
766 for (
size_t i = 0; i <
count; ++i )
770 results.push_back( result );
779 return "No such script.";
784 return "Failed to load symbols.";
787 for (
size_t i = 0; i <
count; ++i )
790 results.push_back( result );
797 if ( filenum == 0 || filenum >= static_cast<int>( prog->
dbg_filenames.size() ) )
801 for (
int skip = 1; skip < linenum; ++skip )
803 if ( !getline( ifs, tmp ) )
806 if ( getline( ifs, tmp ) )
816 return "No such script.";
821 return "Failed to load symbols.";
823 int last_filenum = -1;
824 int last_linenum = -1;
826 for (
size_t ins = 0; ins <
count; ++ins )
830 if ( filenum == last_filenum && linenum == last_linenum )
833 std::string result =
get_fileline( eprog, filenum, linenum );
835 results.push_back(
Clib::decint( ins ) +
" " + result );
837 last_filenum = filenum;
838 last_linenum = linenum;
846 return "No script attached.";
853 return "No script attached.";
860 return "No script attached.";
862 int start = uoexec->
PC - 5;
863 int end = uoexec->
PC + 5;
866 if ( end >= static_cast<int>( uoexec->
nLines ) )
868 for (
int i = start; i <= end; ++i )
878 return "No script attached.";
881 return "Script not ready to trace.";
891 return "No script attached.";
894 return "Script not ready to trace.";
898 return "Stepping In.";
904 return "No script attached.";
907 return "Script not ready to trace.";
911 return "Stepping Over.";
917 return "No script attached.";
920 return "Script not ready to trace.";
929 return "No script attached.";
935 return "Marked for break-into.";
940 return "No script attached.";
942 uoexec->
dbg_setbp( atoi( rest.c_str() ) );
943 return "Breakpoint set.";
948 return "No script attached.";
950 uoexec->
dbg_clrbp( atoi( rest.c_str() ) );
951 return "Breakpoint cleared.";
956 return "No script attached.";
959 return "All breakpoints cleared.";
964 return "No script attached.";
968 return "No debug information available.";
970 unsigned ins = uoexec->
PC;
972 ins = atoi( rest.c_str() );
973 int filenum, linenum;
975 return "out of range";
978 return "out of range";
992 return "attach or setscript first";
995 return "No debug information available.";
1000 results.push_back( tmp );
1014 return "attach or setscript first";
1017 return "No debug information available.";
1019 unsigned filenum, firstline, lastline;
1022 if ( !( is >> filenum ) )
1023 return "File # must be specified";
1024 if ( !( is >> firstline ) )
1026 if ( !( is >> lastline ) )
1030 return "File # out of range";
1034 for (
unsigned skip = 1; skip < firstline; ++skip )
1036 if ( !getline( ifs, tmp ) )
1039 while ( ( lastline == 0 || firstline++ <= lastline ) && getline( ifs, tmp ) )
1041 tmp.erase( tmp.find_last_not_of(
"\n\r" ) + 1 );
1042 results.push_back( tmp );
1050 return "No script attached.";
1054 return "No debug information available.";
1058 size_t left = uoexec->
Locals2->size();
1059 results.resize( left );
1062 while ( left <= prog->blocks[block].parentvariables )
1064 block = prog->
blocks[block].parentblockidx;
1066 size_t varidx = left - 1 - prog->
blocks[block].parentvariables;
1067 results[left - 1] = prog->
blocks[block].localvarnames[varidx];
1075 return "No script attached.";
1079 return "No debug information available.";
1081 BObjectRefVec::const_iterator itr = uoexec->
Globals2.begin(), end = uoexec->
Globals2.end();
1083 for (
unsigned idx = 0; itr != end; ++itr, ++idx )
1095 return "No script attached.";
1099 unsigned varidx = atoi( rest.c_str() );
1100 if ( varidx >= uoexec->
Locals2->size() )
1101 return "Error: Index out of range";
1102 return "Value: " + ( *uoexec->
Locals2 )[varidx]->impref().getStringRep();
1108 return "No script attached.";
1111 unsigned varidx = atoi( rest.c_str() );
1112 if ( varidx >= uoexec->
Locals2->size() )
1113 return "Error: Index out of range";
1117 const char* memname;
1120 if ( strrep.find(
"ItemRef" ) != std::string::npos )
1122 for ( i = 0; i < 14; i++ )
1124 memname = poldbg_base_members[i];
1125 os << memname <<
" " << var.
get_member( memname ).
get()->impptr()->getStringRep();
1131 for ( i = 0; i < 27; i++ )
1133 memname = poldbg_itemref_members[i];
1134 os << memname <<
" " << var.
get_member( memname ).
get()->impptr()->getStringRep();
1141 else if ( strrep.find(
"MobileRef" ) != std::string::npos )
1143 for ( i = 0; i < 14; i++ )
1145 memname = poldbg_base_members[i];
1146 os << memname <<
" " << var.
get_member( memname ).
get()->impptr()->getStringRep();
1152 for ( i = 0; i < 59; i++ )
1154 memname = poldbg_mobileref_members[i];
1155 os << memname <<
" " << var.
get_member( memname ).
get()->impptr()->getStringRep();
1161 return "Value: " + strrep;
1166 unsigned filenum, linenum;
1168 return "No script attached.";
1172 return "No debug information available.";
1175 if ( !( is >> filenum ) )
1176 return "File # must be specified";
1177 if ( !( is >> linenum ) )
1178 return "Line # must be specified";
1181 return "File # out of range";
1183 for (
unsigned i = 0; i < prog->
dbg_filenum.size(); ++i )
1191 if ( !results.empty() )
1200 return "No script attached.";
1204 unsigned varidx = atoi( rest.c_str() );
1205 if ( varidx >= uoexec->
Locals2->size() )
1206 return "Error: Index out of range";
1207 return "Value: " + ( *uoexec->
Locals2 )[varidx]->impref().pack();
1212 return "No script attached.";
1216 unsigned varidx = atoi( rest.c_str() );
1217 if ( varidx >= uoexec->
Globals2.size() )
1218 return "Error: Index out of range";
1219 return "Value: " + uoexec->
Globals2[varidx]->impref().pack();
1224 return "No script attached.";
1231 if ( !( is >> varidx ) )
1232 return "format: setlocalpacked [varidx] [packedvalue]";
1234 is.unsetf( std::ios::skipws );
1236 is.setf( std::ios::skipws );
1238 if ( varidx >= uoexec->
Locals2->size() )
1239 return "Error: Index out of range";
1244 if ( newimp ==
nullptr )
1245 return "Error: unable to unpack";
1249 return "Value: " + ( *uoexec->
Locals2 )[varidx]->impref().pack();
1254 return "No script attached.";
1260 if ( !( is >> varidx ) )
1261 return "format: setglobalpacked [varidx] [packedvalue]";
1262 is.unsetf( std::ios::skipws );
1264 is.setf( std::ios::skipws );
1266 if ( varidx >= uoexec->
Globals2.size() )
1267 return "Error: Index out of range";
1272 if ( newimp ==
nullptr )
1273 return "Error: unable to unpack";
1277 return "Value: " + uoexec->
Globals2[varidx]->impref().pack();
1292 if ( !_sck.is_local() )
1294 Clib::writeline( _sck,
"Only accepting connections from localhost." );
1299 std::string cmdline;
1300 std::vector<std::string> results;
1301 while ( !dctx.
done() )
1307 bool ret = dctx.
process( cmdline, results );
1312 for (
unsigned i = 0; i < results.size(); ++i )
std::string cmd_kill(unsigned pid)
virtual BObjectRef get_member(const char *membername)
std::vector< unsigned > dbg_ins_blocks
virtual std::string getStringRep() const =0
const EScriptProgram * prog() const
const std::string & value() const
bool in_debugger_holdlist() const
std::string get_fileline(EScriptProgram *prog, int filenum, int linenum)
std::string cmd_scriptins(const std::string &rest, Results &results)
void splitnamevalue(const std::string &istr, std::string &propname, std::string &propvalue)
std::string cmd_clrallbp()
const char * poldbg_base_members[]
ValueStackCont ValueStack
bool config_nodie(const std::string &name, const Plib::Package *pkg, const char *mainpfx)
std::string cmd_stacktrace(Results &results)
ref_ptr< EScriptProgram > _script
std::string cmd_ins(Results &results)
std::string debug_password
std::string cmd_loadsym(unsigned pid)
BApplicObj< ref_ptr< DebugContext > > DebugContextObjImpBase
bool find_uoexec(unsigned int pid, UOExecutor **pp_uoexec)
std::string cmd_attach(unsigned pid)
std::string cmd_inslist(const std::string &rest, Results &results)
std::string decint(unsigned short v)
int match(char *a, char *b)
std::vector< BObjectRef > BObjectRefVec
std::string cmd_getlocalpacked(const std::string &rest)
std::string cmd_setglobalpacked(const std::string &rest)
boost_utils::script_name_flystring name
std::string cmd_call(const std::string &rest, Results &results)
void debug_listen_thread(void)
#define OSTRINGSTREAM_STR(x)
bool process(const std::string &cmd, Results &results)
[1] Debugger Commands: password [pwd] Authorize with password quit exit debugger start [eclfile] Star...
std::string cmd_setscript(const std::string &rest, Results &results)
bool isa(BObjectImp::BObjectType type) const
const char * poldbg_itemref_members[]
virtual std::string pack() const
std::string cmd_funclist(const std::string &rest, Results &results)
std::string cmd_setbp(const std::string &rest)
std::string cmd_localvars(Results &results)
const std::string & name() const
std::string dbg_get_instruction(size_t atPC) const
std::string cmd_localvar(const std::string &rest)
void pushArg(BObjectImp *arg)
std::vector< std::string > Results
void setimp(BObjectImp *imp)
std::vector< std::string > globalvarnames
std::vector< ReturnContext > ControlStack
std::vector< std::string > dbg_filenames
std::string cmd_globalvars(Results &results)
std::vector< BObjectRefVec * > upperLocals2
std::string cmd_instrace()
void writeline(Socket &sck, const std::string &s)
std::string tostring(const Bscript::BTokenType &v)
std::string cmd_files(Results &results)
std::string cmd_srcprof(const std::string &rest, Results &results)
std::string dbg_get_instruction(size_t atPC) const
DebugContextObjImp(ref_ptr< DebugContext > rcdctx)
std::string cmd_filecont(const std::string &rest, Results &results)
virtual u8 typeOfInt() const POL_OVERRIDE
std::vector< Instruction > instr
static BObjectImp * unpack(const char *pstr)
virtual BObjectImp * copy() const POL_OVERRIDE
std::string cmd_localvarmembers(const std::string &rest, Results &results)
weak_ptr_owner< UOExecutor > weakptr
std::string cmd_scriptlist(const std::string &rest, Results &results)
std::string cmd_stepover()
std::string cmd_scriptprofile(const std::string &rest, Results &results)
std::vector< EPDbgBlock > blocks
unsigned int count() const
std::string cmd_getglobalpacked(const std::string &rest)
virtual const char * typeOf() const POL_OVERRIDE
BObjectImp * create_debug_context()
ScriptScheduler scriptScheduler
void dbg_setbp(unsigned atPC)
const PidList & getPidlist()
std::string cmd_start(const std::string &rest)
const std::string & scriptname() const
std::vector< unsigned > dbg_linenum
std::vector< unsigned > dbg_filenum
const String * getStringParam(unsigned param)
BApplicObjType debugcontextobjimp_type
std::string strlower(const std::string &str)
void dbg_clrbp(unsigned atPC)
std::string prompt() const
virtual BObjectRef get_member(const char *membername) POL_OVERRIDE
std::string cmd_funcprof(const std::string &rest, Results &results)
std::string cmd_pidlist(const std::string &rest, Results &results)
std::vector< std::string > localvarnames
std::string cmd_setlocalpacked(const std::string &rest)
bool hasParams(unsigned howmany) const
weak_ptr< UOExecutor > uoexec_wptr
virtual void run() POL_OVERRIDE
std::string cmd_stepinto()
std::string cmd_clrbp(const std::string &rest)
virtual BObjectImp * call_method(const char *methodname, Executor &ex) POL_OVERRIDE
bool run(int argc, char **argv)
void start_script(const char *filename, Bscript::BObjectImp *param0, Bscript::BObjectImp *param1)
bool GetConnection(unsigned int timeout_sec)
bool readline(Socket &sck, std::string &s, bool *timeout_exit, unsigned int timeout_secs, unsigned maxlen)
std::string cmd_scriptsrc(const std::string &rest, Results &results)
DebugClientThread(Clib::SocketListener &SL)
BObjectImp * run_executor_to_completion(UOExecutor &ex, const ScriptDef &script)
std::atomic< bool > exit_signalled
Module::OSExecutorModule * os_module
const char * poldbg_mobileref_members[]
std::string cmd_fileline(const std::string &rest)