Skip to content

Commit 9660448

Browse files
Add Squirrel debugger
1 parent 82bc30c commit 9660448

File tree

15 files changed

+21496
-12
lines changed

15 files changed

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

0 commit comments

Comments
 (0)