Commit | Line | Data |
---|---|---|
ae5c7864 | 1 | Igor Yu. Zhbanov wrote: |
e2e42a01 | 2 | > I am using rsync compiled with Cygwin on windows. |
ae5c7864 WD |
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.) | |
e2e42a01 | 9 | > |
ae5c7864 WD |
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. | |
e2e42a01 | 15 | > |
ae5c7864 WD |
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 | ||
03019e41 WD |
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 | ||
cc3e685d WD |
28 | diff --git a/errcode.h b/errcode.h |
29 | --- a/errcode.h | |
30 | +++ b/errcode.h | |
ae5c7864 | 31 | @@ -47,6 +47,8 @@ |
ae5c7864 | 32 | #define RERR_TIMEOUT 30 /* timeout in data send/receive */ |
cc3e685d | 33 | #define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */ |
ae5c7864 WD |
34 | |
35 | +#define RERR_WECRASHED 50 /* We have crashed. */ | |
36 | + | |
37 | /* Although it doesn't seem to be specified anywhere, | |
38 | * ssh and the shell seem to return these values: | |
39 | * | |
cc3e685d WD |
40 | diff --git a/log.c b/log.c |
41 | --- a/log.c | |
42 | +++ b/log.c | |
7f0bf1cb | 43 | @@ -83,6 +83,7 @@ struct { |
ae5c7864 WD |
44 | { RERR_TERMINATED , "sibling process terminated abnormally" }, |
45 | { RERR_SIGNAL1 , "received SIGUSR1" }, | |
46 | { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, | |
47 | + { RERR_WECRASHED , "rsync caught a CRASH-causing signal" }, | |
48 | { RERR_WAITCHILD , "waitpid() failed" }, | |
49 | { RERR_MALLOC , "error allocating core memory buffers" }, | |
4c107044 | 50 | { RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" }, |
cc3e685d WD |
51 | diff --git a/main.c b/main.c |
52 | --- a/main.c | |
53 | +++ b/main.c | |
4c107044 | 54 | @@ -163,8 +163,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr) |
ae5c7864 WD |
55 | *exit_code_ptr = RERR_TERMINATED; |
56 | else | |
57 | *exit_code_ptr = RERR_WAITCHILD; | |
58 | - } else | |
59 | + } else { | |
60 | *exit_code_ptr = WEXITSTATUS(status); | |
61 | + if (*exit_code_ptr == RERR_WECRASHED) | |
62 | + *exit_code_ptr = RERR_CRASHED; | |
63 | + } | |
64 | } | |
65 | ||
66 | /* This function gets called from all 3 processes. We want the client side | |
4c107044 | 67 | @@ -1315,6 +1318,14 @@ RETSIGTYPE remember_children(UNUSED(int val)) |
ae5c7864 WD |
68 | break; |
69 | } | |
70 | } | |
71 | + if (WIFSIGNALED(status)) { | |
72 | + rprintf(FLOG, | |
73 | + "rsync error: (1) Child proccess has unexpectedly died with signal %d\n", | |
74 | + WTERMSIG(status)); | |
75 | + } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { | |
76 | + rprintf(FLOG, | |
77 | + "rsync error: (1) Child proccess has CRASHED.\n"); | |
78 | + } | |
79 | } | |
80 | #endif | |
81 | #ifndef HAVE_SIGACTION | |
4c107044 | 82 | @@ -1373,6 +1384,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig)) |
ae5c7864 WD |
83 | } |
84 | #endif | |
85 | ||
86 | +static RETSIGTYPE rsync_crash_handler(UNUSED(int whatsig)) | |
87 | +{ | |
88 | + log_exit(RERR_WECRASHED, __FILE__, __LINE__); | |
89 | + logfile_close(); | |
90 | + _exit(RERR_WECRASHED); | |
91 | +} | |
92 | ||
93 | int main(int argc,char *argv[]) | |
94 | { | |
4c107044 | 95 | @@ -1395,6 +1412,11 @@ int main(int argc,char *argv[]) |
ae5c7864 WD |
96 | SIGACTMASK(SIGFPE, rsync_panic_handler); |
97 | SIGACTMASK(SIGABRT, rsync_panic_handler); | |
98 | SIGACTMASK(SIGBUS, rsync_panic_handler); | |
99 | +#else | |
100 | + SIGACTMASK(SIGSEGV, rsync_crash_handler); | |
101 | + SIGACTMASK(SIGFPE, rsync_crash_handler); | |
102 | + SIGACTMASK(SIGABRT, rsync_crash_handler); | |
103 | + SIGACTMASK(SIGBUS, rsync_crash_handler); | |
104 | #endif | |
105 | ||
106 | starttime = time(NULL); | |
cc3e685d WD |
107 | diff --git a/socket.c b/socket.c |
108 | --- a/socket.c | |
109 | +++ b/socket.c | |
e66d6d51 | 110 | @@ -518,7 +518,17 @@ int is_a_socket(int fd) |
ae5c7864 WD |
111 | static RETSIGTYPE sigchld_handler(UNUSED(int val)) |
112 | { | |
113 | #ifdef WNOHANG | |
114 | - while (waitpid(-1, NULL, WNOHANG) > 0) {} | |
115 | + int status; | |
116 | + while (waitpid(-1, &status, WNOHANG) > 0) { | |
117 | + if (WIFSIGNALED(status)) { | |
118 | + rprintf(FLOG, | |
119 | + "rsync error: (3) Child proccess has unexpectedly died with signal %d\n", | |
120 | + WTERMSIG(status)); | |
121 | + } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { | |
122 | + rprintf(FLOG, | |
123 | + "rsync error: (3) Child proccess has CRASHED.\n"); | |
124 | + } | |
125 | + } | |
126 | #endif | |
127 | #ifndef HAVE_SIGACTION | |
128 | signal(SIGCHLD, sigchld_handler); |