Merge lp:~zorba-coders/zorba/bug1086323-processExitCode into lp:zorba/process-module

Proposed by Cezar Andrei
Status: Superseded
Proposed branch: lp:~zorba-coders/zorba/bug1086323-processExitCode
Merge into: lp:zorba/process-module
Diff against target: 128 lines (+46/-32)
2 files modified
src/com/zorba-xquery/www/modules/process.xq (+10/-0)
src/com/zorba-xquery/www/modules/process.xq.src/process.cpp (+36/-32)
To merge this branch: bzr merge lp:~zorba-coders/zorba/bug1086323-processExitCode
Reviewer Review Type Date Requested Status
Chris Hillery Needs Fixing
Paul J. Lucas Needs Fixing
Sorin Marian Nasoi Pending
Review via email: mp+137966@code.launchpad.net

This proposal has been superseded by a proposal from 2012-12-05.

Commit message

Fix for bug 1086323.

Description of the change

Fix for bug 1086323.

To post a comment you must log in.
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Paul J. Lucas (paul-lucas) wrote :

1. Why return made-up numbers, e.g., -1000, etc? Why not simply return the actual exit status? Of course this implies that you'd have to implement XQuery functions that do the equivalent of the W* macros. Either that, or return XML data, e.g.:

  <process id="1234" raw-exit-code="0" status="normal"/>

or:

  <process id="1234" raw-exit-code="56" status="signal" signal="5" dumped-core="true"/>

2. When you throw the USER_EXCEPTION, why not include the actual OS-level error message? There is code in src/util/error_util.h. Yes, this implies that this code would have to be moved to the public API.

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

The attempt to merge lp:~zorba-coders/zorba/bug1086323-processExitCode into lp:zorba/process-module failed. Below is the output from the failed tests.

CMake Error at /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job bug1086323-processExitCode-2012-12-04T19-47-40.632Z is
  finished. The final status was:

  4 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Chris Hillery (ceejatec) wrote :

I assume using made-up exit codes was so the new information could fit into the existing result schema, for backwards compatibility. Still, I think it probably would be better to improve the schema and bump the module version number. If there is any way for the results to be the same on posix and Windows that'd be ideal.

Also, I would like there to be a test case for this, including invoking a program that segfaults and getting a result. I'm not sure if this could be done cross-platform but it'd be good to try.

Revision history for this message
Cezar Andrei (cezar-andrei) wrote :

Interesting Ubuntu and Fedora don't implement this the same way.

On Ubuntu running a bash script or the process xq script which calls a program that segFaults, the exit code is 139. The macro WIFEXITED(stat) returns true and WEXITSTATUS(stat) returns 139. Which btw means acording to the link below an 128+signal 11.
http://tldp.org/LDP/abs/html/exitcodes.html#EXITCODESREF

On Fedora running the same process implementation, the macro WIFEXITED(stat) returns false and WIFSIGNALED(stat) returns true which means we can call WTERMSIG(stat) which returns 11.

So in order to bring these two together I propose make them both return 139, just like shell because this process module executes a shell command not just an executable and I think we need to respect the same conventions. This means that for the Fedora case just add 128 and use it as exit code.

On Windows I couldn't find something similar, if possible we could follow the same convention.

Comments?

Revision history for this message
Chris Hillery (ceejatec) wrote :

Why does the process module execute a shell command? I would expect it to behave like execl(), not exec() (which is not part of POSIX as far as I can tell).

Oh, yeah, ugh - I see that process.cpp collects the (separate) command-line arguments from the XQuery functions and concatenates them together with spaces. That's broken, IMHO. It uses double-quotes, but that won't work for arguments that contain double-quotes.

I'm not sure how to do all this on Windows, although I'm confident there's a better way. But on Unix this implementation is simply not correct. That probably explains to some degree why the behaviour on Fedora is weird - it's not actually getting the return value of the executed command, but of some intermediate shell which is evaluating that command.

review: Needs Fixing
Revision history for this message
Cezar Andrei (cezar-andrei) wrote :

it's executing a shell with the commands, this way one can have access to shell commands.

Revision history for this message
Chris Hillery (ceejatec) wrote :

It's my opinion that that is not a valuable feature, and the downsides outweigh its usefulness. Also, users can do this themselves if they require it by executing a shell or cmd. We should not do it for them, or at the very least this should not be the default.

34. By Cezar Andrei <email address hidden>

Using the exit codes convention.

35. By Cezar Andrei <email address hidden>

