rsync SIGSEGV signal handler in Cygwin.

Igor Yu. Zhbanov bsg at uniyar.ac.ru
Mon Feb 13 17:30:29 GMT 2006


Hello!

I am using rsync compiled with Cygwin on windows. 
I must call rsync from the *.bat script (I don't want to use a bash on Windows)
and I have noticed that in the case when program compiled by Cygwin crashes
via segmentation fault and default SIGSEGV handler is called, then it
terminates process with exit status 0 as I see it from my *.bat script.
(But if I invoke a program from bash (compiled with Cygwin too) I will see
error code 139 as expected.)

It is a Cygwin's problem, not an rsync's, but to use it on windows and
to distinguish situations when rsync crashes and when it exits normally,
I have written signal handler which terminates process with code 50.
You may use conventional 139. Also signal handler writes corresponding
message to log file.

By the way. When I terminate rsync in daemon mode by pressing Control-C,
it writes an error to log. May be this is not an error but info or notice?

This patch is for version 2.6.6 (if you interesting in it):

diff -ur rsync-2.6.6/errcode.h rsync/errcode.h
--- rsync-2.6.6/errcode.h	Wed Apr 13 03:04:10 2005
+++ rsync/errcode.h	Sat Jan 28 04:35:08 2006
@@ -44,6 +44,8 @@
 
 #define RERR_TIMEOUT    30      /* timeout in data send/receive */
 
+#define RERR_CRASH      50      /* We have crashed. */
+
 /* Although it doesn't seem to be specified anywhere,
  * ssh and the shell seem to return these values:
  *
diff -ur rsync-2.6.6/log.c rsync/log.c
--- rsync-2.6.6/log.c	Fri Jun 10 02:27:22 2005
+++ rsync/log.c	Sat Jan 28 04:37:10 2006
@@ -66,6 +66,7 @@
	{ RERR_MESSAGEIO  , "errors with program diagnostics" },
	{ RERR_IPC        , "error in IPC code" },
	{ RERR_SIGNAL     , "received SIGUSR1 or SIGINT" },
+	{ RERR_CRASH      , "*** WE HAVE CRASHED :-( ***" },
	{ RERR_WAITCHILD  , "some error returned by waitpid()" },
	{ RERR_MALLOC     , "error allocating core memory buffers" },
	{ RERR_PARTIAL    , "some files could not be transferred" },
diff -ur rsync-2.6.6/main.c rsync/main.c
--- rsync-2.6.6/main.c	Thu May 12 11:43:14 2005
+++ rsync/main.c	Sat Jan 28 06:29:06 2006
@@ -114,6 +114,14 @@
	 * message describing the purpose of the child.  Also indicate
	 * this to the caller so that thhey know something went
	 * wrong.  */
+	if (WIFSIGNALED(*status))
+		rprintf(FLOG,
+			"rsync error: (2) Child proccess has unexpectedly died with signal %d\n",
+			WTERMSIG(*status));
+	else if (WIFEXITED(*status) && WEXITSTATUS(*status) == RERR_CRASH)
+		rprintf(FLOG,
+			"rsync error: (2) *** Child proccess has crashed. :-( ***\n");
+
	*status = WEXITSTATUS(*status);
 }
 
@@ -1015,6 +1023,13 @@
				break;
			}
		}
+		if (WIFSIGNALED(status))
+			rprintf(FLOG,
+				"rsync error: (1) Child proccess has unexpectedly died with signal %d\n",
+				WTERMSIG(status));
+		else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_CRASH)
+			rprintf(FLOG,
+				"rsync error: (1) *** Child proccess has crashed. :-( ***\n");
	}
 #endif
 }
@@ -1070,6 +1085,12 @@
 }
 #endif
 
+static RETSIGTYPE rsync_panic_handler2(UNUSED(int whatsig))
+{
+  log_exit(RERR_CRASH, "main.c", -1);
+  logfile_close();
+  _exit(RERR_CRASH);
+}
 
 int main(int argc,char *argv[])
 {
@@ -1085,6 +1106,11 @@
	signal(SIGFPE, rsync_panic_handler);
	signal(SIGABRT, rsync_panic_handler);
	signal(SIGBUS, rsync_panic_handler);
+#else  /* !def MAINTAINER_MODE */
+	signal(SIGSEGV, rsync_panic_handler2);
+	signal(SIGFPE,  rsync_panic_handler2);
+	signal(SIGABRT, rsync_panic_handler2);
+	signal(SIGBUS,  rsync_panic_handler2);
 #endif /* def MAINTAINER_MODE */
 
	starttime = time(NULL);
diff -ur rsync-2.6.6/socket.c rsync/socket.c
--- rsync-2.6.6/socket.c	Thu Apr 14 20:08:12 2005
+++ rsync/socket.c	Sat Jan 28 06:29:20 2006
@@ -431,7 +431,16 @@
 static RETSIGTYPE sigchld_handler(UNUSED(int val))
 {
 #ifdef WNOHANG
-	while (waitpid(-1, NULL, WNOHANG) > 0) {}
+	int status;
+	while (waitpid(-1, &status, WNOHANG) > 0) {
+		if (WIFSIGNALED(status))
+			rprintf(FLOG,
+				"rsync error: (3) Child proccess has unexpectedly died with signal %d\n",
+				WTERMSIG(status));
+		else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_CRASH)
+			rprintf(FLOG,
+				"rsync error: (3) *** Child proccess has crashed. :-( ***\n");
+	}
 #endif
	signal(SIGCHLD, sigchld_handler);
 }
------------------ END -------------------------------------------------------


P.S. Since I'm not subscribed to this list, please send a copy to Reply.



More information about the rsync mailing list