1Igor 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 19I'm not sure I like this, but if you run into the cygwin problem, this might 20prove helpful. 21 22To 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--- old/errcode.h 29+++ new/errcode.h 30@@ -47,6 +47,8 @@ 31 32 #define RERR_TIMEOUT 30 /* timeout in data send/receive */ 33 34+#define RERR_WECRASHED 50 /* We have crashed. */ 35+ 36 /* Although it doesn't seem to be specified anywhere, 37 * ssh and the shell seem to return these values: 38 * 39--- old/log.c 40+++ new/log.c 41@@ -77,6 +77,7 @@ struct { 42 { RERR_TERMINATED , "sibling process terminated abnormally" }, 43 { RERR_SIGNAL1 , "received SIGUSR1" }, 44 { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, 45+ { RERR_WECRASHED , "rsync caught a CRASH-causing signal" }, 46 { RERR_WAITCHILD , "waitpid() failed" }, 47 { RERR_MALLOC , "error allocating core memory buffers" }, 48 { RERR_PARTIAL , "some files could not be transferred" }, 49--- old/main.c 50+++ new/main.c 51@@ -149,8 +149,11 @@ static void wait_process_with_flush(pid_ 52 *exit_code_ptr = RERR_TERMINATED; 53 else 54 *exit_code_ptr = RERR_WAITCHILD; 55- } else 56+ } else { 57 *exit_code_ptr = WEXITSTATUS(status); 58+ if (*exit_code_ptr == RERR_WECRASHED) 59+ *exit_code_ptr = RERR_CRASHED; 60+ } 61 } 62 63 /* This function gets called from all 3 processes. We want the client side 64@@ -1211,6 +1214,14 @@ RETSIGTYPE remember_children(UNUSED(int 65 break; 66 } 67 } 68+ if (WIFSIGNALED(status)) { 69+ rprintf(FLOG, 70+ "rsync error: (1) Child proccess has unexpectedly died with signal %d\n", 71+ WTERMSIG(status)); 72+ } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { 73+ rprintf(FLOG, 74+ "rsync error: (1) Child proccess has CRASHED.\n"); 75+ } 76 } 77 #endif 78 #ifndef HAVE_SIGACTION 79@@ -1269,6 +1280,12 @@ static RETSIGTYPE rsync_panic_handler(UN 80 } 81 #endif 82 83+static RETSIGTYPE rsync_crash_handler(UNUSED(int whatsig)) 84+{ 85+ log_exit(RERR_WECRASHED, __FILE__, __LINE__); 86+ logfile_close(); 87+ _exit(RERR_WECRASHED); 88+} 89 90 int main(int argc,char *argv[]) 91 { 92@@ -1291,6 +1308,11 @@ int main(int argc,char *argv[]) 93 SIGACTMASK(SIGFPE, rsync_panic_handler); 94 SIGACTMASK(SIGABRT, rsync_panic_handler); 95 SIGACTMASK(SIGBUS, rsync_panic_handler); 96+#else 97+ SIGACTMASK(SIGSEGV, rsync_crash_handler); 98+ SIGACTMASK(SIGFPE, rsync_crash_handler); 99+ SIGACTMASK(SIGABRT, rsync_crash_handler); 100+ SIGACTMASK(SIGBUS, rsync_crash_handler); 101 #endif 102 103 starttime = time(NULL); 104--- old/socket.c 105+++ new/socket.c 106@@ -454,7 +454,17 @@ int is_a_socket(int fd) 107 static RETSIGTYPE sigchld_handler(UNUSED(int val)) 108 { 109 #ifdef WNOHANG 110- while (waitpid(-1, NULL, WNOHANG) > 0) {} 111+ int status; 112+ while (waitpid(-1, &status, WNOHANG) > 0) { 113+ if (WIFSIGNALED(status)) { 114+ rprintf(FLOG, 115+ "rsync error: (3) Child proccess has unexpectedly died with signal %d\n", 116+ WTERMSIG(status)); 117+ } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { 118+ rprintf(FLOG, 119+ "rsync error: (3) Child proccess has CRASHED.\n"); 120+ } 121+ } 122 #endif 123 #ifndef HAVE_SIGACTION 124 signal(SIGCHLD, sigchld_handler); 125