Skip to content

Commit 9062bdf

Browse files
Add Squirrel debugger
1 parent 82bc30c commit 9062bdf

File tree

14 files changed

+11446
-10
lines changed

14 files changed

+11446
-10
lines changed

sp/src/game/client/vscript_client.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
extern IScriptManager *scriptmanager;
2929
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
3030

31+
#ifdef MAPBASE_VSCRIPT
32+
extern int vscript_debugger_port;
33+
#endif
34+
3135
// #define VMPROFILE 1
3236

3337
#ifdef VMPROFILE
@@ -682,6 +686,14 @@ bool VScriptClientInit()
682686
//g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
683687
#endif
684688

689+
#ifdef MAPBASE_VSCRIPT
690+
if ( vscript_debugger_port )
691+
{
692+
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
693+
vscript_debugger_port = 0;
694+
}
695+
#endif
696+
685697
if (scriptLanguage == SL_SQUIRREL)
686698
{
687699
g_pScriptVM->Run( g_Script_vscript_client );
@@ -768,11 +780,19 @@ class CVScriptGameSystem : public CAutoGameSystemPerFrame
768780
VScriptClientTerm();
769781
}
770782

771-
virtual void FrameUpdatePostEntityThink()
783+
#ifdef MAPBASE_VSCRIPT
784+
virtual void Update( float frametime )
785+
{
786+
if ( g_pScriptVM )
787+
g_pScriptVM->Frame( frametime );
788+
}
789+
#else
790+
virtual void FrameUpdatePostEntityThink()
772791
{
773792
if ( g_pScriptVM )
774793
g_pScriptVM->Frame( gpGlobals->frametime );
775794
}
795+
#endif
776796

777797
bool m_bAllowEntityCreationInScripts;
778798
};

sp/src/game/server/vscript_server.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222

2323
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
2424

25+
#ifdef MAPBASE_VSCRIPT
26+
extern int vscript_debugger_port;
27+
#endif
28+
2529
// #define VMPROFILE 1
2630

2731
#ifdef VMPROFILE
@@ -663,6 +667,14 @@ bool VScriptServerInit()
663667
RegisterSharedScriptFunctions();
664668
#endif
665669

670+
#ifdef MAPBASE_VSCRIPT
671+
if ( vscript_debugger_port )
672+
{
673+
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
674+
vscript_debugger_port = 0;
675+
}
676+
#endif
677+
666678
if (scriptLanguage == SL_SQUIRREL)
667679
{
668680
g_pScriptVM->Run( g_Script_vscript_server );

sp/src/game/shared/vscript_shared.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
3737
#ifdef MAPBASE_VSCRIPT
3838
// This is to ensure a dependency exists between the vscript library and the game DLLs
3939
extern int vscript_token;
40+
extern int vscript_debugger_port;
4041
int vscript_token_hack = vscript_token;
4142
#endif
4243

@@ -390,12 +391,30 @@ CON_COMMAND_F( script_debug, "Connect the vscript VM to the script debugger", FC
390391
if ( !IsCommandIssuedByServerAdmin() )
391392
return;
392393

394+
#ifdef MAPBASE_VSCRIPT
395+
#ifdef GAME_DLL
396+
int port = 1212;
397+
#else
398+
int port = 1213;
399+
#endif
400+
#endif
401+
393402
if ( !g_pScriptVM )
394403
{
404+
#ifdef MAPBASE_VSCRIPT
405+
vscript_debugger_port = port;
406+
CGMsg( 0, CON_GROUP_VSCRIPT, "VScript VM is not running, waiting for it to attach the debugger to port %d...\n", port );
407+
#else
395408
CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" );
409+
#endif
396410
return;
397411
}
412+
413+
#ifdef MAPBASE_VSCRIPT
414+
g_pScriptVM->ConnectDebugger( port );
415+
#else
398416
g_pScriptVM->ConnectDebugger();
417+
#endif
399418
}
400419

401420
#ifdef CLIENT_DLL

sp/src/public/vscript/ivscript.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,11 @@ class IScriptVM
838838
virtual bool Init() = 0;
839839
virtual void Shutdown() = 0;
840840

841+
#ifdef MAPBASE_VSCRIPT
842+
virtual bool ConnectDebugger( int port = 0 ) = 0;
843+
#else
841844
virtual bool ConnectDebugger() = 0;
845+
#endif
842846
virtual void DisconnectDebugger() = 0;
843847

844848
virtual ScriptLanguage_t GetLanguage() = 0;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//-----------------------------------------------------------------------
2+
// github.com/samisalreadytaken/sqdbg
3+
//-----------------------------------------------------------------------
4+
//
5+
// Squirrel Debugger
6+
//
7+
8+
#ifndef SQDBG_SERVER_H
9+
#define SQDBG_SERVER_H
10+
11+
#include <squirrel.h>
12+
13+
#define SQDBG_SV_API_VER 1
14+
15+
struct SQDebugServer;
16+
typedef SQDebugServer* HSQDEBUGSERVER;
17+
18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
21+
22+
// Create and attach a new debugger
23+
// Memory is owned by the VM, it is freed when the VM dies or
24+
// the debugger is disconnected via sqdbg_destroy_debugger()
25+
extern HSQDEBUGSERVER sqdbg_attach_debugger( HSQUIRRELVM vm );
26+
27+
// Detach and destroy the debugger attached to this VM
28+
// Invalidates the handle returned from sqdbg_attach_debugger()
29+
extern void sqdbg_destroy_debugger( HSQUIRRELVM vm );
30+
31+
// Open specified port and allow client connections
32+
// Returns 0 on success
33+
extern int sqdbg_listen_socket( HSQDEBUGSERVER dbg, unsigned short port );
34+
35+
// Process client connections and incoming messages
36+
extern void sqdbg_frame( HSQDEBUGSERVER dbg );
37+
38+
// Redirects to sq_compilebuffer
39+
// If the VM has a debugger attached, copies every script to be able to source them to debugger clients
40+
extern SQRESULT sqdbg_compilebuffer( HSQUIRRELVM vm, const SQChar *script, SQInteger size,
41+
const SQChar *sourcename, SQBool raiseerror );
42+
43+
#ifdef __cplusplus
44+
}
45+
#endif
46+
47+
#endif // SQDBG_SERVER_H

