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 #define NO_CPP_DEMANGLE
27 #ifndef NO_CPP_DEMANGLE
34 # define SIGSEGV_STACK_IA64
35 # define REGFORMAT "%016lx"
36 #elif defined(REG_EIP)
37 # define SIGSEGV_STACK_X86
38 # define REGFORMAT "%08x"
40 # define SIGSEGV_STACK_GENERIC
41 # define REGFORMAT "%x"
45 int ms_setup_sigsegv(void);
46 int ms_setup_sigpipe(void);
47 int ms_setup_sigint(void);
50 /* signal seg reaches, this function will run */
51 static void ms_signal_segv(int signum
, siginfo_t
*info
, void *ptr
)
55 UNUSED_ARGUMENT(signum
);
56 UNUSED_ARGUMENT(info
);
59 pthread_mutex_lock(&ms_global
.quit_mutex
);
60 fprintf(stderr
, "Segmentation fault occurred.\n");
62 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
73 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
74 # if defined(SIGSEGV_STACK_IA64)
75 ip
= (void *)ucontext
->uc_mcontext
.gregs
[REG_RIP
];
76 bp
= (void **)ucontext
->uc_mcontext
.gregs
[REG_RBP
];
77 # elif defined(SIGSEGV_STACK_X86)
78 ip
= (void *)ucontext
->uc_mcontext
.gregs
[REG_EIP
];
79 bp
= (void **)ucontext
->uc_mcontext
.gregs
[REG_EBP
];
82 fprintf(stderr
, "Stack trace:\n");
85 if (! dladdr(ip
, &dlinfo
))
88 const char *symname
= dlinfo
.dli_sname
;
89 # ifndef NO_CPP_DEMANGLE
91 char *tmp
= __cxa_demangle(symname
, NULL
, 0, &status
);
93 if ((status
== 0) && tmp
)
97 fprintf(stderr
, "% 2d: %p <%s+%u> (%s)\n",
101 (unsigned)(ip
- dlinfo
.dli_saddr
),
104 # ifndef NO_CPP_DEMANGLE
109 if (dlinfo
.dli_sname
&& ! strcmp(dlinfo
.dli_sname
, "main"))
116 fprintf(stderr
, "Stack trace:\n");
117 sz
= backtrace(bt
, 20);
118 strings
= backtrace_symbols(bt
, sz
);
120 for (i
= 0; i
< sz
; ++i
)
122 fprintf(stderr
, "%s\n", strings
[i
]);
125 fprintf(stderr
, "End of stack trace\n");
126 pthread_mutex_unlock(&ms_global
.quit_mutex
);
128 } /* ms_signal_segv */
131 /* signal pipe reaches, this function will run */
132 static void ms_signal_pipe(int signum
, siginfo_t
*info
, void *ptr
)
134 UNUSED_ARGUMENT(signum
);
135 UNUSED_ARGUMENT(info
);
136 UNUSED_ARGUMENT(ptr
);
138 pthread_mutex_lock(&ms_global
.quit_mutex
);
139 fprintf(stderr
, "\tMemslap encountered a server error. Quitting...\n");
140 fprintf(stderr
, "\tError info: SIGPIPE captured (from write?)\n");
142 "\tProbably a socket I/O error when the server is down.\n");
143 pthread_mutex_unlock(&ms_global
.quit_mutex
);
145 } /* ms_signal_pipe */
148 /* signal int reaches, this function will run */
149 static void ms_signal_int(int signum
, siginfo_t
*info
, void *ptr
)
151 UNUSED_ARGUMENT(signum
);
152 UNUSED_ARGUMENT(info
);
153 UNUSED_ARGUMENT(ptr
);
155 pthread_mutex_lock(&ms_global
.quit_mutex
);
156 fprintf(stderr
, "SIGINT handled.\n");
157 pthread_mutex_unlock(&ms_global
.quit_mutex
);
159 } /* ms_signal_int */
163 * redirect signal seg
165 * @return if success, return 0, else return -1
167 int ms_setup_sigsegv(void)
169 struct sigaction action
;
171 memset(&action
, 0, sizeof(action
));
172 action
.sa_sigaction
= ms_signal_segv
;
173 action
.sa_flags
= SA_SIGINFO
;
174 if (sigaction(SIGSEGV
, &action
, NULL
) < 0)
181 } /* ms_setup_sigsegv */
185 * redirect signal pipe
187 * @return if success, return 0, else return -1
189 int ms_setup_sigpipe(void)
191 struct sigaction action_2
;
193 memset(&action_2
, 0, sizeof(action_2
));
194 action_2
.sa_sigaction
= ms_signal_pipe
;
195 action_2
.sa_flags
= SA_SIGINFO
;
196 if (sigaction(SIGPIPE
, &action_2
, NULL
) < 0)
203 } /* ms_setup_sigpipe */
207 * redirect signal int
209 * @return if success, return 0, else return -1
211 int ms_setup_sigint(void)
213 struct sigaction action_3
;
215 memset(&action_3
, 0, sizeof(action_3
));
216 action_3
.sa_sigaction
= ms_signal_int
;
217 action_3
.sa_flags
= SA_SIGINFO
;
218 if (sigaction(SIGINT
, &action_3
, NULL
) < 0)
225 } /* ms_setup_sigint */
228 #ifndef SIGSEGV_NO_AUTO_INIT
229 static void __attribute((constructor
)) ms_init(void)