3 * Author: Mingqiang Zhuang
5 * Created on March 15, 2009
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
20 #include "ms_memslap.h"
21 #include "ms_setting.h"
23 #define NO_CPP_DEMANGLE
24 #ifndef NO_CPP_DEMANGLE
31 # define SIGSEGV_STACK_IA64
32 # define REGFORMAT "%016lx"
33 #elif defined(REG_EIP)
34 # define SIGSEGV_STACK_X86
35 # define REGFORMAT "%08x"
37 # define SIGSEGV_STACK_GENERIC
38 # define REGFORMAT "%x"
42 int ms_setup_sigsegv(void);
43 int ms_setup_sigpipe(void);
44 int ms_setup_sigint(void);
47 /* signal seg reaches, this function will run */
48 static void ms_signal_segv(int signum
, siginfo_t
*info
, void *ptr
)
52 UNUSED_ARGUMENT(signum
);
53 UNUSED_ARGUMENT(info
);
56 pthread_mutex_lock(&ms_global
.quit_mutex
);
57 fprintf(stderr
, "Segmentation fault occurred.\n");
59 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
70 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
71 # if defined(SIGSEGV_STACK_IA64)
72 ip
= (void *)ucontext
->uc_mcontext
.gregs
[REG_RIP
];
73 bp
= (void **)ucontext
->uc_mcontext
.gregs
[REG_RBP
];
74 # elif defined(SIGSEGV_STACK_X86)
75 ip
= (void *)ucontext
->uc_mcontext
.gregs
[REG_EIP
];
76 bp
= (void **)ucontext
->uc_mcontext
.gregs
[REG_EBP
];
79 fprintf(stderr
, "Stack trace:\n");
82 if (! dladdr(ip
, &dlinfo
))
85 const char *symname
= dlinfo
.dli_sname
;
86 # ifndef NO_CPP_DEMANGLE
88 char *tmp
= __cxa_demangle(symname
, NULL
, 0, &status
);
90 if ((status
== 0) && tmp
)
94 fprintf(stderr
, "% 2d: %p <%s+%u> (%s)\n",
98 (unsigned)(ip
- dlinfo
.dli_saddr
),
101 # ifndef NO_CPP_DEMANGLE
106 if (dlinfo
.dli_sname
&& ! strcmp(dlinfo
.dli_sname
, "main"))
113 fprintf(stderr
, "Stack trace:\n");
114 sz
= backtrace(bt
, 20);
115 strings
= backtrace_symbols(bt
, sz
);
117 for (i
= 0; i
< sz
; ++i
)
119 fprintf(stderr
, "%s\n", strings
[i
]);
122 fprintf(stderr
, "End of stack trace\n");
123 pthread_mutex_unlock(&ms_global
.quit_mutex
);
125 } /* ms_signal_segv */
128 /* signal pipe reaches, this function will run */
129 static void ms_signal_pipe(int signum
, siginfo_t
*info
, void *ptr
)
131 UNUSED_ARGUMENT(signum
);
132 UNUSED_ARGUMENT(info
);
133 UNUSED_ARGUMENT(ptr
);
135 pthread_mutex_lock(&ms_global
.quit_mutex
);
136 fprintf(stderr
, "\tMemslap encountered a server error. Quitting...\n");
137 fprintf(stderr
, "\tError info: SIGPIPE captured (from write?)\n");
139 "\tProbably a socket I/O error when the server is down.\n");
140 pthread_mutex_unlock(&ms_global
.quit_mutex
);
142 } /* ms_signal_pipe */
145 /* signal int reaches, this function will run */
146 static void ms_signal_int(int signum
, siginfo_t
*info
, void *ptr
)
148 UNUSED_ARGUMENT(signum
);
149 UNUSED_ARGUMENT(info
);
150 UNUSED_ARGUMENT(ptr
);
152 pthread_mutex_lock(&ms_global
.quit_mutex
);
153 fprintf(stderr
, "SIGINT handled.\n");
154 pthread_mutex_unlock(&ms_global
.quit_mutex
);
156 } /* ms_signal_int */
160 * redirect signal seg
162 * @return if success, return 0, else return -1
164 int ms_setup_sigsegv(void)
166 struct sigaction action
;
168 memset(&action
, 0, sizeof(action
));
169 action
.sa_sigaction
= ms_signal_segv
;
170 action
.sa_flags
= SA_SIGINFO
;
171 if (sigaction(SIGSEGV
, &action
, NULL
) < 0)
178 } /* ms_setup_sigsegv */
182 * redirect signal pipe
184 * @return if success, return 0, else return -1
186 int ms_setup_sigpipe(void)
188 struct sigaction action_2
;
190 memset(&action_2
, 0, sizeof(action_2
));
191 action_2
.sa_sigaction
= ms_signal_pipe
;
192 action_2
.sa_flags
= SA_SIGINFO
;
193 if (sigaction(SIGPIPE
, &action_2
, NULL
) < 0)
200 } /* ms_setup_sigpipe */
204 * redirect signal int
206 * @return if success, return 0, else return -1
208 int ms_setup_sigint(void)
210 struct sigaction action_3
;
212 memset(&action_3
, 0, sizeof(action_3
));
213 action_3
.sa_sigaction
= ms_signal_int
;
214 action_3
.sa_flags
= SA_SIGINFO
;
215 if (sigaction(SIGINT
, &action_3
, NULL
) < 0)
222 } /* ms_setup_sigint */
225 #ifndef SIGSEGV_NO_AUTO_INIT
226 static void __attribute((constructor
)) ms_init(void)