zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #03659
[Merge] lp:~zorba-coders/zorba/debugger_ctrl_c into lp:zorba
Gabriel Petrovay has proposed merging lp:~zorba-coders/zorba/debugger_ctrl_c into lp:zorba.
Requested reviews:
Gabriel Petrovay (gabipetrovay)
David Graf (davidagraf)
Related bugs:
Bug #913822 in Zorba: "Debugger: Interrupt execution with Ctrl-C and stop at next breakpoint"
https://bugs.launchpad.net/zorba/+bug/913822
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/debugger_ctrl_c/+merge/88918
Added Ctrl-C hooking in the debugger. Ctrl-C can not kill the debugger anymore. It will only stop the running query.
--
https://code.launchpad.net/~zorba-coders/zorba/debugger_ctrl_c/+merge/88918
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'bin/CMakeLists.txt'
--- bin/CMakeLists.txt 2012-01-11 17:30:25 +0000
+++ bin/CMakeLists.txt 2012-01-17 18:50:35 +0000
@@ -31,6 +31,7 @@
SET (DEBUG_CLIENT_SRCS
debugger/main.cpp
+ debugger/xqdb_client.cpp
debugger/process_listener.cpp
debugger/command_prompt.cpp
debugger/command_line_handler.cpp
=== modified file 'bin/debugger/command_prompt.cpp'
--- bin/debugger/command_prompt.cpp 2012-01-11 17:30:25 +0000
+++ bin/debugger/command_prompt.cpp 2012-01-17 18:50:35 +0000
@@ -94,6 +94,8 @@
void
CommandPrompt::execute()
{
+ bool lWithOutput = true;
+
for (;;) {
#ifdef ZORBA_HAVE_LIBEDIT_H
const char* lBuf;
@@ -101,10 +103,19 @@
lBuf = el_gets(theEditLine, &lCharsRead);
std::string lCommandLine(lBuf, lCharsRead - 1);
#else
- std::cout << "(xqdb) ";
+ if (lWithOutput) {
+ std::cout << "(xqdb) ";
+ }
+ lWithOutput = true;
std::string lCommandLine;
std::getline(std::cin, lCommandLine);
+ if (std::cin.fail()) {
+ lWithOutput = false;
+ std::cin.clear();
+ continue;
+ }
#endif
+
std::vector<std::string> lArgs;
// split the command into arguments
=== modified file 'bin/debugger/main.cpp'
--- bin/debugger/main.cpp 2012-01-11 17:30:25 +0000
+++ bin/debugger/main.cpp 2012-01-17 18:50:35 +0000
@@ -24,67 +24,27 @@
#include <zorba/config.h>
-#include "command_prompt.h"
-#include "command_line_handler.h"
+#include "xqdb_client.h"
#include "process_listener.h"
+
using namespace zorba;
using namespace zorba::debugger;
-class XqdbClient {
-
- public:
-
- XqdbClient(unsigned int aPort)
- {
- theIdQueue = new LockFreeQueue<std::size_t>();
- theQuitQueue = new LockFreeQueue<bool>();
- theEventHandler = new EventHandler(*theIdQueue, *theQuitQueue);
- theEventHandler->init();
-
- theCommandPrompt = new CommandPrompt();
- theCommandLineHandler = new CommandLineHandler(aPort, *theIdQueue, *theQuitQueue, theEventHandler, theCommandPrompt);
- }
-
- ~XqdbClient()
- {
- if (theCommandLineHandler) {
- delete theCommandLineHandler;
- }
- if (theCommandPrompt) {
- delete theCommandPrompt;
- }
- if (theEventHandler) {
- delete theEventHandler;
- }
-
- delete theIdQueue;
- delete theQuitQueue;
- }
-
- void start()
- {
- theCommandLineHandler->execute();
- }
-
- private:
-
- LockFreeQueue<std::size_t>* theIdQueue;
- LockFreeQueue<bool>* theQuitQueue;
-
- EventHandler* theEventHandler;
- CommandPrompt* theCommandPrompt;
- CommandLineHandler* theCommandLineHandler;
-};
+
+std::auto_ptr<XqdbClient> theClient;
void
onExitProcess(ExitCode aExitCode) {
- //if (aExitCode != -1) {
- // std::cout << "Zorba has exited with code: " << aExitCode << std::endl;
- //}
- std::cout << "Terminating debugger client."<< std::endl;
- // TODO: and the memory?
+ std::cout << std::endl << "Terminating debugger client." << std::endl;
+
+#ifndef WIN32
+ XqdbClient* lClient = theClient.release();
+ if (lClient) {
+ delete lClient;
+ }
+#endif
exit(aExitCode);
}
@@ -314,6 +274,23 @@
return true;
}
+#ifdef WIN32
+BOOL WINAPI
+ctrlC_Handler(DWORD aCtrlType)
+{
+ if (CTRL_C_EVENT == aCtrlType) {
+ return true;
+ }
+ return false;
+}
+#else
+void
+ctrlC_Handler(int lParam)
+{
+ //exit(1);
+}
+#endif
+
#ifndef _WIN32_WCE
int
main(int argc, char* argv[])
@@ -322,6 +299,12 @@
_tmain(int argc, _TCHAR* argv[])
#endif
{
+#ifdef WIN32
+ SetConsoleCtrlHandler(ctrlC_Handler, TRUE);
+#else
+ signal(SIGINT, ctrlC_Handler);
+#endif
+
// **************************************************************************
// processing arguments
@@ -369,12 +352,19 @@
// **************************************************************************
// start the debugger command line
- std::auto_ptr<XqdbClient> theClient(new XqdbClient(lPort));
+ theClient.reset(new XqdbClient(lPort));
theClient->start();
} catch (...) {
return -1;
}
+#ifndef WIN32
+ XqdbClient* lClient = theClient.release();
+ if (lClient) {
+ delete lClient;
+ }
+#endif
+
return 0;
}
=== added file 'bin/debugger/xqdb_client.cpp'
--- bin/debugger/xqdb_client.cpp 1970-01-01 00:00:00 +0000
+++ bin/debugger/xqdb_client.cpp 2012-01-17 18:50:35 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "xqdb_client.h"
+
+#include <iostream>
+
+#ifdef ZORBA_HAVE_PTHREAD_H
+# include <cassert>
+#endif
+
+
+namespace zorba { namespace debugger {
+
+XqdbClient::XqdbClient(unsigned int aPort)
+{
+ theIdQueue = new LockFreeQueue<std::size_t>();
+ theQuitQueue = new LockFreeQueue<bool>();
+ theEventHandler = new EventHandler(*theIdQueue, *theQuitQueue);
+ theEventHandler->init();
+
+ theCommandPrompt = new CommandPrompt();
+ theCommandLineHandler = new CommandLineHandler(aPort, *theIdQueue, *theQuitQueue, theEventHandler, theCommandPrompt);
+}
+
+XqdbClient::~XqdbClient()
+{
+ if (theCommandLineHandler) {
+ delete theCommandLineHandler;
+ }
+ if (theCommandPrompt) {
+ delete theCommandPrompt;
+ }
+ if (theEventHandler) {
+ delete theEventHandler;
+ }
+
+ delete theIdQueue;
+ delete theQuitQueue;
+}
+
+void
+XqdbClient::start()
+{
+ theCommandLineHandler->execute();
+}
+
+
+} // namespace zorba
+} // namespace debugger
=== added file 'bin/debugger/xqdb_client.h'
--- bin/debugger/xqdb_client.h 1970-01-01 00:00:00 +0000
+++ bin/debugger/xqdb_client.h 2012-01-17 18:50:35 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+#ifndef ZORBA_DEBUGGER_XQDB_CLIENT_H
+#define ZORBA_DEBUGGER_XQDB_CLIENT_H
+
+#include "command_prompt.h"
+#include "command_line_handler.h"
+
+
+namespace zorba { namespace debugger {
+
+class XqdbClient {
+
+ public:
+
+ XqdbClient(unsigned int aPort);
+
+ ~XqdbClient();
+
+ void
+ start();
+
+ private:
+
+ LockFreeQueue<std::size_t>* theIdQueue;
+ LockFreeQueue<bool>* theQuitQueue;
+
+ EventHandler* theEventHandler;
+ CommandPrompt* theCommandPrompt;
+ CommandLineHandler* theCommandLineHandler;
+};
+
+
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_XQDB_CLIENT_H
=== modified file 'src/debugger/debugger_clientimpl.cpp'
--- src/debugger/debugger_clientimpl.cpp 2012-01-11 17:30:25 +0000
+++ src/debugger/debugger_clientimpl.cpp 2012-01-17 18:50:35 +0000
@@ -53,17 +53,22 @@
lStr >> length;
#endif
- // we are not interested in the length, but only in the init message
std::getline(*(theClient->theInStream), str, '\0');
+ // only assert if we have a good stream (no stream was broken,
+ // case in which an empty string will be returned)
+ if (theClient->theInStream->good()) {
#ifndef NDEBUG
- assert(str.size() == length);
+ assert(str.size() == length);
#endif
+ } else {
+ break;
+ }
theClient->theHandler->parseMessage(str);
// TODO: this was the initial implementation. This will have to change
- this->sleep_(1000);
+ this->sleep_(250);
}
}
=== modified file 'src/debugger/debugger_commons.cpp'
--- src/debugger/debugger_commons.cpp 2012-01-11 17:30:25 +0000
+++ src/debugger/debugger_commons.cpp 2012-01-17 18:50:35 +0000
@@ -35,6 +35,8 @@
#include "zorba/util/uri.h"
+#include "debugger_runtime.h"
+
namespace zorba {
// ****************************************************************************
@@ -382,8 +384,12 @@
bool
DebuggerCommons::mustBreak(SuspensionCause& aCause)
{
+ if (theRuntime->getAndClearInterruptBreak()) {
+ aCause = CAUSE_USER;
+ return true;
+ }
if (theBreak) {
- aCause = CAUSE_STEP;
+ aCause = theCause;
return true;
} else if (theStepping) {
std::size_t lSize = theIteratorStack.size();
=== modified file 'src/debugger/debugger_runtime.cpp'
--- src/debugger/debugger_runtime.cpp 2012-01-11 17:30:25 +0000
+++ src/debugger/debugger_runtime.cpp 2012-01-17 18:50:35 +0000
@@ -60,7 +60,8 @@
Zorba_SerializerOptions& serializerOptions,
DebuggerCommunicator* communicator,
itemHandler aHandler,
- void* aCallBackData)
+ void* aCallBackData,
+ bool* aNotBremse)
: theQuery(xqueryImpl),
theOStream(oStream),
theSerializerOptions(serializerOptions),
@@ -71,7 +72,8 @@
theSerializer(0),
theItemHandler(aHandler),
theCallbackData(aCallBackData),
- theLastContinuationCommand()
+ theLastContinuationCommand(),
+ theNotBremse(aNotBremse)
{
}
@@ -320,6 +322,7 @@
if (theExecStatus != QUERY_SUSPENDED) {
return;
}
+ *theNotBremse = false;
theExecStatus = QUERY_RUNNING;
resume();
}
@@ -500,6 +503,17 @@
}
+bool
+DebuggerRuntime::getAndClearInterruptBreak()
+{
+ bool lMustBreak = *theNotBremse;
+ if (lMustBreak) {
+ *theNotBremse = false;
+ }
+ return lMustBreak;
+}
+
+
std::list<std::pair<zstring, zstring> >
DebuggerRuntime::eval(zstring& aExpr)
{
@@ -700,7 +714,8 @@
theSerializerOptions,
theCommunicator,
theItemHandler,
- theCallbackData);
+ theCallbackData,
+ theNotBremse);
lNewRuntime->theBreakpoints = theBreakpoints;
return lNewRuntime;
=== modified file 'src/debugger/debugger_runtime.h'
--- src/debugger/debugger_runtime.h 2012-01-11 17:30:25 +0000
+++ src/debugger/debugger_runtime.h 2012-01-17 18:50:35 +0000
@@ -52,7 +52,8 @@
Zorba_SerializerOptions& serializerOptions,
DebuggerCommunicator* communicator,
itemHandler aHandler,
- void* aCallBackData);
+ void* aCallBackData,
+ bool* aNotBremse);
virtual ~DebuggerRuntime();
@@ -151,6 +152,9 @@
void
stepOut();
+ bool
+ getAndClearInterruptBreak();
+
DebuggerRuntime*
clone();
@@ -174,8 +178,8 @@
serializer* theSerializer;
itemHandler theItemHandler;
void* theCallbackData;
-
std::pair<int, std::string> theLastContinuationCommand;
+ bool* theNotBremse;
};
}
=== modified file 'src/debugger/debugger_server.cpp'
--- src/debugger/debugger_server.cpp 2012-01-11 17:30:25 +0000
+++ src/debugger/debugger_server.cpp 2012-01-17 18:50:35 +0000
@@ -18,6 +18,9 @@
#include "debugger_server.h"
#include <sstream>
+#ifndef WIN32
+# include <signal.h>
+#endif
#include <zorba/base64.h>
#include <zorba/util/uri.h>
@@ -34,6 +37,27 @@
namespace zorba {
+bool theNotBremse = false;
+
+#ifdef WIN32
+BOOL WINAPI
+DebuggerServer::ctrlC_Handler(DWORD aCtrlType)
+{
+ if (CTRL_C_EVENT == aCtrlType) {
+ theNotBremse = true;
+ return true;
+ }
+ return false;
+}
+#else
+void
+DebuggerServer::ctrlC_Handler(int lParam)
+{
+ theNotBremse = true;
+}
+#endif
+
+
DebuggerServer::DebuggerServer(
XQueryImpl* aQuery,
Zorba_SerializerOptions& aSerializerOptions,
@@ -47,7 +71,8 @@
theCommunicator = new DebuggerCommunicator(aHost, aPort);
theRuntime = new DebuggerRuntime(
aQuery, aOstream, aSerializerOptions,
- theCommunicator, aHandler, aCallbackData);
+ theCommunicator, aHandler, aCallbackData,
+ &theNotBremse);
#ifdef WIN32
theFileName = aQuery->getFileName().str();
#else
@@ -66,9 +91,17 @@
delete theCommunicator;
}
+
bool
DebuggerServer::run()
{
+ // add the interrupt handlers to catch Ctrl-C
+ #ifdef WIN32
+ SetConsoleCtrlHandler(DebuggerServer::ctrlC_Handler, TRUE);
+ #else
+ signal(SIGINT, ctrlC_Handler);
+ #endif
+
theCommunicator->connect();
if (!theCommunicator->isConnected()) {
=== modified file 'src/debugger/debugger_server.h'
--- src/debugger/debugger_server.h 2011-12-21 14:40:33 +0000
+++ src/debugger/debugger_server.h 2012-01-17 18:50:35 +0000
@@ -59,6 +59,15 @@
private:
+#ifdef WIN32
+ static BOOL WINAPI
+ ctrlC_Handler(DWORD aCtrlType);
+#else
+ static void
+ ctrlC_Handler(int lParam);
+#endif
+
+
std::string
processCommand(DebuggerCommand command);
Follow ups