3 * Author: Mingqiang Zhuang
5 * Created on March 15, 2009
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
23 #include "ms_memslap.h"
24 #include "ms_setting.h"
26 #if defined(__cplusplus) && defined(HAVE_ABI_CXA_DEMANGLE)
33 # define SIGSEGV_STACK_IA64
34 # define REGFORMAT "%016lx"
35 #elif defined(REG_EIP)
36 # define SIGSEGV_STACK_X86
37 # define REGFORMAT "%08x"
39 # define SIGSEGV_STACK_GENERIC
40 # define REGFORMAT "%x"
44 int ms_setup_sigsegv(void);
45 int ms_setup_sigpipe(void);
46 int ms_setup_sigint(void);
49 /* signal seg reaches, this function will run */
50 static void ms_signal_segv(int signum
, siginfo_t
*info
, void *ptr
)
54 UNUSED_ARGUMENT(signum
);
55 UNUSED_ARGUMENT(info
);
58 pthread_mutex_lock(&ms_global
.quit_mutex
);
59 fprintf(stderr
, "Segmentation fault occurred.\n");
61 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
72 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
73 # if defined(SIGSEGV_STACK_IA64)
74 ip
= (void *)ucontext
->uc_mcontext
.gregs
[REG_RIP
];
75 bp
= (void **)ucontext
->uc_mcontext
.gregs
[REG_RBP
];
76 # elif defined(SIGSEGV_STACK_X86)
77 ip
= (void *)ucontext
->uc_mcontext
.gregs
[REG_EIP
];
78 bp
= (void **)ucontext
->uc_mcontext
.gregs
[REG_EBP
];
81 fprintf(stderr
, "Stack trace:\n");
84 if (! dladdr(ip
, &dlinfo
))
87 const char *symname
= dlinfo
.dli_sname
;
88 # if defined(HAVE_ABI_CXA_DEMANGLE) && defined(__cplusplus)
90 char *tmp
= __cxa_demangle(symname
, NULL
, 0, &status
);
92 if ((status
== 0) && tmp
)
96 fprintf(stderr
, "% 2d: %p <%s+%u> (%s)\n",
100 (unsigned)(ip
- dlinfo
.dli_saddr
),
103 # if defined(HAVE_ABI_CXA_DEMANGLE) && defined(__cplusplus)
108 if (dlinfo
.dli_sname
&& ! strcmp(dlinfo
.dli_sname
, "main"))
115 fprintf(stderr
, "Stack trace:\n");
116 sz
= backtrace(bt
, 20);
117 strings
= backtrace_symbols(bt
, sz
);
119 for (i
= 0; i
< sz
; ++i
)
121 fprintf(stderr
, "%s\n", strings
[i
]);
124 fprintf(stderr
, "End of stack trace\n");
125 pthread_mutex_unlock(&ms_global
.quit_mutex
);
127 } /* ms_signal_segv */
130 /* signal pipe reaches, this function will run */
131 static void ms_signal_pipe(int signum
, siginfo_t
*info
, void *ptr
)
133 UNUSED_ARGUMENT(signum
);
134 UNUSED_ARGUMENT(info
);
135 UNUSED_ARGUMENT(ptr
);
137 pthread_mutex_lock(&ms_global
.quit_mutex
);
138 fprintf(stderr
, "\tMemslap encountered a server error. Quitting...\n");
139 fprintf(stderr
, "\tError info: SIGPIPE captured (from write?)\n");
141 "\tProbably a socket I/O error when the server is down.\n");
142 pthread_mutex_unlock(&ms_global
.quit_mutex
);
144 } /* ms_signal_pipe */
147 /* signal int reaches, this function will run */
148 static void ms_signal_int(int signum
, siginfo_t
*info
, void *ptr
)
150 UNUSED_ARGUMENT(signum
);
151 UNUSED_ARGUMENT(info
);
152 UNUSED_ARGUMENT(ptr
);
154 pthread_mutex_lock(&ms_global
.quit_mutex
);
155 fprintf(stderr
, "SIGINT handled.\n");
156 pthread_mutex_unlock(&ms_global
.quit_mutex
);
158 } /* ms_signal_int */
162 * redirect signal seg
164 * @return if success, return 0, else return -1
166 int ms_setup_sigsegv(void)
168 struct sigaction action
;
170 memset(&action
, 0, sizeof(action
));
171 action
.sa_sigaction
= ms_signal_segv
;
172 action
.sa_flags
= SA_SIGINFO
;
173 if (sigaction(SIGSEGV
, &action
, NULL
) < 0)
180 } /* ms_setup_sigsegv */
184 * redirect signal pipe
186 * @return if success, return 0, else return -1
188 int ms_setup_sigpipe(void)
190 struct sigaction action_2
;
192 memset(&action_2
, 0, sizeof(action_2
));
193 action_2
.sa_sigaction
= ms_signal_pipe
;
194 action_2
.sa_flags
= SA_SIGINFO
;
195 if (sigaction(SIGPIPE
, &action_2
, NULL
) < 0)
202 } /* ms_setup_sigpipe */
206 * redirect signal int
208 * @return if success, return 0, else return -1
210 int ms_setup_sigint(void)
212 struct sigaction action_3
;
214 memset(&action_3
, 0, sizeof(action_3
));
215 action_3
.sa_sigaction
= ms_signal_int
;
216 action_3
.sa_flags
= SA_SIGINFO
;
217 if (sigaction(SIGINT
, &action_3
, NULL
) < 0)
224 } /* ms_setup_sigint */
227 #ifndef SIGSEGV_NO_AUTO_INIT
228 static void __attribute((constructor
)) ms_init(void)