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);
46 /* signal seg reaches, this function will run */
47 static void ms_signal_segv(int signum
, siginfo_t
* info
, void * ptr
) {
50 UNUSED_ARGUMENT(signum
);
51 UNUSED_ARGUMENT(info
);
54 pthread_mutex_lock(&ms_global
.quit_mutex
);
55 fprintf(stderr
, "Segmentation fault occurred.\n");
57 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
68 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
69 #if defined(SIGSEGV_STACK_IA64)
70 ip
= (void*)ucontext
->uc_mcontext
.gregs
[REG_RIP
];
71 bp
= (void**)ucontext
->uc_mcontext
.gregs
[REG_RBP
];
72 #elif defined(SIGSEGV_STACK_X86)
73 ip
= (void*)ucontext
->uc_mcontext
.gregs
[REG_EIP
];
74 bp
= (void**)ucontext
->uc_mcontext
.gregs
[REG_EBP
];
77 fprintf(stderr
, "Stack trace:\n");
79 if(!dladdr(ip
, &dlinfo
))
82 const char *symname
= dlinfo
.dli_sname
;
83 #ifndef NO_CPP_DEMANGLE
85 char *tmp
= __cxa_demangle(symname
, NULL
, 0, &status
);
87 if(status
== 0 && tmp
)
91 fprintf(stderr
, "% 2d: %p <%s+%u> (%s)\n",
95 (unsigned)(ip
- dlinfo
.dli_saddr
),
98 #ifndef NO_CPP_DEMANGLE
103 if(dlinfo
.dli_sname
&& !strcmp(dlinfo
.dli_sname
, "main"))
110 fprintf(stderr
, "Stack trace:\n");
111 sz
= backtrace(bt
, 20);
112 strings
= backtrace_symbols(bt
, sz
);
114 for(i
= 0; i
< sz
; ++i
)
115 fprintf(stderr
, "%s\n", strings
[i
]);
117 fprintf(stderr
, "End of stack trace\n");
118 pthread_mutex_unlock(&ms_global
.quit_mutex
);
122 /* signal pipe reaches, this function will run */
123 static void ms_signal_pipe(int signum
, siginfo_t
* info
, void*ptr
)
125 UNUSED_ARGUMENT(signum
);
126 UNUSED_ARGUMENT(info
);
127 UNUSED_ARGUMENT(ptr
);
129 pthread_mutex_lock(&ms_global
.quit_mutex
);
130 fprintf(stderr
, "\tMemslap encountered a server error. Quitting...\n");
131 fprintf(stderr
, "\tError info: SIGPIPE captured (from write?)\n");
132 fprintf(stderr
, "\tProbably a socket I/O error when the server is down.\n");
133 pthread_mutex_unlock(&ms_global
.quit_mutex
);
137 /* signal int reaches, this function will run */
138 static void ms_signal_int(int signum
, siginfo_t
* info
, void*ptr
)
140 UNUSED_ARGUMENT(signum
);
141 UNUSED_ARGUMENT(info
);
142 UNUSED_ARGUMENT(ptr
);
144 pthread_mutex_lock(&ms_global
.quit_mutex
);
145 fprintf(stderr
, "SIGINT handled.\n");
146 pthread_mutex_unlock(&ms_global
.quit_mutex
);
151 * redirect signal seg
153 * @return if success, return 0, else return -1
155 int ms_setup_sigsegv(void) {
156 struct sigaction action
;
157 memset(&action
, 0, sizeof(action
));
158 action
.sa_sigaction
= ms_signal_segv
;
159 action
.sa_flags
= SA_SIGINFO
;
160 if(sigaction(SIGSEGV
, &action
, NULL
) < 0) {
169 * redirect signal pipe
171 * @return if success, return 0, else return -1
173 int ms_setup_sigpipe(void)
175 struct sigaction action_2
;
176 memset(&action_2
, 0, sizeof(action_2
));
177 action_2
.sa_sigaction
= ms_signal_pipe
;
178 action_2
.sa_flags
= SA_SIGINFO
;
179 if(sigaction(SIGPIPE
, &action_2
, NULL
) < 0) {
188 * redirect signal int
190 * @return if success, return 0, else return -1
192 int ms_setup_sigint(void)
194 struct sigaction action_3
;
195 memset(&action_3
, 0, sizeof(action_3
));
196 action_3
.sa_sigaction
= ms_signal_int
;
197 action_3
.sa_flags
= SA_SIGINFO
;
198 if(sigaction(SIGINT
, &action_3
, NULL
) < 0) {
206 #ifndef SIGSEGV_NO_AUTO_INIT
207 static void __attribute((constructor
)) ms_init(void) {