Fix for bug #15450
[awesomized/libmemcached] / clients / ms_sigsegv.c
1 /*
2 * File: ms_sigsegv.c
3 * Author: Mingqiang Zhuang
4 *
5 * Created on March 15, 2009
6 *
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
9 *
10 * Rewrite of stack dump:
11 * Copyright (C) 2009 Sun Microsystems
12 * Author Trond Norbye
13 */
14
15 #include "config.h"
16
17 #include <memory.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <signal.h>
21 #include <pthread.h>
22
23 #include "ms_memslap.h"
24 #include "ms_setting.h"
25
26 /* prototypes */
27 int ms_setup_sigsegv(void);
28 int ms_setup_sigpipe(void);
29 int ms_setup_sigint(void);
30
31
32 /* signal seg reaches, this function will run */
33 static void ms_signal_segv(int signum, siginfo_t *info, void *ptr)
34 {
35 UNUSED_ARGUMENT(signum);
36 UNUSED_ARGUMENT(info);
37 UNUSED_ARGUMENT(ptr);
38
39 pthread_mutex_lock(&ms_global.quit_mutex);
40 fprintf(stderr, "Segmentation fault occurred.\nStack trace:\n");
41 pandora_print_callstack(stderr);
42 fprintf(stderr, "End of stack trace\n");
43 pthread_mutex_unlock(&ms_global.quit_mutex);
44 abort();
45 }
46
47 /* signal pipe reaches, this function will run */
48 static void ms_signal_pipe(int signum, siginfo_t *info, void *ptr)
49 {
50 UNUSED_ARGUMENT(signum);
51 UNUSED_ARGUMENT(info);
52 UNUSED_ARGUMENT(ptr);
53
54 pthread_mutex_lock(&ms_global.quit_mutex);
55 fprintf(stderr, "\tMemslap encountered a server error. Quitting...\n");
56 fprintf(stderr, "\tError info: SIGPIPE captured (from write?)\n");
57 fprintf(stderr,
58 "\tProbably a socket I/O error when the server is down.\n");
59 pthread_mutex_unlock(&ms_global.quit_mutex);
60 exit(1);
61 } /* ms_signal_pipe */
62
63
64 /* signal int reaches, this function will run */
65 static void ms_signal_int(int signum, siginfo_t *info, void *ptr)
66 {
67 UNUSED_ARGUMENT(signum);
68 UNUSED_ARGUMENT(info);
69 UNUSED_ARGUMENT(ptr);
70
71 pthread_mutex_lock(&ms_global.quit_mutex);
72 fprintf(stderr, "SIGINT handled.\n");
73 pthread_mutex_unlock(&ms_global.quit_mutex);
74 exit(1);
75 } /* ms_signal_int */
76
77
78 /**
79 * redirect signal seg
80 *
81 * @return if success, return 0, else return -1
82 */
83 int ms_setup_sigsegv(void)
84 {
85 struct sigaction action;
86
87 memset(&action, 0, sizeof(action));
88 action.sa_sigaction= ms_signal_segv;
89 action.sa_flags= SA_SIGINFO;
90 if (sigaction(SIGSEGV, &action, NULL) < 0)
91 {
92 perror("sigaction");
93 return 0;
94 }
95
96 return -1;
97 } /* ms_setup_sigsegv */
98
99
100 /**
101 * redirect signal pipe
102 *
103 * @return if success, return 0, else return -1
104 */
105 int ms_setup_sigpipe(void)
106 {
107 struct sigaction action_2;
108
109 memset(&action_2, 0, sizeof(action_2));
110 action_2.sa_sigaction= ms_signal_pipe;
111 action_2.sa_flags= SA_SIGINFO;
112 if (sigaction(SIGPIPE, &action_2, NULL) < 0)
113 {
114 perror("sigaction");
115 return 0;
116 }
117
118 return -1;
119 } /* ms_setup_sigpipe */
120
121
122 /**
123 * redirect signal int
124 *
125 * @return if success, return 0, else return -1
126 */
127 int ms_setup_sigint(void)
128 {
129 struct sigaction action_3;
130
131 memset(&action_3, 0, sizeof(action_3));
132 action_3.sa_sigaction= ms_signal_int;
133 action_3.sa_flags= SA_SIGINFO;
134 if (sigaction(SIGINT, &action_3, NULL) < 0)
135 {
136 perror("sigaction");
137 return 0;
138 }
139
140 return -1;
141 } /* ms_setup_sigint */
142
143
144 #ifndef SIGSEGV_NO_AUTO_INIT
145 static void __attribute((constructor)) ms_init(void)
146 {
147 ms_setup_sigsegv();
148 ms_setup_sigpipe();
149 ms_setup_sigint();
150 }
151 #endif