Merge lp:~zorba-coders/zorba/debugger_stop_command into lp:zorba

Proposed by Gabriel Petrovay
Status: Merged
Approved by: Gabriel Petrovay
Approved revision: 10611
Merged at revision: 10613
Proposed branch: lp:~zorba-coders/zorba/debugger_stop_command
Merge into: lp:zorba
Diff against target: 451 lines (+97/-65)
13 files modified
bin/debugger/command_line_handler.cpp (+11/-1)
bin/debugger/command_line_handler.h (+6/-2)
bin/debugger/event_handler.cpp (+1/-2)
bin/debugger/main.cpp (+9/-12)
bin/debugger/process_listener.cpp (+13/-9)
bin/debugger/process_listener.h (+1/-1)
include/zorba/debugger_client.h (+5/-1)
src/debugger/debugger_clientimpl.cpp (+6/-2)
src/debugger/debugger_clientimpl.h (+1/-1)
src/debugger/debugger_communicator.cpp (+10/-7)
src/debugger/debugger_runtime.cpp (+8/-18)
src/debugger/debugger_runtime.h (+0/-4)
src/debugger/debugger_server.cpp (+26/-5)
To merge this branch: bzr merge lp:~zorba-coders/zorba/debugger_stop_command
Reviewer Review Type Date Requested Status
David Graf (community) Approve
Gabriel Petrovay (community) Approve
Review via email: mp+88107@code.launchpad.net

Commit message

Implemented the stop command.
Fixed termination on Windows.
TODO: still a problem on Windows when quitting the debugger client: a zorba store is shut down and in the store destructor a lock hangs the execution of xqdb forever. Not even Ctrl-C helps (probably because everything is called from the exit function in main.cpp)

Description of the change

Implemented the stop command.
Fixed termination on Windows.
TODO: still a problem on Windows when quitting the debugger client: a zorba store is shut down and in the store destructor a lock hangs the execution of xqdb forever. Not even Ctrl-C helps (probably because everything is called from the exit function in main.cpp)

To post a comment you must log in.
Revision history for this message
Gabriel Petrovay (gabipetrovay) :
review: Approve
Revision history for this message
David Graf (davidagraf) wrote :

It works. But during testing this feature, I managed to produce an Assertion that has nothing to do with this change. I file a bug for it.

