1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "tools/edit_gui_common.h"
30
31
32 #include "../../sys/win32/rc/debugger_resource.h"
33 #include "DebuggerApp.h"
34 #include "DebuggerServer.h"
35
36 DWORD CALLBACK DebuggerThread ( LPVOID param );
37
38 rvDebuggerApp gDebuggerApp;
39 HWND gDebuggerWindow = NULL;
40 bool gDebuggerSuspend = false;
41 bool gDebuggerConnnected = false;
42 HANDLE gDebuggerGameThread = NULL;
43
44 rvDebuggerServer* gDebuggerServer = NULL;
45 HANDLE gDebuggerServerThread = NULL;
46 DWORD gDebuggerServerThreadID = 0;
47 bool gDebuggerServerQuit = false;
48
49 /*
50 ================
51 DebuggerMain
52
53 Main entry point for the debugger application
54 ================
55 */
DebuggerClientInit(const char * cmdline)56 void DebuggerClientInit( const char *cmdline )
57 {
58 // See if the debugger is already running
59 if ( rvDebuggerWindow::Activate ( ) )
60 {
61 goto DebuggerClientInitDone;
62 }
63
64 if ( !gDebuggerApp.Initialize ( win32.hInstance ) )
65 {
66 goto DebuggerClientInitDone;
67 }
68
69 gDebuggerApp.Run ( );
70
71 DebuggerClientInitDone:
72
73 common->Quit();
74 }
75
76 /*
77 ================
78 DebuggerLaunch
79
80 Launches another instance of the running executable with +debugger appended
81 to the end to indicate that the debugger should start up.
82 ================
83 */
DebuggerClientLaunch(void)84 void DebuggerClientLaunch ( void )
85 {
86 if ( renderSystem->IsFullScreen() ) {
87 common->Printf( "Cannot run the script debugger in fullscreen mode.\n"
88 "Set r_fullscreen to 0 and vid_restart.\n" );
89 return;
90 }
91
92 // See if the debugger is already running
93 if ( rvDebuggerWindow::Activate ( ) ) {
94 return;
95 }
96
97 char exeFile[MAX_PATH];
98 char curDir[MAX_PATH];
99
100 STARTUPINFO startup;
101 PROCESS_INFORMATION process;
102
103 ZeroMemory ( &startup, sizeof(startup) );
104 startup.cb = sizeof(startup);
105
106 GetCurrentDirectory ( MAX_PATH, curDir );
107
108 GetModuleFileName ( NULL, exeFile, MAX_PATH );
109 const char* s = va("%s +set fs_game %s +set fs_cdpath %s +debugger", exeFile, cvarSystem->GetCVarString( "fs_game" ), cvarSystem->GetCVarString( "fs_cdpath" ) );
110 CreateProcess ( NULL, (LPSTR)s,
111 NULL, NULL, FALSE, 0, NULL, curDir, &startup, &process );
112
113 CloseHandle ( process.hThread );
114 CloseHandle ( process.hProcess );
115 }
116
117 /*
118 ================
119 DebuggerServerThread
120
121 Thread proc for the debugger server
122 ================
123 */
DebuggerServerThread(LPVOID param)124 DWORD CALLBACK DebuggerServerThread ( LPVOID param )
125 {
126 assert ( gDebuggerServer );
127
128 while ( !gDebuggerServerQuit )
129 {
130 gDebuggerServer->ProcessMessages ( );
131 Sleep ( 1 );
132 }
133
134 return 0;
135 }
136
137 /*
138 ================
139 DebuggerServerInit
140
141 Starts up the debugger server
142 ================
143 */
DebuggerServerInit(void)144 bool DebuggerServerInit ( void )
145 {
146 // Dont do this if we are in the debugger already
147 if ( com_editors & EDITOR_DEBUGGER )
148 {
149 return false;
150 }
151
152 // Allocate the new debugger server
153 gDebuggerServer = new rvDebuggerServer;
154 if ( !gDebuggerServer )
155 {
156 return false;
157 }
158
159 // Initialize the debugger server
160 if ( !gDebuggerServer->Initialize ( ) )
161 {
162 delete gDebuggerServer;
163 gDebuggerServer = NULL;
164 return false;
165 }
166
167 // Start the debugger server thread
168 gDebuggerServerThread = CreateThread ( NULL, 0, DebuggerServerThread, 0, 0, &gDebuggerServerThreadID );
169
170 return true;
171 }
172
173 /*
174 ================
175 DebuggerServerShutdown
176
177 Shuts down the debugger server
178 ================
179 */
DebuggerServerShutdown(void)180 void DebuggerServerShutdown ( void )
181 {
182 if ( gDebuggerServerThread )
183 {
184 // Signal the debugger server to quit
185 gDebuggerServerQuit = true;
186
187 // Wait for the thread to finish
188 WaitForSingleObject ( gDebuggerServerThread, INFINITE );
189
190 // Shutdown the server now
191 gDebuggerServer->Shutdown();
192
193 delete gDebuggerServer;
194 gDebuggerServer = NULL;
195
196 // Cleanup the thread handle
197 CloseHandle ( gDebuggerServerThread );
198 gDebuggerServerThread = NULL;
199 }
200 }
201
202 /*
203 ================
204 DebuggerServerCheckBreakpoint
205
206 Check to see if there is a breakpoint associtated with this statement
207 ================
208 */
DebuggerServerCheckBreakpoint(idInterpreter * interpreter,idProgram * program,int instructionPointer)209 void DebuggerServerCheckBreakpoint ( idInterpreter* interpreter, idProgram* program, int instructionPointer )
210 {
211 if ( !gDebuggerServer )
212 {
213 return;
214 }
215
216 gDebuggerServer->CheckBreakpoints ( interpreter, program, instructionPointer );
217 }
218
219 /*
220 ================
221 DebuggerServerPrint
222
223 Sends a print message to the debugger client
224 ================
225 */
DebuggerServerPrint(const char * text)226 void DebuggerServerPrint ( const char* text )
227 {
228 if ( !gDebuggerServer )
229 {
230 return;
231 }
232
233 gDebuggerServer->Print ( text );
234 }
235