Annotation of embedaddon/rsync/patches/catch_crash_signals.diff, revision 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>