Also fix xqdoc.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/com/zorba-xquery/www/modules/process.xq'
2--- src/com/zorba-xquery/www/modules/process.xq 2012-09-27 16:53:40 +0000
3+++ src/com/zorba-xquery/www/modules/process.xq 2012-12-05 17:32:23 +0000
4@@ -56,6 +56,11 @@
5 : @return the result of the execution as an element as
6 : shown in the documentation of this module. The exit-code
7 : element returns the exit code of the child process.
8+ : For POSIX compliant platforms: returns the process exit code. If process is
9+ : terminated: (-1000) - termination signal code. If process is stoped:
10+ : (-2000) - stop signal code or -1999 othewise.
11+ : For Windows platforms: returns the return value of the process or the exit
12+ : or terminate process specified value.
13 :
14 : @error process:PROC01 if an error occurred while communicating
15 : with the executed process.
16@@ -75,6 +80,11 @@
17 : @return the result of the execution as an element as
18 : shown in the documentation of this module. The exit-code
19 : element returns the exit code of the child process.
20+ : For POSIX compliant platforms: returns the process exit code. If process is
21+ : terminated: (-1000) - termination signal code. If process is stoped:
22+ : (-2000) - stop signal code or -1999 othewise.
23+ : For Windows platforms: returns the return value of the process or the exit
24+ : or terminate process specified value.
25 :
26 : @error process:PROC01 if an error occurred while communicating
27 : with the executed process.
28
29=== modified file 'src/com/zorba-xquery/www/modules/process.xq.src/process.cpp'
30--- src/com/zorba-xquery/www/modules/process.xq.src/process.cpp 2012-07-21 01:09:37 +0000
31+++ src/com/zorba-xquery/www/modules/process.xq.src/process.cpp 2012-12-05 17:32:23 +0000
32@@ -257,7 +257,7 @@
33 };
34
35 //start child process
36- BOOL ok=create_child_process(lStdOut,lStdErr,aCommand,lChildProcessInfo);
37+ BOOL ok = create_child_process(lStdOut,lStdErr,aCommand,lChildProcessInfo);
38 if(ok==TRUE)
39 {
40
41@@ -413,8 +413,8 @@
42 std::ostringstream lStderr;
43
44 #ifdef WIN32
45- std::string lCommandLineString=lTmp.str();
46- int code = run_process(lCommandLineString,lStdout,lStderr);
47+ std::string lCommandLineString = lTmp.str();
48+ int code = run_process(lCommandLineString, lStdout, lStderr);
49
50 if (code != 0)
51 {
52@@ -424,6 +424,7 @@
53 "http://www.zorba-xquery.com/modules/process", "PROC01");
54 throw USER_EXCEPTION(lQName, lErrorMsg.str().c_str());
55 }
56+ exit_code = code;
57
58 #else //not WIN32
59
60@@ -470,36 +471,39 @@
61
62 int stat = 0;
63
64- waitpid(pid, &stat, 0);
65- /*pid_t w;
66- do
67- {
68- w = waitpid(pid, &stat, WUNTRACED | WCONTINUED);
69- if (w == -1)
70- {
71- perror("waitpid");
72- exit(EXIT_FAILURE);
73- }
74+ pid_t w = waitpid(pid, &stat, 0);
75+
76+ if (w == -1)
77+ {
78+ std::stringstream lErrorMsg;
79+ lErrorMsg << "Failed to wait for child process ";
80+ Item lQName = ProcessModule::getItemFactory()->createQName(
81+ "http://www.zorba-xquery.com/modules/process", "PROC01");
82+ throw USER_EXCEPTION(lQName, lErrorMsg.str().c_str());
83+ }
84
85- if (WIFEXITED(stat))
86- {
87- printf("exited, status=%d\n", WEXITSTATUS(stat));
88- }
89- else if (WIFSIGNALED(stat))
90- {
91- printf("killed by signal %d\n", WTERMSIG(stat));
92- }
93- else if (WIFSTOPPED(stat))
94- {
95- printf("stopped by signal %d\n", WSTOPSIG(stat));
96- }
97- else if (WIFCONTINUED(stat))
98- {
99- printf("continued\n");
100- }
101- } while (!WIFEXITED(stat) && !WIFSIGNALED(stat));
102- */
103- exit_code = WEXITSTATUS(stat);
104+ if (WIFEXITED(stat))
105+ {
106+ //std::cout << " WEXITSTATUS : " << WEXITSTATUS(stat) << std::endl; std::cout.flush();
107+ exit_code = WEXITSTATUS(stat);
108+ }
109+ else if (WIFSIGNALED(stat))
110+ {
111+ //std::cout << " WTERMSIG : " << WTERMSIG(stat) << std::endl; std::cout.flush();
112+ exit_code = 128 + WTERMSIG(stat);
113+ }
114+ else if (WIFSTOPPED(stat))
115+ {
116+ //std::cout << " STOPSIG : " << WSTOPSIG(stat) << std::endl; std::cout.flush();
117+ exit_code = 128 + WSTOPSIG(stat);
118+ }
119+ else
120+ {
121+ //std::cout << " else : " << std::endl; std::cout.flush();
122+ exit_code = 255;
123+ }
124+
125+ //std::cout << " exit_code : " << exit_code << std::endl; std::cout.flush();
126
127 }
128 #endif // WIN32

Subscribers

People subscribed via source and target branches

to all changes: