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

Proposed by Cezar Andrei
Status: Merged
Approved by: Paul J. Lucas
Approved revision: 35
Merged at revision: 33
Proposed branch: lp:~zorba-coders/zorba/bug1086323-processExitCode
Merge into: lp:zorba/process-module
Diff against target: 126 lines (+44/-32)
2 files modified
src/com/zorba-xquery/www/modules/process.xq (+8/-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
Paul J. Lucas Approve
Chris Hillery Approve
Sorin Marian Nasoi Approve
Review via email: mp+138266@code.launchpad.net

This proposal supersedes a proposal from 2012-12-04.

Commit message

Fix for bug 1086323, align Fedora and Ubuntu when process module executes a command that crashes.

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 : Posted in a previous version of this proposal
Revision history for this message
Paul J. Lucas (paul-lucas) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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.

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

Using the usual exit codes convention, as per our todays' talk.

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
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-05T17-36-43.652Z 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
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Chris Hillery (ceejatec) wrote :

The module comments still list the -2000 / -1000 return value numbers.

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

Paul (not sure if you were on the conf call today) : we decided that we should fix just this problem in the process module for now, to allow it to consistently report exit status across Linux distributions and hopefully MacOS. As for the other issues you and I raised, I will file new bugs which will be rolled into a v2 of the process module sometime after Zorba 2.8 is shippped.

It would be great if you could test this on MacOS, and vote Approve if there are no other issues.

Revision history for this message
Paul J. Lucas (paul-lucas) wrote :

> It would be great if you could test this on MacOS, and vote Approve if there
> are no other issues.

I could test it if there were a test I could run.

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

Validation queue job bug1086323-processExitCode-2012-12-05T18-10-35.842Z is finished. The final status was:

All tests succeeded!

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

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 1 Needs Fixing, 2 Pending.

Revision history for this message
Sorin Marian Nasoi (sorin.marian.nasoi) wrote :

I have checked on Fedora and these are the returned codes:

- if a test ends in a SEG FAULT => exit-code = 139
- if a test reaches an ASSERT => exit code = 134

So I approve this proposal but at least someone on Ubuntu (ideally also on MacOS) should confirm that they get the same exact codes.

review: Approve
35. By Cezar Andrei <email address hidden>

Also fix xqdoc.

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

Fixed xqdoc.

Also I tested it on Ubuntu, segfault comes with exit code 139.

To test it one needs to call process:exec on a program that ends with a segmentation fault.

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

Verified (with Sorin's repro script in email) that this works on Ubuntu.

review: Approve
Revision history for this message
Paul J. Lucas (paul-lucas) wrote :

On Mac OS X 10.8.2, it prints:

139 0

Revision history for this message
Paul J. Lucas (paul-lucas) wrote :

After discussion with Chris, I'm approving this despite it not working on Mac OS X since the short-term goal is to have this working on Linux where having it working on Mac OS X is a nice-to-have.

The test that was supposed to SEGFAULT did; the test that was supposed to have an assert() failure didn't.

review: Approve
Revision history for this message
Paul J. Lucas (paul-lucas) wrote :

Follow-up: after running a new query to call a C program:

#include <stdlib.h>
int main() {
  abort();
}

it prints 134. Hence, the process-module fix works but the HOF code behaves differently on Mac OS X.

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

Subscribers

People subscribed via source and target branches

to all changes: