//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #ifndef _TELNETDEBUGGER_H_ #define _TELNETDEBUGGER_H_ #ifndef _PLATFORM_PLATFORMNET_H_ #include "platform/platformNet.h" #endif class CodeBlock; /// Telnet debug service implementation. /// /// This is the C++ side of the built-in Torque debugger. /// /// To use the debugger, use dbgSetParameters(port, password); in the console /// of the server to enable debugger connections. Then on some other system, /// start up the app (you don't have to start a game or connect to the /// server) and exec("common/debugger/debugger.tscript"); in the console. Then use /// the debugger GUI to connect to the server with the right port and password. /// /// @see http://www.planettribes.com/tribes2/editing.shtml for more thorough discussion. class TelnetDebugger { S32 mAcceptPort; NetSocket mAcceptSocket; NetSocket mDebugSocket; enum { // We should only change this is we truely // break the protocol in a future version. Version = 2, PasswordMaxLength = 32, MaxCommandSize = 2048 }; char mDebuggerPassword[PasswordMaxLength+1]; enum State { NotConnected, PasswordTry, Initialize, Connected }; S32 mState; char mLineBuffer[MaxCommandSize]; S32 mCurPos; bool mWaitForClient; TelnetDebugger(); ~TelnetDebugger(); struct Breakpoint { StringTableEntry fileName; CodeBlock *code; U32 lineNumber; S32 passCount; S32 curCount; char *testExpression; bool clearOnHit; Breakpoint *next; }; Breakpoint *mBreakpoints; Breakpoint **findBreakpoint(StringTableEntry fileName, S32 lineNumber); bool mProgramPaused; bool mBreakOnNextStatement; S32 mStackPopBreakIndex; void addVariableBreakpoint(const char *varName, S32 passCount, const char *evalString); void removeVariableBreakpoint(const char *varName); void addBreakpoint(const char *fileName, S32 line, bool clear, S32 passCount, const char *evalString); void removeBreakpoint(const char *fileName, S32 line); void removeAllBreakpoints(); void debugBreakNext(); void debugContinue(); void debugStepIn(); void debugStepOver(); void debugStepOut(); void evaluateExpression(const char *tag, S32 frame, const char *evalBuffer); void dumpFileList(); void dumpBreakableList(const char *fileName); void removeBreakpointsFromCode(CodeBlock *code); void checkDebugRecv(); void processLineBuffer(S32); void sendBreak(); void setBreakOnNextStatement( bool enabled ); public: static void create(); static void destroy(); void disconnect(); bool isConnected() const { return mState == Connected; } void process(); void popStackFrame(); void pushStackFrame(); void addAllBreakpoints(CodeBlock *code); void clearCodeBlockPointers(CodeBlock *code); void breakProcess(); void executionStopped(CodeBlock *code, U32 lineNumber); void send(const char *s); void setDebugParameters(S32 port, const char *password, bool waitForClient); void processConsoleLine(const char *consoleLine); }; extern TelnetDebugger *TelDebugger; #endif