Annotation of embedaddon/rsync/patches/catch_crash_signals.diff, revision 1.1.1.1

1.1       misho       1: Igor Yu. Zhbanov wrote:
                      2: > I am using rsync compiled with Cygwin on windows.
                      3: > I must call rsync from the *.bat script (I don't want to use a bash on Windows)
                      4: > and I have noticed that in the case when program compiled by Cygwin crashes
                      5: > via segmentation fault and default SIGSEGV handler is called, then it
                      6: > terminates process with exit status 0 as I see it from my *.bat script.
                      7: > (But if I invoke a program from bash (compiled with Cygwin too) I will see
                      8: > error code 139 as expected.)
                      9: >
                     10: > It is a Cygwin's problem, not an rsync's, but to use it on windows and
                     11: > to distinguish situations when rsync crashes and when it exits normally,
                     12: > I have written signal handler which terminates process with code 50.
                     13: > You may use conventional 139. Also signal handler writes corresponding
                     14: > message to log file.
                     15: >
                     16: > By the way. When I terminate rsync in daemon mode by pressing Control-C,
                     17: > it writes an error to log. May be this is not an error but info or notice?
                     18: 
                     19: I'm not sure I like this, but if you run into the cygwin problem, this might
                     20: prove helpful.
                     21: 
                     22: To use this patch, run these commands for a successful build:
                     23: 
                     24:     patch -p1 <patches/catch_crash_signals.diff
                     25:     ./configure                                  (optional if already run)
                     26:     make
                     27: 
                     28: based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
                     29: diff --git a/errcode.h b/errcode.h
                     30: --- a/errcode.h
                     31: +++ b/errcode.h
                     32: @@ -47,6 +47,8 @@
                     33:  #define RERR_TIMEOUT    30      /* timeout in data send/receive */
                     34:  #define RERR_CONTIMEOUT 35      /* timeout waiting for daemon connection */
                     35:  
                     36: +#define RERR_WECRASHED         50      /* We have crashed. */
                     37: +
                     38:  /* Although it doesn't seem to be specified anywhere,
                     39:   * ssh and the shell seem to return these values:
                     40:   *
                     41: diff --git a/log.c b/log.c
                     42: --- a/log.c
                     43: +++ b/log.c
                     44: @@ -92,6 +92,7 @@ struct {
                     45:        { RERR_TERMINATED , "sibling process terminated abnormally" },
                     46:        { RERR_SIGNAL1    , "received SIGUSR1" },
                     47:        { RERR_SIGNAL     , "received SIGINT, SIGTERM, or SIGHUP" },
                     48: +      { RERR_WECRASHED  , "rsync caught a CRASH-causing signal" },
                     49:        { RERR_WAITCHILD  , "waitpid() failed" },
                     50:        { RERR_MALLOC     , "error allocating core memory buffers" },
                     51:        { RERR_PARTIAL    , "some files/attrs were not transferred (see previous errors)" },
                     52: diff --git a/main.c b/main.c
                     53: --- a/main.c
                     54: +++ b/main.c
                     55: @@ -214,8 +214,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
                     56:                        *exit_code_ptr = RERR_TERMINATED;
                     57:                else
                     58:                        *exit_code_ptr = RERR_WAITCHILD;
                     59: -      } else
                     60: +      } else {
                     61:                *exit_code_ptr = WEXITSTATUS(status);
                     62: +              if (*exit_code_ptr == RERR_WECRASHED)
                     63: +                      *exit_code_ptr = RERR_CRASHED;
                     64: +      }
                     65:  }
                     66:  
                     67:  void write_del_stats(int f)
                     68: @@ -1629,6 +1632,14 @@ void remember_children(UNUSED(int val))
                     69:                                break;
                     70:                        }
                     71:                }
                     72: +              if (WIFSIGNALED(status)) {
                     73: +                      rprintf(FLOG,
                     74: +                              "rsync error: (1) Child proccess has unexpectedly died with signal %d\n",
                     75: +                              WTERMSIG(status));
                     76: +              } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) {
                     77: +                      rprintf(FLOG,
                     78: +                              "rsync error: (1) Child proccess has CRASHED.\n");
                     79: +              }
                     80:        }
                     81:  #endif
                     82:  #ifndef HAVE_SIGACTION
                     83: @@ -1684,6 +1695,12 @@ static void rsync_panic_handler(UNUSED(int whatsig))
                     84:  }
                     85:  #endif
                     86:  
                     87: +static void rsync_crash_handler(UNUSED(int whatsig))
                     88: +{
                     89: +      log_exit(RERR_WECRASHED, __FILE__, __LINE__);
                     90: +      logfile_close();
                     91: +      _exit(RERR_WECRASHED);
                     92: +}
                     93:  
                     94:  int main(int argc,char *argv[])
                     95:  {
                     96: @@ -1708,6 +1725,11 @@ int main(int argc,char *argv[])
                     97:        SIGACTMASK(SIGFPE, rsync_panic_handler);
                     98:        SIGACTMASK(SIGABRT, rsync_panic_handler);
                     99:        SIGACTMASK(SIGBUS, rsync_panic_handler);
                    100: +#else
                    101: +      SIGACTMASK(SIGSEGV, rsync_crash_handler);
                    102: +      SIGACTMASK(SIGFPE, rsync_crash_handler);
                    103: +      SIGACTMASK(SIGABRT, rsync_crash_handler);
                    104: +      SIGACTMASK(SIGBUS, rsync_crash_handler);
                    105:  #endif
                    106:  #ifdef SIGINFO
                    107:        SIGACTMASK(SIGINFO, siginfo_handler);
                    108: diff --git a/socket.c b/socket.c
                    109: --- a/socket.c
                    110: +++ b/socket.c
                    111: @@ -522,7 +522,17 @@ int is_a_socket(int fd)
                    112:  static void sigchld_handler(UNUSED(int val))
                    113:  {
                    114:  #ifdef WNOHANG
                    115: -      while (waitpid(-1, NULL, WNOHANG) > 0) {}
                    116: +      int status;
                    117: +      while (waitpid(-1, &status, WNOHANG) > 0) {
                    118: +              if (WIFSIGNALED(status)) {
                    119: +                      rprintf(FLOG,
                    120: +                              "rsync error: (3) Child proccess has unexpectedly died with signal %d\n",
                    121: +                              WTERMSIG(status));
                    122: +              } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) {
                    123: +                      rprintf(FLOG,
                    124: +                              "rsync error: (3) Child proccess has CRASHED.\n");
                    125: +              }
                    126: +      }
                    127:  #endif
                    128:  #ifndef HAVE_SIGACTION
                    129:        signal(SIGCHLD, sigchld_handler);

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>