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 | ||
72e5645e | 28 | based-on: 3b8f8192227b14e708bf535072485e50f4362270 |
cc3e685d WD |
29 | diff --git a/errcode.h b/errcode.h |
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 WD |
41 | diff --git a/log.c b/log.c |
42 | --- a/log.c | |
43 | +++ b/log.c | |
fc557362 | 44 | @@ -88,6 +88,7 @@ struct { |
ae5c7864 WD |
45 | { RERR_TERMINATED , "sibling process terminated abnormally" }, |
46 | { RERR_SIGNAL1 , "received SIGUSR1" }, | |
47 | { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, | |
48 | + { RERR_WECRASHED , "rsync caught a CRASH-causing signal" }, | |
49 | { RERR_WAITCHILD , "waitpid() failed" }, | |
50 | { RERR_MALLOC , "error allocating core memory buffers" }, | |
4c107044 | 51 | { RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" }, |
cc3e685d WD |
52 | diff --git a/main.c b/main.c |
53 | --- a/main.c | |
54 | +++ b/main.c | |
72e5645e | 55 | @@ -175,8 +175,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr) |
ae5c7864 WD |
56 | *exit_code_ptr = RERR_TERMINATED; |
57 | else | |
58 | *exit_code_ptr = RERR_WAITCHILD; | |
59 | - } else | |
60 | + } else { | |
61 | *exit_code_ptr = WEXITSTATUS(status); | |
62 | + if (*exit_code_ptr == RERR_WECRASHED) | |
63 | + *exit_code_ptr = RERR_CRASHED; | |
64 | + } | |
65 | } | |
66 | ||
fc557362 | 67 | void write_del_stats(int f) |
72e5645e | 68 | @@ -1407,6 +1410,14 @@ RETSIGTYPE remember_children(UNUSED(int val)) |
ae5c7864 WD |
69 | break; |
70 | } | |
71 | } | |
72 | + if (WIFSIGNALED(status)) { | |
73 | + rprintf(FLOG, | |
74 | + "rsync error: (1) Child proccess has unexpectedly died with signal %d\n", | |
75 | + WTERMSIG(status)); | |
76 | + } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { | |
77 | + rprintf(FLOG, | |
78 | + "rsync error: (1) Child proccess has CRASHED.\n"); | |
79 | + } | |
80 | } | |
81 | #endif | |
82 | #ifndef HAVE_SIGACTION | |
72e5645e | 83 | @@ -1465,6 +1476,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig)) |
ae5c7864 WD |
84 | } |
85 | #endif | |
86 | ||
87 | +static RETSIGTYPE rsync_crash_handler(UNUSED(int whatsig)) | |
88 | +{ | |
89 | + log_exit(RERR_WECRASHED, __FILE__, __LINE__); | |
90 | + logfile_close(); | |
91 | + _exit(RERR_WECRASHED); | |
92 | +} | |
93 | ||
94 | int main(int argc,char *argv[]) | |
95 | { | |
72e5645e | 96 | @@ -1487,6 +1504,11 @@ int main(int argc,char *argv[]) |
ae5c7864 WD |
97 | SIGACTMASK(SIGFPE, rsync_panic_handler); |
98 | SIGACTMASK(SIGABRT, rsync_panic_handler); | |
99 | SIGACTMASK(SIGBUS, rsync_panic_handler); | |
100 | +#else | |
101 | + SIGACTMASK(SIGSEGV, rsync_crash_handler); | |
102 | + SIGACTMASK(SIGFPE, rsync_crash_handler); | |
103 | + SIGACTMASK(SIGABRT, rsync_crash_handler); | |
104 | + SIGACTMASK(SIGBUS, rsync_crash_handler); | |
105 | #endif | |
106 | ||
107 | starttime = time(NULL); | |
cc3e685d WD |
108 | diff --git a/socket.c b/socket.c |
109 | --- a/socket.c | |
110 | +++ b/socket.c | |
e66d6d51 | 111 | @@ -518,7 +518,17 @@ int is_a_socket(int fd) |
ae5c7864 WD |
112 | static RETSIGTYPE sigchld_handler(UNUSED(int val)) |
113 | { | |
114 | #ifdef WNOHANG | |
115 | - while (waitpid(-1, NULL, WNOHANG) > 0) {} | |
116 | + int status; | |
117 | + while (waitpid(-1, &status, WNOHANG) > 0) { | |
118 | + if (WIFSIGNALED(status)) { | |
119 | + rprintf(FLOG, | |
120 | + "rsync error: (3) Child proccess has unexpectedly died with signal %d\n", | |
121 | + WTERMSIG(status)); | |
122 | + } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { | |
123 | + rprintf(FLOG, | |
124 | + "rsync error: (3) Child proccess has CRASHED.\n"); | |
125 | + } | |
126 | + } | |
127 | #endif | |
128 | #ifndef HAVE_SIGACTION | |
129 | signal(SIGCHLD, sigchld_handler); |