Annotation of embedaddon/rsync/patches/catch_crash_signals.diff, revision 1.1.1.1
1.1 misho 1: Igor 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:
19: I'm not sure I like this, but if you run into the cygwin problem, this might
20: prove helpful.
21:
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:
28: based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
29: diff --git a/errcode.h b/errcode.h
30: --- a/errcode.h
31: +++ b/errcode.h
32: @@ -47,6 +47,8 @@
33: #define RERR_TIMEOUT 30 /* timeout in data send/receive */
34: #define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */
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: *
41: diff --git a/log.c b/log.c
42: --- a/log.c
43: +++ b/log.c
44: @@ -92,6 +92,7 @@ struct {
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" },
51: { RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" },
52: diff --git a/main.c b/main.c
53: --- a/main.c
54: +++ b/main.c
55: @@ -214,8 +214,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
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:
67: void write_del_stats(int f)
68: @@ -1629,6 +1632,14 @@ void remember_children(UNUSED(int val))
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
83: @@ -1684,6 +1695,12 @@ static void rsync_panic_handler(UNUSED(int whatsig))
84: }
85: #endif
86:
87: +static void 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: {
96: @@ -1708,6 +1725,11 @@ int main(int argc,char *argv[])
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: #ifdef SIGINFO
107: SIGACTMASK(SIGINFO, siginfo_handler);
108: diff --git a/socket.c b/socket.c
109: --- a/socket.c
110: +++ b/socket.c
111: @@ -522,7 +522,17 @@ int is_a_socket(int fd)
112: static void 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);
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>