Skip to content

Commit f536972

Browse files
Add Squirrel debugger
1 parent 82bc30c commit f536972

File tree

15 files changed

+22623
-12
lines changed

15 files changed

+22623
-12
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: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//-----------------------------------------------------------------------
2+
// github.com/samisalreadytaken/sqdbg
3+
//-----------------------------------------------------------------------
4+
//
5+
// Squirrel Debugger
6+
//
7+
8+
#ifndef SQDBG_H
9+
#define SQDBG_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+
// If port is 0, the system will choose a unique available port
33+
// Returns 0 on success
34+
extern int sqdbg_listen_socket( HSQDEBUGSERVER dbg, unsigned short port );
35+
36+
// Process client connections and incoming messages
37+
// Blocks on script breakpoints while a client is connected
38+
extern void sqdbg_frame( HSQDEBUGSERVER dbg );
39+
40+
// Copies the script to be able to source it to debugger clients
41+
extern void sqdbg_on_script_compile( HSQDEBUGSERVER dbg, const SQChar *script, SQInteger size,
42+
const SQChar *sourcename, SQInteger sourcenamelen );
43+
44+
#ifdef __cplusplus
45+
}
46+
#endif
47+
48+
#endif // SQDBG_H

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

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

0 commit comments

Comments
 (0)