sp/src/vscript/sqdbg/sqdbg/debug.h

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//-----------------------------------------------------------------------
2+
// github.com/samisalreadytaken/sqdbg
3+
//-----------------------------------------------------------------------
4+
//
5+
6+
#ifndef SQDBG_DEBUG_H
7+
#define SQDBG_DEBUG_H
8+
9+
#ifdef _DEBUG
10+
#ifdef _WIN32
11+
#include <crtdbg.h>
12+
13+
bool __IsDebuggerPresent();
14+
15+
static inline const char *GetModuleBaseName()
16+
{
17+
static char module[MAX_PATH];
18+
DWORD len = GetModuleFileNameA( NULL, module, sizeof(module) );
19+
20+
if ( len != 0 )
21+
{
22+
for ( char *pBase = module + len; pBase-- > module; )
23+
{
24+
if ( *pBase == '\\' )
25+
return pBase + 1;
26+
}
27+
28+
return module;
29+
}
30+
31+
return "";
32+
}
33+
34+
#define DebuggerBreak() do { if ( __IsDebuggerPresent() ) __debugbreak(); } while(0);
35+
36+
#define Assert(x) \
37+
do { \
38+
__CAT( L, __LINE__ ): \
39+
if ( !(x) && (1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, GetModuleBaseName(), #x)) ) { \
40+
if ( !__IsDebuggerPresent() ) \
41+
goto __CAT( L, __LINE__ ); \
42+
__debugbreak(); \
43+
} \
44+
} while(0)
45+
46+
#define AssertMsg(x,msg) \
47+
do { \
48+
__CAT( L, __LINE__ ): \
49+
if ( !(x) && (1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, GetModuleBaseName(), msg)) ) { \
50+
if ( !__IsDebuggerPresent() ) \
51+
goto __CAT( L, __LINE__ ); \
52+
__debugbreak(); \
53+
} \
54+
} while(0)
55+
56+
#define AssertMsgF(x,msg,...) \
57+
do { \
58+
__CAT( L, __LINE__ ): \
59+
if ( !(x) && (1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, GetModuleBaseName(), msg, __VA_ARGS__)) ) { \
60+
if ( !__IsDebuggerPresent() ) \
61+
goto __CAT( L, __LINE__ ); \
62+
__debugbreak(); \
63+
} \
64+
} while(0)
65+
#else
66+
extern "C" int printf(const char *, ...);
67+
68+
#define DebuggerBreak() asm("int3")
69+
70+
#define Assert(x) \
71+
do { \
72+
if ( !(x) ) \
73+
{ \
74+
::printf("Assertion failed %s:%d: %s\n", __FILE__, __LINE__, #x); \
75+
DebuggerBreak(); \
76+
} \
77+
} while(0)
78+
79+
#define AssertMsg(x,msg) \
80+
do { \
81+
if ( !(x) ) \
82+
{ \
83+
::printf("Assertion failed %s:%d: %s\n", __FILE__, __LINE__, msg); \
84+
DebuggerBreak(); \
85+
} \
86+
} while(0)
87+
88+
#define AssertMsgF(x,msg,...) \
89+
do { \
90+
if ( !(x) ) \
91+
{ \
92+
::printf("Assertion failed %s:%d: ", __FILE__, __LINE__); \
93+
::printf(msg, __VA_ARGS__); \
94+
::printf("\n"); \
95+
DebuggerBreak(); \
96+
} \
97+
} while(0)
98+
#endif
99+
#define Verify(x) Assert(x)
100+
#else
101+
#define DebuggerBreak()
102+
#define Assert(x)
103+
#define AssertMsg(x,msg)
104+
#define AssertMsgF(x,msg,...)
105+
#define Verify(x) x
106+
#endif // _DEBUG
107+
108+
#ifdef _WIN32
109+
#define UNREACHABLE() do { Assert(!"UNREACHABLE"); __assume(0); } while(0);
110+
#else
111+
#define UNREACHABLE() do { Assert(!"UNREACHABLE"); __builtin_unreachable(); } while(0);
112+
#endif
113+
114+
#define ___CAT(a, b) a##b
115+
#define __CAT(a, b) ___CAT(a,b)
116+
117+
#ifndef assert
118+
#define assert(x) Assert(x)
119+
#endif
120+
121+
#ifdef _DEBUG
122+
class CEntryCounter
123+
{
124+
int *count;
125+
public:
126+
CEntryCounter( int *p ) : count(p) { (*count)++; }
127+
~CEntryCounter() { (*count)--; }
128+
};
129+
130+
#define TRACK_ENTRIES() \
131+
static int s_EntryCount = 0; \
132+
CEntryCounter entrycounter( &s_EntryCount );
133+
#else
134+
#define TRACK_ENTRIES()
135+
#endif
136+
137+
#endif // SQDBG_DEBUG_H

0 commit comments

Comments
 (0)