Moved some misplaced code.
[rsync/rsync-patches.git] / catch_crash_signals.diff
CommitLineData
ae5c7864
WD
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
03019e41
WD
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
ae5c7864
WD
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
f2376a08 41@@ -79,6 +79,7 @@ struct {
ae5c7864
WD
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
f2376a08 51@@ -155,8 +155,11 @@ static void wait_process_with_flush(pid_
ae5c7864
WD
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
f2376a08 64@@ -1234,6 +1237,14 @@ RETSIGTYPE remember_children(UNUSED(int
ae5c7864
WD
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
f2376a08 79@@ -1292,6 +1303,12 @@ static RETSIGTYPE rsync_panic_handler(UN
ae5c7864
WD
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 {
f2376a08 92@@ -1314,6 +1331,11 @@ int main(int argc,char *argv[])
ae5c7864
WD
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
03019e41 106@@ -454,7 +454,17 @@ int is_a_socket(int fd)
ae5c7864
WD
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);