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