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