00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wx/wxprec.h"
00011
00012 #ifdef __BORLANDC__
00013 #pragma hdrstop
00014 #endif
00015
00016 #ifndef WX_PRECOMP
00017 #include "wx/wx.h"
00018 #endif
00019
00020 #include "wx/thread.h"
00021 #include "wxluasocket/include/wxldserv.h"
00022 #include "wxluadebug/include/wxlstack.h"
00023
00024 #if !wxCHECK_VERSION(2, 6, 0)
00025 #define wxMilliSleep wxUsleep
00026 #endif // !wxCHECK_VERSION(2, 6, 0)
00027
00028
00029
00030
00031
00032 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_CONNECTED)
00033 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_DISCONNECTED)
00034 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_BREAK)
00035 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_PRINT)
00036 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_ERROR)
00037 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_EXIT)
00038 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_STACK_ENUM)
00039 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_STACK_ENTRY_ENUM)
00040 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_TABLE_ENUM)
00041 DEFINE_EVENT_TYPE(wxEVT_WXLUA_DEBUGGER_EVALUATE_EXPR)
00042
00043
00044
00045 IMPLEMENT_DYNAMIC_CLASS(wxLuaDebuggerEvent, wxEvent)
00046
00047 wxLuaDebuggerEvent::wxLuaDebuggerEvent(const wxLuaDebuggerEvent& event)
00048 :wxEvent(event),
00049 m_line_number(event.m_line_number),
00050 m_fileName(event.m_fileName),
00051 m_strMessage(event.m_strMessage),
00052 m_has_message(event.m_has_message),
00053 m_lua_ref(event.m_lua_ref),
00054 m_debugData(wxNullLuaDebugData),
00055 m_enabled_flag(event.m_enabled_flag)
00056 {
00057 SetDebugData(event.GetReference(), event.GetDebugData());
00058 }
00059
00060 wxLuaDebuggerEvent::wxLuaDebuggerEvent(wxEventType eventType,
00061 wxObject* eventObject,
00062 int line_number,
00063 const wxString &file, bool enabled_flag)
00064 :wxEvent(0, eventType),
00065 m_line_number(line_number),
00066 m_fileName(file),
00067 m_has_message(false),
00068 m_lua_ref(-1),
00069 m_debugData(wxNullLuaDebugData),
00070 m_enabled_flag(enabled_flag)
00071 {
00072 SetEventObject(eventObject);
00073 }
00074
00075 void wxLuaDebuggerEvent::SetMessage(const wxString& message)
00076 {
00077 m_strMessage = message;
00078 m_has_message = true;
00079 }
00080
00081 void wxLuaDebuggerEvent::SetDebugData(long nReference, const wxLuaDebugData& debugData)
00082 {
00083 m_lua_ref = nReference;
00084 m_debugData = debugData;
00085 }
00086
00087
00088
00089
00090 IMPLEMENT_ABSTRACT_CLASS(wxLuaDebuggerStackDialog, wxLuaStackDialog)
00091
00092 wxLuaDebuggerStackDialog::wxLuaDebuggerStackDialog(wxLuaDebuggerBase* luaDebugger,
00093 wxWindow* parent, wxWindowID id,
00094 const wxString& title,
00095 const wxPoint& pos, const wxSize& size)
00096 : m_luaDebugger(luaDebugger)
00097 {
00098 wxCHECK_RET(m_luaDebugger != NULL, wxT("Invalid wxLuaDebuggerBase in wxLuaDebuggerStackDialog"));
00099
00100 Create(wxNullLuaState, parent, id, title, pos, size);
00101 }
00102
00103 wxLuaDebuggerStackDialog::~wxLuaDebuggerStackDialog()
00104 {
00105 if (m_luaDebugger != NULL)
00106 m_luaDebugger->ClearDebugReferences();
00107 }
00108
00109 void wxLuaDebuggerStackDialog::EnumerateStack()
00110 {
00111 wxCHECK_RET(m_luaDebugger, wxT("Invalid wxLuaDebuggerServer"));
00112 wxBeginBusyCursor();
00113 m_luaDebugger->EnumerateStack();
00114 }
00115
00116 void wxLuaDebuggerStackDialog::EnumerateStackEntry(int nEntry)
00117 {
00118 wxCHECK_RET(m_luaDebugger, wxT("Invalid wxLuaDebuggerServer"));
00119 wxBeginBusyCursor();
00120 m_luaDebugger->EnumerateStackEntry(nEntry);
00121 }
00122
00123 void wxLuaDebuggerStackDialog::EnumerateTable(int nRef, int nEntry, long lc_item)
00124 {
00125 wxCHECK_RET(m_luaDebugger, wxT("Invalid wxLuaDebuggerServer"));
00126 wxBeginBusyCursor();
00127 m_luaDebugger->EnumerateTable(nRef, nEntry, lc_item);
00128 }
00129
00130 void wxLuaDebuggerStackDialog::EnumerateGlobalData(long lc_item)
00131 {
00132 wxCHECK_RET(m_luaDebugger, wxT("Invalid wxLuaDebuggerServer"));
00133 wxBeginBusyCursor();
00134 m_luaDebugger->EnumerateTable(-1, -1, lc_item);
00135 }
00136
00137
00138
00139
00140
00141 void wxLuaDebuggerProcess::OnTerminate(int pid, int status)
00142 {
00143
00144
00145 if (m_debugger && m_debugger->m_debuggeeProcess)
00146 {
00147
00148 wxProcessEvent event(m_id, pid, status);
00149 m_debugger->OnEndDebugeeProcess(event);
00150
00151 m_debugger->m_debuggeeProcess = NULL;
00152 m_debugger->m_debuggeeProcessID = -1;
00153 }
00154
00155 delete this;
00156 }
00157
00158
00159
00160
00161
00162 IMPLEMENT_ABSTRACT_CLASS(wxLuaDebuggerBase, wxEvtHandler)
00163
00164 wxString wxLuaDebuggerBase::sm_programName;
00165 wxString wxLuaDebuggerBase::sm_networkName;
00166
00167 BEGIN_EVENT_TABLE(wxLuaDebuggerBase, wxEvtHandler)
00168 EVT_WXLUA_DEBUGGER_STACK_ENUM( wxID_ANY, wxLuaDebuggerBase::OnDebugStackEnum)
00169 EVT_WXLUA_DEBUGGER_STACK_ENTRY_ENUM( wxID_ANY, wxLuaDebuggerBase::OnDebugStackEntryEnum)
00170 EVT_WXLUA_DEBUGGER_TABLE_ENUM( wxID_ANY, wxLuaDebuggerBase::OnDebugTableEnum)
00171
00172
00173 END_EVENT_TABLE()
00174
00175 wxLuaDebuggerBase::wxLuaDebuggerBase(int port_number)
00176 :wxEvtHandler(), m_port_number(port_number),
00177 m_stackDialog(NULL),
00178 m_debuggeeProcess(NULL), m_debuggeeProcessID(-1)
00179 {
00180
00181 if (sm_programName.IsEmpty())
00182 sm_programName = wxTheApp->argv[0];
00183
00184
00185 if (sm_networkName.IsEmpty())
00186 {
00187 #ifdef __WXMSW__
00188 sm_networkName = wxGetHostName();
00189 #else
00190 sm_networkName = wxT("localhost");
00191 #endif // __WXMSW__
00192 }
00193 }
00194
00195 wxLuaDebuggerBase::~wxLuaDebuggerBase()
00196 {
00197
00198
00199
00200 if ((m_debuggeeProcess != NULL) && (m_debuggeeProcessID > 0) &&
00201 wxProcess::Exists(m_debuggeeProcessID))
00202 {
00203 m_debuggeeProcess->m_debugger = NULL;
00204 m_debuggeeProcess = NULL;
00205 wxProcess::Kill(m_debuggeeProcessID, wxSIGKILL, wxKILL_CHILDREN);
00206 }
00207 }
00208
00209 long wxLuaDebuggerBase::StartClient()
00210 {
00211 if (m_debuggeeProcess == NULL)
00212 {
00213 m_debuggeeProcess = new wxLuaDebuggerProcess(this, ID_WXLUASOCKET_DEBUGGEE_PROCESS);
00214 wxString command = wxString::Format(wxT("%s -d%s:%u"),
00215 GetProgramName().c_str(),
00216 GetNetworkName().c_str(),
00217 m_port_number);
00218
00219 m_debuggeeProcessID = wxExecute(command, wxEXEC_ASYNC|wxEXEC_MAKE_GROUP_LEADER, m_debuggeeProcess);
00220
00221 if (m_debuggeeProcessID < 1)
00222 KillDebuggee();
00223 }
00224
00225 return m_debuggeeProcessID;
00226 }
00227
00228 bool wxLuaDebuggerBase::AddBreakPoint(const wxString &fileName, int lineNumber)
00229 {
00230 return CheckSocketConnected(true, wxT("Debugger AddBreakPoint")) && CheckSocketWrite(
00231 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_ADD_BREAKPOINT) &&
00232 GetSocketBase()->WriteString(fileName) &&
00233 GetSocketBase()->WriteInt32(lineNumber),
00234 wxT("Debugger AddBreakPoint"));
00235 }
00236
00237 bool wxLuaDebuggerBase::RemoveBreakPoint(const wxString &fileName, int lineNumber)
00238 {
00239 return CheckSocketConnected(true, wxT("Debugger RemoveBreakPoint")) && CheckSocketWrite(
00240 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_REMOVE_BREAKPOINT) &&
00241 GetSocketBase()->WriteString(fileName) &&
00242 GetSocketBase()->WriteInt32(lineNumber),
00243 wxT("Debugger RemoveBreakPoint"));
00244 }
00245
00246 bool wxLuaDebuggerBase::DisableBreakPoint(const wxString &fileName, int lineNumber)
00247 {
00248 return CheckSocketConnected(true, wxT("Debugger DisableBreakPoint")) && CheckSocketWrite(
00249 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_DISABLE_BREAKPOINT) &&
00250 GetSocketBase()->WriteString(fileName) &&
00251 GetSocketBase()->WriteInt32(lineNumber),
00252 wxT("Debugger DisableBreakPoint"));
00253 }
00254
00255 bool wxLuaDebuggerBase::EnableBreakPoint(const wxString &fileName, int lineNumber)
00256 {
00257 return CheckSocketConnected(true, wxT("Debugger EnableBreakPoint")) && CheckSocketWrite(
00258 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_ENABLE_BREAKPOINT) &&
00259 GetSocketBase()->WriteString(fileName) &&
00260 GetSocketBase()->WriteInt32(lineNumber),
00261 wxT("Debugger EnableBreakPoint"));
00262 }
00263
00264 bool wxLuaDebuggerBase::ClearAllBreakPoints()
00265 {
00266 return CheckSocketConnected(true, wxT("Debugger ClearAllBreakPoints")) && CheckSocketWrite(
00267 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_CLEAR_ALL_BREAKPOINTS),
00268 wxT("Debugger ClearAllBreakPoints"));
00269 }
00270
00271 bool wxLuaDebuggerBase::Run(const wxString &fileName, const wxString &buffer)
00272 {
00273 return CheckSocketConnected(true, wxT("Debugger Run")) && CheckSocketWrite(
00274 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_RUN_BUFFER) &&
00275 GetSocketBase()->WriteString(fileName) &&
00276 GetSocketBase()->WriteString(buffer),
00277 wxT("Debugger Run"));
00278 }
00279
00280 bool wxLuaDebuggerBase::Step()
00281 {
00282 return CheckSocketConnected(true, wxT("Debugger Step")) && CheckSocketWrite(
00283 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_DEBUG_STEP),
00284 wxT("Debugger Step"));
00285 }
00286
00287 bool wxLuaDebuggerBase::StepOver()
00288 {
00289 return CheckSocketConnected(true, wxT("Debugger StepOver")) && CheckSocketWrite(
00290 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_DEBUG_STEPOVER),
00291 wxT("Debugger StepOver"));
00292 }
00293
00294 bool wxLuaDebuggerBase::StepOut()
00295 {
00296 return CheckSocketConnected(true, wxT("Debugger StepOut")) && CheckSocketWrite(
00297 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_DEBUG_STEPOUT),
00298 wxT("Debugger StepOut"));
00299 }
00300
00301 bool wxLuaDebuggerBase::Continue()
00302 {
00303 return CheckSocketConnected(true, wxT("Debugger Continue")) && CheckSocketWrite(
00304 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_DEBUG_CONTINUE),
00305 wxT("Debugger Continue"));
00306 }
00307
00308 bool wxLuaDebuggerBase::Break()
00309 {
00310 return CheckSocketConnected(true, wxT("Debugger Break")) && CheckSocketWrite(
00311 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_DEBUG_BREAK),
00312 wxT("Debugger Break"));
00313 }
00314
00315 bool wxLuaDebuggerBase::Reset()
00316 {
00317 return CheckSocketConnected(true, wxT("Debugger Reset")) && CheckSocketWrite(
00318 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_RESET),
00319 wxT("Debugger Reset"));
00320 }
00321
00322 bool wxLuaDebuggerBase::EnumerateStack()
00323 {
00324 return CheckSocketConnected(true, wxT("Debugger EnumerateStack")) && CheckSocketWrite(
00325 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_ENUMERATE_STACK),
00326 wxT("Debugger EnumerateStack"));
00327 }
00328
00329 bool wxLuaDebuggerBase::EnumerateStackEntry(int stackEntry)
00330 {
00331 return CheckSocketConnected(true, wxT("Debugger EnumerateStackEntry")) && CheckSocketWrite(
00332 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_ENUMERATE_STACK_ENTRY) &&
00333 GetSocketBase()->WriteInt32(stackEntry),
00334 wxT("Debugger EnumerateStackEntry"));
00335 }
00336
00337 bool wxLuaDebuggerBase::EnumerateTable(int tableRef, int nIndex, long nItemNode)
00338 {
00339 return CheckSocketConnected(true, wxT("Debugger EnumerateTable")) && CheckSocketWrite(
00340 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_ENUMERATE_TABLE_REF) &&
00341 GetSocketBase()->WriteInt32(tableRef) &&
00342 GetSocketBase()->WriteInt32(nIndex) &&
00343 GetSocketBase()->WriteLong(nItemNode),
00344 wxT("Debugger EnumerateTable"));
00345 }
00346
00347 bool wxLuaDebuggerBase::ClearDebugReferences()
00348 {
00349 return CheckSocketConnected(true, wxT("Debugger ClearDebugReferences")) && CheckSocketWrite(
00350 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_CLEAR_DEBUG_REFERENCES),
00351 wxT("Debugger ClearDebugReferences"));
00352 }
00353
00354 bool wxLuaDebuggerBase::EvaluateExpr(int exprRef, const wxString &strExpression)
00355 {
00356 return CheckSocketConnected(true, wxT("Debugger EvaluateExpr")) && CheckSocketWrite(
00357 GetSocketBase()->WriteCmd(wxLUASOCKET_DEBUGGER_CMD_EVALUATE_EXPR) &&
00358 GetSocketBase()->WriteInt32(exprRef) &&
00359 GetSocketBase()->WriteString(strExpression),
00360 wxT("Debugger EvaluateExpr"));
00361 }
00362
00363
00364
00365
00366
00367 int wxLuaDebuggerBase::HandleDebuggeeEvent(int event_type)
00368 {
00369 wxCHECK_MSG(GetSocketBase(), event_type, wxT("Invalid socket"));
00370
00371
00372
00373
00374
00375 switch (event_type)
00376 {
00377 case wxLUASOCKET_DEBUGGEE_EVENT_BREAK:
00378 {
00379 wxString fileName;
00380 wxInt32 lineNumber = 0;
00381
00382 if (CheckSocketRead(
00383 GetSocketBase()->ReadString(fileName) &&
00384 GetSocketBase()->ReadInt32(lineNumber),
00385 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_BREAK")))
00386 {
00387 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_BREAK, this, lineNumber, fileName);
00388 SendEvent(debugEvent);
00389 }
00390 else return -1;
00391
00392 break;
00393 }
00394 case wxLUASOCKET_DEBUGGEE_EVENT_PRINT:
00395 {
00396 wxString strMessage;
00397
00398 if (CheckSocketRead(
00399 GetSocketBase()->ReadString(strMessage),
00400 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_PRINT")))
00401 {
00402 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_PRINT, this);
00403 debugEvent.SetMessage(strMessage);
00404 SendEvent(debugEvent);
00405 }
00406 else return -1;
00407
00408 break;
00409 }
00410 case wxLUASOCKET_DEBUGGEE_EVENT_ERROR:
00411 {
00412 wxString strMessage;
00413
00414 if (CheckSocketRead(
00415 GetSocketBase()->ReadString(strMessage),
00416 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_ERROR")))
00417 {
00418 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_ERROR, this);
00419 debugEvent.SetMessage(strMessage);
00420 SendEvent(debugEvent);
00421 }
00422 else return -1;
00423
00424 break;
00425 }
00426 case wxLUASOCKET_DEBUGGEE_EVENT_EXIT:
00427 {
00428 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_EXIT, this);
00429 wxPostEvent(this, debugEvent);
00430 break;
00431 }
00432 case wxLUASOCKET_DEBUGGEE_EVENT_STACK_ENUM:
00433 {
00434 wxLuaDebugData debugData(true);
00435
00436 if (CheckSocketRead(
00437 GetSocketBase()->ReadDebugData(debugData),
00438 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_STACK_ENUM")))
00439 {
00440 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_STACK_ENUM, this);
00441 debugEvent.SetDebugData(-1, debugData);
00442 SendEvent(debugEvent);
00443 }
00444 else return -1;
00445
00446 break;
00447 }
00448 case wxLUASOCKET_DEBUGGEE_EVENT_STACK_ENTRY_ENUM:
00449 {
00450 wxInt32 stackRef = 0;
00451 wxLuaDebugData debugData(true);
00452
00453 if (CheckSocketRead(
00454 GetSocketBase()->ReadInt32(stackRef) &&
00455 GetSocketBase()->ReadDebugData(debugData),
00456 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_STACK_ENTRY_ENUM")))
00457 {
00458 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_STACK_ENTRY_ENUM, this);
00459 debugEvent.SetDebugData(stackRef, debugData);
00460 SendEvent(debugEvent);
00461 }
00462 else return -1;
00463
00464 break;
00465 }
00466 case wxLUASOCKET_DEBUGGEE_EVENT_TABLE_ENUM:
00467 {
00468 long itemNode = 0;
00469 wxLuaDebugData debugData(true);
00470
00471 if (CheckSocketRead(
00472 GetSocketBase()->ReadLong(itemNode) &&
00473 GetSocketBase()->ReadDebugData(debugData),
00474 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_TABLE_ENUM")))
00475 {
00476 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_TABLE_ENUM, this);
00477 debugEvent.SetDebugData(itemNode, debugData);
00478 SendEvent(debugEvent);
00479 }
00480 else return -1;
00481
00482 break;
00483 }
00484 case wxLUASOCKET_DEBUGGEE_EVENT_EVALUATE_EXPR:
00485 {
00486 wxInt32 exprRef = 0;
00487 wxString strResult;
00488
00489 if (CheckSocketRead(
00490 GetSocketBase()->ReadInt32(exprRef) &&
00491 GetSocketBase()->ReadString(strResult),
00492 wxT("Debugger wxLUASOCKET_DEBUGGEE_EVENT_EVALUATE_EXPR")))
00493 {
00494 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_EVALUATE_EXPR, this);
00495 debugEvent.SetMessage(strResult);
00496 debugEvent.SetDebugData(exprRef);
00497 SendEvent(debugEvent);
00498 }
00499 else return -1;
00500
00501 break;
00502 }
00503 default : return -1;
00504 }
00505
00506 return event_type;
00507 }
00508
00509
00510 bool wxLuaDebuggerBase::CheckSocketConnected(bool send_event, const wxString& msg)
00511 {
00512 if (GetSocketBase() == NULL)
00513 {
00514 if (send_event)
00515 {
00516 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_DISCONNECTED, this);
00517 debugEvent.SetMessage(wxT("Debugger socket not created. ") + msg);
00518 SendEvent(debugEvent);
00519 }
00520
00521 return false;
00522 }
00523 else if (!GetSocketBase()->IsConnected())
00524 {
00525 if (send_event)
00526 {
00527 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_DISCONNECTED, this);
00528 debugEvent.SetMessage(wxT("Debugger socket not connected. ") + msg);
00529 SendEvent(debugEvent);
00530 }
00531
00532 return false;
00533 }
00534
00535 return true;
00536 }
00537 bool wxLuaDebuggerBase::CheckSocketRead(bool read_ok, const wxString& msg)
00538 {
00539 if (!read_ok)
00540 {
00541 wxString s = wxT("Failed reading from the debugger socket. ") + msg + wxT("\n");
00542 s += GetSocketErrorMsg();
00543
00544 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_DISCONNECTED, this);
00545 debugEvent.SetMessage(s);
00546 SendEvent(debugEvent);
00547 }
00548
00549 return read_ok;
00550 }
00551 bool wxLuaDebuggerBase::CheckSocketWrite(bool write_ok, const wxString& msg)
00552 {
00553 if (!write_ok)
00554 {
00555 wxString s = wxT("Failed writing to the debugger socket. ") + msg + wxT("\n");
00556 s += GetSocketErrorMsg();
00557
00558 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_DISCONNECTED, this);
00559 debugEvent.SetMessage(s);
00560 SendEvent(debugEvent);
00561 }
00562
00563 return write_ok;
00564 }
00565
00566 bool wxLuaDebuggerBase::DisplayStackDialog(wxWindow *parent, wxWindowID winid)
00567 {
00568 wxCHECK_MSG(m_stackDialog == NULL, false, wxT("Stack dialog already shown"));
00569
00570 m_stackDialog = new wxLuaDebuggerStackDialog(this, parent, winid);
00571 m_stackDialog->ShowModal();
00572 m_stackDialog->Destroy();
00573 m_stackDialog = NULL;
00574 return true;
00575 }
00576
00577 void wxLuaDebuggerBase::OnDebugStackEnum(wxLuaDebuggerEvent &event)
00578 {
00579 if (GetStackDialog() != NULL)
00580 GetStackDialog()->FillStackCombobox(event.GetDebugData());
00581 else
00582 event.Skip();
00583
00584 wxEndBusyCursor();
00585 }
00586 void wxLuaDebuggerBase::OnDebugStackEntryEnum(wxLuaDebuggerEvent &event)
00587 {
00588 if (GetStackDialog() != NULL)
00589 GetStackDialog()->FillStackEntry(event.GetReference(), event.GetDebugData());
00590 else
00591 event.Skip();
00592
00593 wxEndBusyCursor();
00594 }
00595 void wxLuaDebuggerBase::OnDebugTableEnum(wxLuaDebuggerEvent &event)
00596 {
00597 if (GetStackDialog() != NULL)
00598 GetStackDialog()->FillTableEntry(event.GetReference(), event.GetDebugData());
00599 else
00600 event.Skip();
00601
00602 wxEndBusyCursor();
00603 }
00604
00605 void wxLuaDebuggerBase::OnEndDebugeeProcess(wxProcessEvent& event)
00606 {
00607
00608
00609
00610
00611 if (m_debuggeeProcess != NULL)
00612 {
00613 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_EXIT, this);
00614 debugEvent.SetMessage(wxString::Format(wxT("Process (%d) ended with exit code : %d"), event.GetPid(), event.GetExitCode()));
00615 wxPostEvent(this, debugEvent);
00616 }
00617
00618 event.Skip();
00619 }
00620
00621 bool wxLuaDebuggerBase::KillDebuggee()
00622 {
00623
00624
00625 if ((m_debuggeeProcess != NULL) && (m_debuggeeProcessID > 0))
00626 {
00627 m_debuggeeProcess->m_debugger = NULL;
00628 m_debuggeeProcess = NULL;
00629
00630
00631 wxProcess::Kill(m_debuggeeProcessID, wxSIGKILL, wxKILL_CHILDREN);
00632 }
00633 else if (m_debuggeeProcess != NULL)
00634 {
00635 wxLuaDebuggerProcess* p = m_debuggeeProcess;
00636 m_debuggeeProcess->m_debugger = NULL;
00637 m_debuggeeProcess = NULL;
00638 delete p;
00639 }
00640
00641 m_debuggeeProcessID = -1;
00642
00643 return true;
00644 }
00645
00646 #ifdef WXLUASOCKET_USE_C_SOCKET
00647
00648
00649
00650
00651
00652 void *wxLuaDebuggerCServer::LuaThread::Entry()
00653 {
00654 m_pServer->ThreadFunction();
00655 return 0;
00656 }
00657
00658 void wxLuaDebuggerCServer::LuaThread::OnExit()
00659 {
00660 wxThread::OnExit();
00661
00662 }
00663
00664
00665
00666
00667 IMPLEMENT_ABSTRACT_CLASS(wxLuaDebuggerCServer, wxLuaDebuggerBase)
00668
00669 wxLuaDebuggerCServer::wxLuaDebuggerCServer(int port_number)
00670 :wxLuaDebuggerBase(port_number),
00671 m_serverSocket(NULL), m_acceptedSocket(NULL),
00672 m_pThread(NULL),
00673 m_shutdown(false)
00674 {
00675 }
00676
00677 wxLuaDebuggerCServer::~wxLuaDebuggerCServer()
00678 {
00679 StopServer();
00680 }
00681
00682 bool wxLuaDebuggerCServer::StartServer()
00683 {
00684 wxCHECK_MSG(m_serverSocket == NULL, false, wxT("Debugger server socket already created"));
00685
00686 m_shutdown = false;
00687 m_serverSocket = new wxLuaCSocket();
00688 m_serverSocket->m_name = wxString::Format(wxT("wxLuaDebuggerCServer::m_serverSocket (%ld)"), (long)wxGetProcessId());
00689
00690 if (m_serverSocket->Listen(m_port_number))
00691 {
00692 wxCHECK_MSG(m_pThread == NULL, false, wxT("Debugger server thread already created"));
00693
00694 if (!m_shutdown)
00695 {
00696 m_pThread = new wxLuaDebuggerCServer::LuaThread(this);
00697
00698 return ((m_pThread != NULL) &&
00699 (m_pThread->Create() == wxTHREAD_NO_ERROR) &&
00700 (m_pThread->Run() == wxTHREAD_NO_ERROR));
00701 }
00702 }
00703 else
00704 {
00705 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_ERROR, this);
00706 debugEvent.SetMessage(m_serverSocket->GetErrorMsg(true));
00707 AddPendingEvent(debugEvent);
00708
00709 delete m_serverSocket;
00710 m_serverSocket = NULL;
00711 m_shutdown = true;
00712 }
00713
00714 return false;
00715 }
00716
00717 long wxLuaDebuggerCServer::StartClient()
00718 {
00719 wxCHECK_MSG(m_serverSocket, false, wxT("Debugger server not started"));
00720 wxCHECK_MSG(m_pThread, false, wxT("Debugger server thread not running"));
00721
00722 if (!m_shutdown)
00723 return wxLuaDebuggerBase::StartClient();
00724
00725 return m_debuggeeProcessID;
00726 }
00727
00728 bool wxLuaDebuggerCServer::StopServer()
00729 {
00730
00731
00732
00733 m_shutdown = true;
00734
00735
00736 if (m_acceptedSocket)
00737 {
00738 Reset();
00739 wxMilliSleep(500);
00740 }
00741
00742
00743
00744 wxLuaSocket *acceptedSocket = m_acceptedSocket;
00745
00746
00747
00748 if (acceptedSocket != NULL)
00749 {
00750 if (!acceptedSocket->Shutdown(SD_BOTH))
00751 {
00752 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_ERROR, this);
00753 debugEvent.SetMessage(acceptedSocket->GetErrorMsg(true));
00754 AddPendingEvent(debugEvent);
00755 }
00756
00757 wxMilliSleep(500);
00758
00759
00760 }
00761
00762
00763
00764 if (m_serverSocket != NULL)
00765 {
00766 wxLuaSocket *serverSocket = m_serverSocket;
00767 m_serverSocket = NULL;
00768
00769
00770
00771
00772
00773
00774 wxLuaSocket closeSocket;
00775 closeSocket.m_name = wxString::Format(wxT("wxLuaDebuggerCServer closeSocket (%ld)"), (long)wxGetProcessId());
00776
00777 if (!closeSocket.Connect(GetNetworkName(), m_port_number) ||
00778 !closeSocket.Shutdown(SD_BOTH))
00779 {
00780 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_ERROR, this);
00781 debugEvent.SetMessage(serverSocket->GetErrorMsg(true));
00782 AddPendingEvent(debugEvent);
00783 }
00784
00785 wxMilliSleep(100);
00786
00787 delete serverSocket;
00788 }
00789
00790
00791 if ((m_pThread != NULL) && m_pThread->IsRunning())
00792 m_pThread->Wait();
00793
00794 delete m_pThread;
00795 m_pThread = NULL;
00796
00797 return true;
00798 }
00799
00800 void wxLuaDebuggerCServer::ThreadFunction()
00801 {
00802 wxCHECK_RET(m_serverSocket, wxT("Invalid server socket"));
00803 wxCHECK_RET(m_acceptedSocket == NULL, wxT("The debugger server has already accepted a socket connection"));
00804
00805 m_acceptedSocket = m_serverSocket->Accept();
00806 if (!m_acceptedSocket)
00807 {
00808 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_ERROR, this);
00809 debugEvent.SetMessage(m_serverSocket->GetErrorMsg(true));
00810 AddPendingEvent(debugEvent);
00811 }
00812 else
00813 {
00814 m_acceptedSocket->m_name = wxString::Format(wxT("wxLuaDebuggerCServer::m_acceptedSocket (%ld)"), (long)wxGetProcessId());
00815
00816 wxLuaSocket *serverSocket = m_serverSocket;
00817 m_serverSocket = NULL;
00818 delete serverSocket;
00819
00820 wxThread::Sleep(500);
00821
00822
00823 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_CONNECTED, this);
00824 AddPendingEvent(debugEvent);
00825
00826 unsigned char debug_event = 0;
00827
00828
00829 while (!m_pThread->TestDestroy() && !m_shutdown && m_acceptedSocket)
00830 {
00831 debug_event = wxLUASOCKET_DEBUGGEE_EVENT_EXIT;
00832
00833 {
00834
00835 wxCriticalSectionLocker locker(m_acceptSockCritSect);
00836 if (m_shutdown || (m_acceptedSocket == NULL) || !m_acceptedSocket->ReadCmd(debug_event))
00837 {
00838 m_shutdown = true;
00839 break;
00840 }
00841 }
00842
00843 if((debug_event == wxLUASOCKET_DEBUGGEE_EVENT_EXIT) ||
00844 (HandleDebuggeeEvent(debug_event) != -1))
00845 {
00846
00847 if (debug_event == wxLUASOCKET_DEBUGGEE_EVENT_EXIT)
00848 {
00849 m_shutdown = true;
00850 break;
00851 }
00852 }
00853 }
00854
00855 wxCriticalSectionLocker locker(m_acceptSockCritSect);
00856
00857 if (m_acceptedSocket != NULL)
00858 {
00859 wxLuaSocket *acceptedSocket = m_acceptedSocket;
00860 m_acceptedSocket = NULL;
00861 delete acceptedSocket;
00862 }
00863 }
00864
00865
00866
00867 {
00868 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_EXIT, this);
00869 wxPostEvent(this, debugEvent);
00870 }
00871 }
00872
00873 wxString wxLuaDebuggerCServer::GetSocketErrorMsg()
00874 {
00875 wxString s;
00876
00877 if (m_serverSocket)
00878 s += m_serverSocket->GetErrorMsg(true);
00879 if (m_acceptedSocket)
00880 s += m_acceptedSocket->GetErrorMsg(true);
00881
00882 return s;
00883 }
00884
00885 #else // !WXLUASOCKET_USE_C_SOCKET
00886
00887
00888
00889
00890 IMPLEMENT_ABSTRACT_CLASS(wxLuaDebuggerwxSocketServer, wxLuaDebuggerBase)
00891
00892 BEGIN_EVENT_TABLE(wxLuaDebuggerwxSocketServer, wxLuaDebuggerBase)
00893 EVT_SOCKET(ID_WXLUA_SERVER, wxLuaDebuggerwxSocketServer::OnServerEvent)
00894 EVT_SOCKET(ID_WXLUA_SOCKET, wxLuaDebuggerwxSocketServer::OnSocketEvent)
00895 END_EVENT_TABLE()
00896
00897
00898 wxLuaDebuggerwxSocketServer::wxLuaDebuggerwxSocketServer(int port_number)
00899 :wxLuaDebuggerBase(port_number),
00900 m_serverSocket(NULL), m_acceptedSocket(NULL)
00901 {
00902 }
00903
00904 wxLuaDebuggerwxSocketServer::~wxLuaDebuggerwxSocketServer()
00905 {
00906 StopServer();
00907 }
00908
00909
00910 bool wxLuaDebuggerwxSocketServer::StartServer()
00911 {
00912 if (!m_serverSocket)
00913 {
00914
00915 wxIPV4address addr;
00916 addr.Service(m_port_number);
00917
00918
00919 m_serverSocket = new wxSocketServer(addr, wxSOCKET_NOWAIT|wxSOCKET_BLOCK);
00920 m_serverSocket->SetEventHandler(*this, ID_WXLUA_SERVER);
00921 m_serverSocket->SetNotify(wxSOCKET_CONNECTION_FLAG);
00922 m_serverSocket->SetFlags(wxSOCKET_BLOCK);
00923 m_serverSocket->Notify(true);
00924 }
00925
00926 return m_serverSocket->Ok();
00927 }
00928
00929 bool wxLuaDebuggerwxSocketServer::StopServer()
00930 {
00931 if (m_acceptedSocket)
00932 {
00933 m_acceptedSocket->GetSocket()->Notify(false);
00934 m_acceptedSocket->Destroy();
00935 delete m_acceptedSocket;
00936 m_acceptedSocket = NULL;
00937 }
00938
00939 if (m_serverSocket)
00940 {
00941 m_serverSocket->Notify(false);
00942 m_serverSocket->Destroy();
00943 m_serverSocket = NULL;
00944 }
00945
00946 return true;
00947 }
00948
00949 long wxLuaDebuggerwxSocketServer::StartClient()
00950 {
00951 return wxLuaDebuggerBase::StartClient();
00952 }
00953
00954 wxString wxLuaDebuggerwxSocketServer::GetSocketErrorMsg()
00955 {
00956 wxString s;
00957 if (m_acceptedSocket)
00958 s += m_acceptedSocket->GetErrorMsg(true);
00959
00960 return s;
00961 }
00962
00963 void wxLuaDebuggerwxSocketServer::OnServerEvent(wxSocketEvent& event)
00964 {
00965 switch(event.GetSocketEvent())
00966 {
00967 case wxSOCKET_CONNECTION:
00968 {
00969 wxSocketBase *sock = m_serverSocket->Accept(false);
00970 if (!sock)
00971 {
00972
00973 return;
00974 }
00975
00976 sock->SetFlags(wxSOCKET_NOWAIT);
00977 m_acceptedSocket = new wxLuawxSocket(sock);
00978 m_acceptedSocket->m_port_number = m_port_number;
00979 m_acceptedSocket->m_name = wxString::Format(wxT("wxLuaDebuggerwxSocketServer::m_acceptedSocket (%ld)"), (long)wxGetProcessId());
00980
00981
00982 sock->SetEventHandler(*this, ID_WXLUA_SOCKET);
00983 sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
00984 sock->Notify(true);
00985
00986 wxMilliSleep(500);
00987
00988
00989 wxLuaDebuggerEvent debugEvent(wxEVT_WXLUA_DEBUGGER_DEBUGGEE_CONNECTED, this);
00990 AddPendingEvent(debugEvent);
00991
00992 break;
00993 }
00994
00995 default:
00996
00997 break;
00998 }
00999 }
01000
01001
01002 void wxLuaDebuggerwxSocketServer::OnSocketEvent(wxSocketEvent& event)
01003 {
01004 wxSocketBase *sock = event.GetSocket();
01005
01006
01007 switch(event.GetSocketEvent())
01008 {
01009 case wxSOCKET_INPUT:
01010 {
01011
01012
01013 sock->SetNotify(wxSOCKET_LOST_FLAG);
01014
01015 unsigned char debugEvent = 0;
01016 if (m_acceptedSocket->ReadCmd(debugEvent))
01017 HandleDebuggeeEvent(debugEvent);
01018
01019
01020 sock->SetNotify(wxSOCKET_LOST_FLAG | wxSOCKET_INPUT_FLAG);
01021 break;
01022 }
01023 case wxSOCKET_LOST:
01024 {
01025 m_acceptedSocket->Destroy();
01026 delete m_acceptedSocket;
01027 m_acceptedSocket = NULL;
01028 break;
01029 }
01030 default:
01031
01032 break;
01033 }
01034 }
01035
01036 #endif // WXLUASOCKET_USE_C_SOCKET