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/89014

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/89014
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-18 12:08:07 +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-18 12:08:07 +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-18 12:08:07 +0000
@@ -24,67 +24,47 @@
 
 #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;
+
+// this will make sure the xqdb process will not quit when Ctrl-C is pressed
+#ifdef WIN32
+BOOL WINAPI
+ctrlC_Handler(DWORD aCtrlType)
+{
+  if (CTRL_C_EVENT == aCtrlType) {
+    return true;
+  }
+  return false;
+}
+#else
+void
+ctrlC_Handler(int lParam)
+{
+  // an empty sugnal handler on Linux should do the job
+}
+#endif
+
+
+// this handler function is passed the the zorba process listener and will
+// the client if the zorba process terminates
 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);
 }
@@ -322,6 +302,12 @@
 _tmain(int argc, _TCHAR* argv[])
 #endif
 {
+#ifdef WIN32
+  SetConsoleCtrlHandler(ctrlC_Handler, TRUE);
+#else
+  signal(SIGINT, ctrlC_Handler);
+#endif
+
   // **************************************************************************
   // processing arguments
 
@@ -369,12 +355,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-18 12:08:07 +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-18 12:08:07 +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-18 12:08:07 +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-18 12:08:07 +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-18 12:08:07 +0000
@@ -60,7 +60,8 @@
   Zorba_SerializerOptions& serializerOptions,
   DebuggerCommunicator* communicator,
   itemHandler aHandler,
-  void* aCallBackData)
+  void* aCallBackData,
+  bool* aInterruptBreak)
   : theQuery(xqueryImpl),
     theOStream(oStream),
     theSerializerOptions(serializerOptions),
@@ -71,7 +72,8 @@
     theSerializer(0),
     theItemHandler(aHandler),
     theCallbackData(aCallBackData),
-    theLastContinuationCommand()
+    theLastContinuationCommand(),
+    theInterruptBreak(aInterruptBreak)
 {
 }
 
@@ -320,6 +322,7 @@
   if (theExecStatus != QUERY_SUSPENDED) {
     return;
   }
+  *theInterruptBreak = false;
   theExecStatus = QUERY_RUNNING;
   resume();
 }
@@ -500,6 +503,17 @@
 }
 
 
+bool
+DebuggerRuntime::getAndClearInterruptBreak()
+{
+  bool lMustBreak = *theInterruptBreak;
+  if (lMustBreak) {
+    *theInterruptBreak = false;
+  }
+  return lMustBreak;
+}
+
+
 std::list<std::pair<zstring, zstring> >
 DebuggerRuntime::eval(zstring& aExpr)
 {
@@ -700,7 +714,8 @@
     theSerializerOptions,
     theCommunicator,
     theItemHandler,
-    theCallbackData);
+    theCallbackData,
+    theInterruptBreak);
 
   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-18 12:08:07 +0000
@@ -48,11 +48,12 @@
 
     DebuggerRuntime(
       XQueryImpl* xqueryImpl,
-      std::ostream& oStream,
+      std::ostream& outStream,
       Zorba_SerializerOptions&  serializerOptions,
       DebuggerCommunicator* communicator,
-      itemHandler aHandler,
-      void* aCallBackData);
+      itemHandler handler,
+      void* callBackData,
+      bool* interruptBreak);
 
     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*                             theInterruptBreak;
   };
 }
 

=== 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-18 12:08:07 +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,31 @@
 
 namespace zorba {
 
+bool theInterruptBreak = false;
+
+// this will make sure the zorba when run in debug (i.e. with the debugger)
+// will not terminate when Ctrl-C is pressed but trigger a query interruption
+// break through the theInterruptBreak variable that is continuously monitored
+// by the debugger commons through the debugger runtime
+#ifdef WIN32
+BOOL WINAPI
+DebuggerServer::ctrlC_Handler(DWORD aCtrlType)
+{
+  if (CTRL_C_EVENT == aCtrlType) {
+    theInterruptBreak = true;
+    return true;
+  }
+  return false;
+}
+#else
+void
+DebuggerServer::ctrlC_Handler(int lParam)
+{
+  theInterruptBreak = true;
+}
+#endif
+
+
 DebuggerServer::DebuggerServer(
   XQueryImpl*               aQuery,
   Zorba_SerializerOptions&  aSerializerOptions,
@@ -47,7 +75,8 @@
   theCommunicator = new DebuggerCommunicator(aHost, aPort);
   theRuntime = new DebuggerRuntime(
     aQuery, aOstream, aSerializerOptions,
-    theCommunicator, aHandler, aCallbackData);
+    theCommunicator, aHandler, aCallbackData,
+    &theInterruptBreak);
 #ifdef WIN32
   theFileName = aQuery->getFileName().str();
 #else
@@ -66,9 +95,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-18 12:08:07 +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);
 

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to