bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gnulib] GNULIB wait-process module.


From: Derek Price
Subject: Re: [bug-gnulib] GNULIB wait-process module.
Date: Fri, 04 Mar 2005 11:28:13 -0500
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

Bruno Haible wrote:

Derek Price wrote:


Hello.  I was looking at removing CVS's internal waitpid substitute in
favor of the GNULIB wait-process module, but it's missing one feature
I need.  CVS needs to detect core dumps in the child of the server so
that the parent knows not to clean up the temporary workspace the
server is using.  This is for debugging purposes, really, but I can
think of no good alternative ...

Would you be amenable to a modification to wait-process that allows
core dumps to be detected?



Hmm, there is a problem with it.
 1) Core dumps are a Unix specific feature. They don't exist on Windows.
    gnulib tries to make portable APIs. - What would you think should your
    debugging code do on Windows?



Well, my general solution would return any signal that could be
detected, if desired.

Glancing at wait_process.c, WCOREDUMP() simply always returns 0
(internally) on Windows.  Something similar could also be done here.

 2) The very idea of a parent process being responsible for helping debug
    the child process makes me shudder, because it makes it hard to
    replace the parent or the client program. The idea of a "program" is
    that it can be invoked from any parent program. - What would you think
    of moving that debugging-helper code from the parent to the child process,
    and activate it when the child got a SIGABRT, SIGFPE, SIGSEGV or SIGBUS?
    This would be mostly portable to Windows: catching SIGABRT on Windows as
    well, and SIGSEGV, SIGBUS (even stack overflow) can be caught through
    libsigsegv. Only about SIGFPE I'm not sure whether you can catch it
    on Windows as well.



Actually moving the code would be complicated and not symetrical.  I
dislike having a process responsible for disposing of temporary data it
did not create.

In the CVS client/server architecture, there are two servers.  The first
authenticates the client and interprets the data coming across in such a
manner as to construct a duplicate of the client workspace.  It then
launches a second server which runs, (mostly) unaware that it is not a
CVS application running in local mode against a local repository.
Meanwhile the first server acts in the background, translating the
second server's output into something acceptable to the client.  When
the second server completes its job, it exits, then the first server
cleans up the temp space.

It is this second server's core dumps that are being caught.  It
wouldn't be impossible to make it responsible for cleaning up its own
workspace (which it did not create), but it would be a lot of work.
Right now, there is a simple switch in the first server which detects
when the child dumps core and skips the workspace cleanup with an
informative error message.

The change I'm proposing is simple.  I've attached a patch.


2005-03-04  Derek R. Price  <address@hidden>

   * lib/wait-process.h (wait_subprocess): Accept a new exitsignal
argument.
   * lib/wait-process.c (wait_subprocess): Always set *exitsignal to 0 when
   present and set it to the offending signal when the child exits due
to one.


Regards,

Derek
Index: lib/wait-process.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/wait-process.c,v
retrieving revision 1.3
diff -u -p -r1.3 wait-process.c
--- lib/wait-process.c  20 Jan 2004 16:47:31 -0000      1.3
+++ lib/wait-process.c  4 Mar 2005 16:18:13 -0000
@@ -251,7 +251,7 @@ unregister_slave_subprocess (pid_t child
    If it didn't terminate correctly, exit if exit_on_error is true, otherwise
    return 127.  */
 int
-wait_subprocess (pid_t child, const char *progname,
+wait_subprocess (pid_t child, const char *progname, int *exitsignal,
                 bool ignore_sigpipe, bool null_stderr,
                 bool slave_process, bool exit_on_error)
 {
@@ -345,6 +345,7 @@ wait_subprocess (pid_t child, const char
   WAIT_T status;

   *(int *) &status = 0;
+  if (exitsignal) *exitsignal = 0;
   for (;;)
     {
       int result = waitpid (child, &status, 0);
@@ -390,6 +391,7 @@ wait_subprocess (pid_t child, const char
       if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe)
        return 0;
 # endif
+      if (exitsignal) *exitsignal = WTERMSIG (status);
       if (exit_on_error || !null_stderr)
        error (exit_on_error ? EXIT_FAILURE : 0, 0,
               _("%s subprocess got fatal signal %d"),
Index: lib/wait-process.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/wait-process.h,v
retrieving revision 1.2
diff -u -p -r1.2 wait-process.h
--- lib/wait-process.h  20 Jan 2004 16:47:31 -0000      1.2
+++ lib/wait-process.h  4 Mar 2005 16:18:13 -0000
@@ -36,11 +36,14 @@ extern "C" {

 /* Wait for a subprocess to finish.  Return its exit code.
    If it didn't terminate correctly, exit if exit_on_error is true, otherwise
-   return 127.
+   return 127 and set exitsignal if the child terminated because of a signal.
    Arguments:
    - child is the pid of the subprocess.
    - progname is the name of the program executed by the subprocess, used for
      error messages.
+   - exitsignal is an optional pointer to an int to hold the signal number of
+     any signal that caused the child to exit.  It will be set to zero if this
+     function exits with an error not caused by the child catching a signal.
    - If ignore_sigpipe is true, consider a subprocess termination due to
      SIGPIPE as equivalent to a success.  This is suitable for processes whose
      only purpose is to write to standard output.  This flag can be safely set
@@ -52,6 +55,7 @@ extern "C" {
    - If exit_on_error is true, any error will cause the main process to exit
      with an error status.  */
 extern int wait_subprocess (pid_t child, const char *progname,
+                           int *exitsignal,
                            bool ignore_sigpipe, bool null_stderr,
                            bool slave_process, bool exit_on_error);

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]