review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job debugger_stop_command-2012-01-11T13-10-06.289Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/debugger/command_line_handler.cpp'
2--- bin/debugger/command_line_handler.cpp 2012-01-03 12:10:06 +0000
3+++ bin/debugger/command_line_handler.cpp 2012-01-10 20:09:25 +0000
4@@ -116,7 +116,7 @@
5 }
6 }
7 }
8- theWaitFor = theClient->stop();
9+ theWaitFor = theClient->stop(true);
10 theClient->quit();
11 theQuit = true;
12 }
13@@ -131,6 +131,13 @@
14
15 template<>
16 void
17+CommandLineHandler::handle<Stop>(ZORBA_TR1_NS::tuple<> &t)
18+{
19+ theWaitFor = theClient->stop(false);
20+}
21+
22+template<>
23+void
24 CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &aTuple)
25 {
26 DebuggerClient::BreakpointType lType = DebuggerClient::Line;
27@@ -271,6 +278,9 @@
28 // DBGP: run
29 *theCommandLine << createCommand<Run>(TUPLE(), "run", *this, "Run the query");
30
31+ // DBGP: stop
32+ *theCommandLine << createCommand<Stop>(TUPLE(), "stop", *this, "Stop the query");
33+
34 // DBGP: breakpoint_set
35 {
36 std::set<std::string> lAliases;
37
38=== modified file 'bin/debugger/command_line_handler.h'
39--- bin/debugger/command_line_handler.h 2012-01-03 12:10:06 +0000
40+++ bin/debugger/command_line_handler.h 2012-01-10 20:09:25 +0000
41@@ -35,6 +35,7 @@
42 Variables,
43 Quit,
44 Run,
45+ Stop,
46 BreakpointSet,
47 BreakpointGet,
48 BreakpointRemove,
49@@ -132,10 +133,13 @@
50
51 template<>
52 void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t);
53-
54+
55+template<>
56+void CommandLineHandler::handle<Stop> (ZORBA_TR1_NS::tuple<> &t);
57+
58 template<>
59 void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t);
60-
61+
62 template<>
63 void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple);
64
65
66=== modified file 'bin/debugger/event_handler.cpp'
67--- bin/debugger/event_handler.cpp 2011-12-21 14:40:33 +0000
68+++ bin/debugger/event_handler.cpp 2012-01-10 20:09:25 +0000
69@@ -91,8 +91,7 @@
70 } catch (ZorbaException& e) {
71 std::cerr << "FATAL: could not execute query: " << std::endl;
72 std::cerr << e << std::endl;
73- std::cerr << "This is a bug, please report to zorba-users@lists.sourceforge.net" << std::endl;
74- //theContinueProducer.produce(false);
75+ std::cerr << "This is a bug, please report it at http://bugs.launchpad.net/zorba" << std::endl;
76 }
77 }
78
79
80=== modified file 'bin/debugger/main.cpp'
81--- bin/debugger/main.cpp 2012-01-05 13:19:14 +0000
82+++ bin/debugger/main.cpp 2012-01-10 20:09:25 +0000
83@@ -78,9 +78,6 @@
84 };
85
86
87-XqdbClient* theClient;
88-
89-
90 void
91 onExitProcess(ExitCode aExitCode) {
92 //if (aExitCode != -1) {
93@@ -89,12 +86,12 @@
94 std::cout << "Terminating debugger client."<< std::endl;
95 // TODO: and the memory?
96
97- delete theClient;
98 exit(aExitCode);
99 }
100
101+
102 int
103-startZorba(std::string& aExec, std::vector<std::string>& aArgs)
104+startZorba(std::string& aExec, std::vector<std::string>& aArgs, std::auto_ptr<ProcessListener>& aProcessListener)
105 {
106 #ifdef WIN32
107 // **************************
108@@ -143,7 +140,7 @@
109
110 if (lResult) {
111 // Watch the process
112- ProcessListener* lPl = new ProcessListener(piProcessInfo.hProcess, &onExitProcess);
113+ aProcessListener.reset(new ProcessListener(piProcessInfo.dwProcessId, &onExitProcess));
114 }
115 else {
116 // CreateProcess failed
117@@ -215,7 +212,7 @@
118 }
119
120 // Watch the process
121- new ProcessListener(pID, &onExitProcess);
122+ aProcessListener.reset(new ProcessListener(pID, &onExitProcess));
123
124 return 0;
125 }
126@@ -357,8 +354,11 @@
127 // **************************************************************************
128 // start a zorba
129
130+ // This is a process listener used to watch the Zorba process termination.
131+ std::auto_ptr<ProcessListener> lProcessListener;
132+
133 if (!lStandalone) {
134- int lResult = startZorba(lZorbaExec, lZorbaArgs);
135+ int lResult = startZorba(lZorbaExec, lZorbaArgs, lProcessListener);
136 if (lResult) {
137 return lResult;
138 }
139@@ -369,13 +369,10 @@
140 // **************************************************************************
141 // start the debugger command line
142
143- theClient = new XqdbClient(lPort);
144+ std::auto_ptr<XqdbClient> theClient(new XqdbClient(lPort));
145 theClient->start();
146
147- delete theClient;
148-
149 } catch (...) {
150- delete theClient;
151 return -1;
152 }
153
154
155=== modified file 'bin/debugger/process_listener.cpp'
156--- bin/debugger/process_listener.cpp 2012-01-05 13:19:14 +0000
157+++ bin/debugger/process_listener.cpp 2012-01-10 20:09:25 +0000
158@@ -62,16 +62,20 @@
159 ProcessId lPid = lThis->getProcessID();
160
161 #ifdef WIN32
162- // wait for the process to exit
163- WaitForSingleObject(lPid, INFINITE);
164-
165- // find out the process exit code if possible
166- if (!GetExitCodeProcess(lThis->getProcessID(), &lExitCode)) {
167- lExitCode = -1;
168+ HANDLE lProcessHandle = OpenProcess(SYNCHRONIZE, false, lPid);
169+ if (lProcessHandle != NULL) {
170+ // wait for the process to exit
171+ DWORD lResult = WaitForSingleObject(lProcessHandle, INFINITE);
172+
173+ // find out the process exit code if possible
174+ if (!GetExitCodeProcess(lProcessHandle, &lExitCode)) {
175+ lExitCode = -1;
176+ }
177+ DWORD dw = GetLastError();
178+
179+ // wait a little for zorba to dump the garbage
180+ Sleep(1000);
181 }
182-
183- // wait a little for zorba to dump the garbage
184- Sleep(1000);
185 #else
186 int lChildExitStatus;
187
188
189=== modified file 'bin/debugger/process_listener.h'
190--- bin/debugger/process_listener.h 2012-01-05 13:19:14 +0000
191+++ bin/debugger/process_listener.h 2012-01-10 20:09:25 +0000
192@@ -29,7 +29,7 @@
193 #else
194 # include <windows.h>
195 typedef DWORD ThreadId;
196- typedef HANDLE ProcessId;
197+ typedef DWORD ProcessId;
198 typedef DWORD ExitCode;
199 # define ZORBA_THREAD_RETURN DWORD WINAPI
200 #endif
201
202=== modified file 'include/zorba/debugger_client.h'
203--- include/zorba/debugger_client.h 2011-12-21 14:40:33 +0000
204+++ include/zorba/debugger_client.h 2012-01-10 20:09:25 +0000
205@@ -273,9 +273,13 @@
206 * This command tells the debug engine, that it should
207 * break the execution at the next point possible.
208 *
209+ * @param withQuit This is a Zorba extension of the DBGP protocol that
210+ * controls if the client should terminate execution and quit (true)
211+ * or only terminate execution but not quit (false). This is used
212+ * by command line clients that implement multiple query runs.
213 * @return The id of this request
214 */
215- virtual std::size_t stop() = 0;
216+ virtual std::size_t stop(bool withQuit) = 0;
217
218 /**
219 * @brief Send the detach command to the debug engine.
220
221=== modified file 'src/debugger/debugger_clientimpl.cpp'
222--- src/debugger/debugger_clientimpl.cpp 2011-12-21 14:40:33 +0000
223+++ src/debugger/debugger_clientimpl.cpp 2012-01-10 20:09:25 +0000
224@@ -213,10 +213,14 @@
225 }
226
227 std::size_t
228-DebuggerClientImpl::stop()
229+DebuggerClientImpl::stop(bool withQuit)
230 {
231 std::size_t id = ++theLastId;
232- *theOutStream << "stop -i " << id << '\0';
233+ *theOutStream << "stop -i " << id;
234+ if (!withQuit) {
235+ *theOutStream << " -z 1";
236+ }
237+ *theOutStream << '\0';
238 theOutStream->flush();
239 return id;
240 }
241
242=== modified file 'src/debugger/debugger_clientimpl.h'
243--- src/debugger/debugger_clientimpl.h 2011-12-21 14:40:33 +0000
244+++ src/debugger/debugger_clientimpl.h 2012-01-10 20:09:25 +0000
245@@ -57,7 +57,7 @@
246 virtual std::size_t step_into();
247 virtual std::size_t step_out();
248 virtual std::size_t step_over();
249- virtual std::size_t stop();
250+ virtual std::size_t stop(bool withQuit = true);
251 virtual std::size_t detach();
252 virtual std::size_t breakpoint_set(BreakpointType aType,
253 bool aEnabled = true,
254
255=== modified file 'src/debugger/debugger_communicator.cpp'
256--- src/debugger/debugger_communicator.cpp 2011-12-21 14:40:33 +0000
257+++ src/debugger/debugger_communicator.cpp 2012-01-10 20:09:25 +0000
258@@ -74,13 +74,17 @@
259 }
260 }
261
262+#ifdef NDEBUG
263+# define TIMEOUT 6
264+#else
265+# define TIMEOUT 60
266+#endif
267+
268 void
269 DebuggerCommunicator::connect()
270 {
271- for (int i = 0; i < 5 && !theSocket; i++)
272- {
273- try
274- {
275+ for (int i = 0; i < TIMEOUT && !theSocket; i++) {
276+ try {
277 // Connect to the client on the given host and port
278 std::auto_ptr<TCPSocket> lSocket(new TCPSocket(theHost, thePort));
279 theSocket = lSocket.release();
280@@ -91,10 +95,9 @@
281 theResponseQueue = new ResponseQueue(theCommunicatorOutStream);
282 theResponseQueue->start();
283 }
284- catch (DebuggerSocketException& /* e */)
285- {
286+ catch (DebuggerSocketException& /* e */) {
287 // Wait one second before trying to reconnect
288- msleep(100);
289+ msleep(1000);
290 }
291 }
292 }
293
294=== modified file 'src/debugger/debugger_runtime.cpp'
295--- src/debugger/debugger_runtime.cpp 2012-01-03 12:10:06 +0000
296+++ src/debugger/debugger_runtime.cpp 2012-01-10 20:09:25 +0000
297@@ -67,7 +67,6 @@
298 theCommunicator(communicator),
299 theWrapper(theQuery->generateWrapper()),
300 theExecStatus(QUERY_IDLE),
301- theNotSendTerminateEvent(false),
302 thePlanIsOpen(false),
303 theSerializer(0),
304 theItemHandler(aHandler),
305@@ -89,6 +88,14 @@
306 theWrapper->open();
307 thePlanIsOpen = true;
308 runQuery();
309+
310+ std::stringstream lResult;
311+ lResult << "<response command=\"" << theLastContinuationCommand.second << "\" "
312+ << "status=\"stopping\" "
313+ << "reason=\"ok\" "
314+ << "transaction_id=\"" << theLastContinuationCommand.first << "\">"
315+ << "</response>";
316+ theCommunicator->send(lResult.str());
317 }
318
319 void
320@@ -107,7 +114,6 @@
321 theWrapper = theQuery->generateWrapper();
322 thePlanIsOpen = false;
323 theExecStatus = QUERY_IDLE;
324- theNotSendTerminateEvent = false;
325 reset();
326 }
327
328@@ -324,15 +330,6 @@
329 {
330 AutoLock lLock(theLock, Lock::WRITE);
331 theExecStatus = QUERY_TERMINATED;
332-
333- std::stringstream lResult;
334- lResult << "<response command=\"" << theLastContinuationCommand.second << "\" "
335- << "status=\"stopping\" "
336- << "reason=\"ok\" "
337- << "transaction_id=\"" << theLastContinuationCommand.first << "\">"
338- << "</response>";
339- theCommunicator->send(lResult.str());
340- // TODO: something more here?
341 }
342
343
344@@ -503,13 +500,6 @@
345 }
346
347
348-void
349-DebuggerRuntime::setNotSendTerminateEvent()
350-{
351- theNotSendTerminateEvent = true;
352-}
353-
354-
355 std::list<std::pair<zstring, zstring> >
356 DebuggerRuntime::eval(zstring& aExpr)
357 {
358
359=== modified file 'src/debugger/debugger_runtime.h'
360--- src/debugger/debugger_runtime.h 2012-01-03 12:10:06 +0000
361+++ src/debugger/debugger_runtime.h 2012-01-10 20:09:25 +0000
362@@ -67,9 +67,6 @@
363 public:
364
365 void
366- setNotSendTerminateEvent();
367-
368- void
369 resetRuntime();
370
371 ExecutionStatus
372@@ -173,7 +170,6 @@
373 ExecutionStatus theExecStatus;
374 mutable Lock theLock;
375 std::set<DebugIterator*> theBreakpoints;
376- bool theNotSendTerminateEvent;
377 bool thePlanIsOpen;
378 serializer* theSerializer;
379 itemHandler theItemHandler;
380
381=== modified file 'src/debugger/debugger_server.cpp'
382--- src/debugger/debugger_server.cpp 2012-01-03 12:10:06 +0000
383+++ src/debugger/debugger_server.cpp 2012-01-10 20:09:25 +0000
384@@ -78,6 +78,8 @@
385 init();
386
387 std::string lCommand;
388+ std::string lCommandName;
389+ int lTransactionID = 0;
390
391 while (!theStopping &&
392 theRuntime->getExecutionStatus() != QUERY_DETACHED) {
393@@ -86,6 +88,9 @@
394 theCommunicator->receive(lCommand);
395 DebuggerCommand lCmd = DebuggerCommand(lCommand);
396
397+ lCommandName = lCmd.getName();
398+ lCmd.getArg("i", lTransactionID);
399+
400 if (theRuntime->getExecutionStatus() == QUERY_TERMINATED) {
401 // clone the existing runtime
402 DebuggerRuntime* lNewRuntime = theRuntime->clone();
403@@ -108,7 +113,16 @@
404 }
405
406 theRuntime->terminate();
407- theRuntime->resetRuntime();
408+
409+ std::stringstream lResult;
410+ lResult << "<response command=\"" << lCommandName << "\" "
411+ << "status=\"stopped\" "
412+ << "reason=\"ok\" "
413+ << "transaction_id=\"" << lTransactionID << "\">"
414+ << "</response>";
415+ theCommunicator->send(lResult.str());
416+
417+ //theRuntime->resetRuntime();
418 theRuntime->join();
419
420 return true;
421@@ -473,10 +487,18 @@
422
423 } else if (aCommand.getName() == "stop") {
424 theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());
425- theStopping = true;
426+ // sending the zorba extensions flag, the debugger server will not terminate
427+ // when the stop command is sent. This way the zorba debugger client can
428+ // perform multiple execution of the same query even when the user terminates
429+ // the execution using the stop command.
430+ // NOTE: theStopping is controlling the main debugger server loop
431+ if (!lZorbaExtensions) {
432+ theStopping = true;
433+ }
434
435- lResponse << "reason=\"ok\" status=\"stopped\" ";
436+ lResponse << "status=\"stopping\" reason=\"ok\"";
437 lResponse << ">";
438+
439 theRuntime->terminateRuntime();
440
441 } else if (aCommand.getName() == "stack_depth") {
442@@ -531,8 +553,7 @@
443 theRuntime->stepOver();
444 return "";
445 } else if (aCommand.getName() == "step_out") {
446- ExecutionStatus lStatus = theRuntime->getExecutionStatus();
447- if (lStatus != QUERY_SUSPENDED) {
448+ if (theRuntime->getExecutionStatus() != QUERY_SUSPENDED) {
449 return buildErrorResponse(lTransactionID, lCmdName, 6, "Can not step out since the execution is not started.");
450 }
451 theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());

Subscribers

People subscribed via source and target branches