18 #include "precompiled.h"
29 "HTTP/1.1 400 Bad Request\r\n"
30 "Content-Type: text/plain; charset=utf-8\r\n\r\n"
36 response.str(std::string());
37 std::stringstream stream;
38 uint nbrCallstacksWritten = 0;
39 std::list<CThreadDebugger*>::iterator itr;
45 if ((*itr)->GetIsInBreak())
47 stream.str(std::string());
48 (*itr)->GetCallstack(stream);
49 if ((
int)stream.tellp() != 0)
51 if (nbrCallstacksWritten != 0)
53 response <<
"{" <<
"\"ThreadDebuggerID\" : " << (*itr)->GetID() <<
", \"CallStack\" : " << stream.str() <<
"}";
54 nbrCallstacksWritten++;
66 response.str(std::string());
67 std::stringstream stream;
68 std::list<CThreadDebugger*>::iterator itr;
71 if ((*itr)->GetID() == threadDebuggerID && (*itr)->GetIsInBreak())
73 (*itr)->GetStackFrameData(stream, nestingLevel, stackInfoKind);
74 if ((
int)stream.tellp() != 0)
76 response << stream.str();
96 LOGWARNING(L
"Javascript debugging webserver enabled.");
112 std::list<CThreadDebugger*>::iterator itr;
115 if ((*itr)->GetID() == threadDebuggerID || threadDebuggerID == 0)
117 if (
DBG_CMD_NONE == (*itr)->GetNextDbgCmd() && (*itr)->GetIsInBreak())
121 (*itr)->SetNextDbgCmd(dbgCmd);
179 std::vector<std::string>& templates = *(std::vector<std::string>*)cbData;
180 std::wstring str(pathname.
string());
181 templates.push_back(std::string(str.begin(), str.end()));
189 response.str(std::string());
191 std::vector<std::string> templates;
194 std::vector<std::string>::iterator itr;
196 for (itr = templates.begin(); itr != templates.end(); ++itr)
198 if (itr != templates.begin())
200 response <<
"\"" << *itr <<
"\"";
210 response <<
"Failed to load the file contents";
228 void* handled = (
void*)
"";
230 const char* header200 =
231 "HTTP/1.1 200 OK\r\n"
232 "Access-Control-Allow-Origin: *\r\n"
233 "Content-Type: text/plain; charset=utf-8\r\n\r\n";
235 const char* header404 =
236 "HTTP/1.1 404 Not Found\r\n"
237 "Content-Type: text/plain; charset=utf-8\r\n\r\n"
244 std::stringstream stream;
245 std::string uri = request_info->
uri;
247 if (uri ==
"/GetThreadDebuggerStatus")
251 else if (uri ==
"/EnumVfsJSFiles")
255 else if (uri ==
"/GetAllCallstacks")
259 else if (uri ==
"/Continue")
261 uint threadDebuggerID;
262 if (!
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
267 else if (uri ==
"/Break")
271 else if (uri ==
"/SetSettingSimultaneousThreadBreak")
273 std::string strEnabled;
274 bool bEnabled =
false;
275 if (!
GetWebArgs(conn, request_info,
"enabled", strEnabled))
278 if (strEnabled ==
"true")
280 else if (strEnabled ==
"false")
286 else if (uri ==
"/GetSettingSimultaneousThreadBreak")
290 else if (uri ==
"/SetSettingBreakOnException")
292 std::string strEnabled;
293 bool bEnabled =
false;
294 if (!
GetWebArgs(conn, request_info,
"enabled", strEnabled))
297 if (strEnabled ==
"true")
299 else if (strEnabled ==
"false")
305 else if (uri ==
"/GetSettingBreakOnException")
309 else if (uri ==
"/Step")
311 uint threadDebuggerID;
312 if (!
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
317 else if (uri ==
"/StepInto")
319 uint threadDebuggerID;
320 if (!
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
325 else if (uri ==
"/StepOut")
327 uint threadDebuggerID;
328 if (!
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
333 else if (uri ==
"/GetStackFrame")
336 uint threadDebuggerID;
337 if (!
GetWebArgs(conn, request_info,
"nestingLevel", nestingLevel) ||
338 !
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
344 else if (uri ==
"/GetStackFrameThis")
347 uint threadDebuggerID;
348 if (!
GetWebArgs(conn, request_info,
"nestingLevel", nestingLevel) ||
349 !
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
355 else if (uri ==
"/GetCurrentGlobalObject")
357 uint threadDebuggerID;
358 if (!
GetWebArgs(conn, request_info,
"threadDebuggerID", threadDebuggerID))
364 else if (uri ==
"/ToggleBreakpoint")
366 std::string filename;
368 if (!
GetWebArgs(conn, request_info,
"filename", filename) ||
369 !
GetWebArgs(conn, request_info,
"line", line))
375 else if (uri ==
"/GetFile")
377 std::string filename;
378 if (!
GetWebArgs(conn, request_info,
"filename", filename))
389 std::string str = stream.str();
390 mg_write(conn, str.c_str(), str.length());
417 const char *options[] = {
418 "listening_ports",
"127.0.0.1:9000",
477 std::list<CThreadDebugger*>::iterator itr;
480 if ((*itr)->CompareScriptInterfacePtr(pScriptInterface))
493 response.str(std::string());
494 std::list<CThreadDebugger*>::iterator itr;
504 response <<
"\"ThreadDebuggerID\" : " << (*itr)->GetID() <<
",";
505 response <<
"\"ScriptInterfaceName\" : \"" << (*itr)->GetName() <<
"\",";
506 response <<
"\"ThreadInBreak\" : " << ((*itr)->GetIsInBreak() ?
"true" :
"false") <<
",";
507 response <<
"\"BreakFileName\" : \"" << (*itr)->GetBreakFileName() <<
"\",";
508 response <<
"\"BreakLine\" : " << (*itr)->GetLastBreakLine();
519 std::list<CThreadDebugger*>::iterator itr;
522 if ((*itr)->ToggleBreakPoint(filename, line))
528 std::list<CBreakPoint>* pBreakPoints = NULL;
532 bool deleted =
false;
533 for (std::list<CBreakPoint>::iterator itr = pBreakPoints->begin(); itr != pBreakPoints->end(); ++itr)
535 if ((*itr).m_Filename == filename && (*itr).m_UserLine == line)
537 itr = pBreakPoints->erase(itr);
549 pBreakPoints->push_back(bP);
CDebuggingServer * g_DebuggingServer
bool m_SettingBreakOnException
CStr DecodeUTF8() const
Returns contents of a UTF-8 encoded file as a string with optional BOM removed.
static const char * header400
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
std::list< CBreakPoint > m_BreakPoints
bool SetNextDbgCmd(uint threadDebuggerID, DBGCMD dbgCmd)
bool GetSettingBreakOnException()
const PSRETURN PSRETURN_OK
Reads a file, then gives read-only access to the contents.
double m_BreakPointsLockID
void RegisterScriptinterface(std::string name, ScriptInterface *pScriptInterface)
Register a new ScriptInerface for debugging the scripts it executes.
Locks a CMutex over this object's lifetime.
bool GetWebArgs(struct mg_connection *conn, const struct mg_request_info *request_info, std::string argName, uint &arg)
Webserver helper function (can be called by multiple mongooser threads)
CMutex m_Mutex
Mutexes used to ensure thread-safety.
bool GetBreakRequestedByUser()
void * MgDebuggingServerCallback(mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info)
std::list< CThreadDebugger * > m_ThreadDebuggers
Shared between multiple scriptinerface threads and multiple mongoose threads.
void GetThreadDebuggerStatus(std::stringstream &response)
Functions that are made available via http (can be called by multiple mongoose threads) ...
SDL_sem * m_BreakPointsSem
Used for controlling access to m_BreakPoints.
uint m_LastThreadDebuggerID
Shared between multiple scriptinterface threads.
void Initialize(uint id, std::string name, ScriptInterface *pScriptInterface, CDebuggingServer *pDebuggingServer)
Initialize the object (required before using the object!).
void ReleaseBreakPointAccess(double breakPointsLockID)
See AquireBreakPointAccess().
void SDL_DestroySemaphore(SDL_sem *sem)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
static Status AddFileResponse(const VfsPath &pathname, const CFileInfo &fileInfo, const uintptr_t cbData)
void EnableHTTP()
Not important for this class' thread-safety.
void GetStackFrameData(std::stringstream &response, uint nestingLevel, uint threadDebuggerID, STACK_INFO stackInfoKind)
void SetBreakRequestedByThread(bool Enabled)
const String & string() const
int mg_get_var(const char *buf, size_t buf_len, const char *name, char *dst, size_t dst_len)
void EnumVfsJSFiles(std::stringstream &response)
Returns a list of the full vfs paths to all files with the extension .js found in the vfs root...
i64 Status
Error handling system.
bool m_SettingSimultaneousThreadBreak
Shared between multiple mongoose threads.
static void * MgDebuggingServerCallback_(mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info)
SDL_sem * SDL_CreateSemaphore(int cnt)
int mg_printf(struct mg_connection *conn, const char *fmt,...)
double AquireBreakPointAccess(std::list< CBreakPoint > **breakPoints)
Aquire exclusive read and write access to the list of breakpoints.
int mg_write(struct mg_connection *conn, const void *buf, size_t len)
bool m_BreakRequestedByThread
Status ForEachFile(const PIVFS &fs, const VfsPath &startPath, FileCallback cb, uintptr_t cbData, const wchar_t *pattern, size_t flags)
call back for each file in a directory tree
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
bool m_BreakRequestedByUser
bool GetSettingSimultaneousThreadBreak()
std::vector< VfsPath > VfsPaths
Abstraction around a SpiderMonkey JSContext.
#define debug_warn(expr)
display the error dialog with the given text.
void ToggleBreakPoint(std::string filename, uint line)
struct mg_context * mg_start(mg_callback_t user_callback, void *user_data, const char **options)
int SDL_SemPost(SDL_sem *sem)
void GetAllCallstacks(std::stringstream &response)
void SetSettingBreakOnException(bool Enabled)
int SDL_SemWait(SDL_sem *sem)
void SetBreakRequestedByUser(bool Enabled)
void mg_stop(struct mg_context *ctx)
void UnRegisterScriptinterface(ScriptInterface *pScriptInterface)
Unregister a ScriptInerface that was previously registered using RegisterScriptinterface.
void GetFile(std::string filename, std::stringstream &response)
Get the content of a .js file loaded into vfs.
bool GetBreakRequestedByThread()
Called from multiple Mongoose threads and multiple ScriptInterface threads.
void SetSettingSimultaneousThreadBreak(bool Enabled)