21 #if defined(USE_UNIX_SIGNAL_HANDLING)
23 #ifdef USE_UNIX_BACKTRACE_SUPPORT
34 #include <sys/types.h>
38 #if defined(__linux__) && defined(REG_ERR)
39 #include <sys/syscall.h>
42 #if defined(__APPLE__)
43 # define _XOPEN_SOURCE
44 # include <ucontext.h>
47 #elif !defined(__OpenBSD__) && !defined(__HAIKU__)
48 # include <ucontext.h>
52 #ifdef __USE_DYNAMIC_STACK_SIZE
53 static constexpr
size_t MYSTACKSIZE = 16*1024+32768;
55 static constexpr
size_t MYSTACKSIZE = 16*1024+SIGSTKSZ;
57 static char mytstack[MYSTACKSIZE]= {0};
58 static bool bStackBelowHeap=
false;
59 static FILE* signalOutput = stdout;
61 void set_signal_handler_output(FILE* f)
71 static bool IsAddressOnStack(
const void* ptr)
87 #define DECLARE_SIGNAL(x) std::make_pair(x, #x)
88 using Signalmap_t = std::map<int, std::string>;
89 static const Signalmap_t listofsignals = {
90 DECLARE_SIGNAL(SIGABRT),
91 DECLARE_SIGNAL(SIGBUS),
92 DECLARE_SIGNAL(SIGFPE),
93 DECLARE_SIGNAL(SIGILL),
94 DECLARE_SIGNAL(SIGINT),
95 DECLARE_SIGNAL(SIGQUIT),
96 DECLARE_SIGNAL(SIGSEGV),
97 DECLARE_SIGNAL(SIGSYS),
99 DECLARE_SIGNAL(SIGUSR1),
102 #undef DECLARE_SIGNAL
111 static void CppcheckSignalHandler(
int signo, siginfo_t * info,
void * context)
116 #if defined(__linux__) && defined(REG_ERR)
117 const auto*
const uc =
reinterpret_cast<const ucontext_t*
>(context);
118 killid = (pid_t) syscall(SYS_gettid);
120 type = (int)uc->uc_mcontext.gregs[REG_ERR] & 2;
127 const Signalmap_t::const_iterator it=listofsignals.find(signo);
128 const char *
const signame = (it==listofsignals.end()) ?
"unknown" : it->second.c_str();
129 bool unexpectedSignal=
true;
131 const bool isAddressOnStack = IsAddressOnStack(info->si_addr);
132 FILE *
const output = signalOutput;
135 fputs(
"Internal error: cppcheck received signal ", output);
136 fputs(signame, output);
141 " - abort or assertion\n",
146 fputs(
"Internal error: cppcheck received signal ", output);
147 fputs(signame, output);
148 switch (info->si_code) {
150 fputs(
" - BUS_ADRALN", output);
153 fputs(
" - BUS_ADRERR", output);
156 fputs(
" - BUS_OBJERR", output);
160 fputs(
" - BUS_MCEERR_AR", output);
165 fputs(
" - BUS_MCEERR_AO", output);
171 fprintf(output,
" (at 0x%lx).\n",
172 (
unsigned long)info->si_addr);
175 fputs(
"Internal error: cppcheck received signal ", output);
176 fputs(signame, output);
177 switch (info->si_code) {
179 fputs(
" - FPE_INTDIV", output);
182 fputs(
" - FPE_INTOVF", output);
185 fputs(
" - FPE_FLTDIV", output);
188 fputs(
" - FPE_FLTOVF", output);
191 fputs(
" - FPE_FLTUND", output);
194 fputs(
" - FPE_FLTRES", output);
197 fputs(
" - FPE_FLTINV", output);
200 fputs(
" - FPE_FLTSUB", output);
205 fprintf(output,
" (at 0x%lx).\n",
206 (
unsigned long)info->si_addr);
209 fputs(
"Internal error: cppcheck received signal ", output);
210 fputs(signame, output);
211 switch (info->si_code) {
213 fputs(
" - ILL_ILLOPC", output);
216 fputs(
" - ILL_ILLOPN", output);
219 fputs(
" - ILL_ILLADR", output);
222 fputs(
" - ILL_ILLTRP", output);
225 fputs(
" - ILL_PRVOPC", output);
228 fputs(
" - ILL_PRVREG", output);
231 fputs(
" - ILL_COPROC", output);
234 fputs(
" - ILL_BADSTK", output);
239 fprintf(output,
" (at 0x%lx).%s\n",
240 (
unsigned long)info->si_addr,
241 (isAddressOnStack)?
" Stackoverflow?":
"");
244 unexpectedSignal=
false;
245 fputs(
"cppcheck received signal ", output);
246 fputs(signame, output);
247 fputs(
".\n", output);
250 fputs(
"Internal error: cppcheck received signal ", output);
251 fputs(signame, output);
252 switch (info->si_code) {
254 fputs(
" - SEGV_MAPERR", output);
257 fputs(
" - SEGV_ACCERR", output);
262 fprintf(output,
" (%sat 0x%lx).%s\n",
265 (type==0) ?
"reading " :
"writing ",
266 (
unsigned long)info->si_addr,
267 (isAddressOnStack)?
" Stackoverflow?":
""
271 fputs(
"cppcheck received signal ", output);
272 fputs(signame, output);
273 fputs(
".\n", output);
277 fputs(
"Internal error: cppcheck received signal ", output);
278 fputs(signame, output);
279 fputs(
".\n", output);
282 #ifdef USE_UNIX_BACKTRACE_SUPPORT
285 print_stacktrace(output, 1,
true, -1,
true);
287 if (unexpectedSignal) {
288 fputs(
"\nPlease report this to the cppcheck developers!\n", output);
294 struct sigaction act;
295 memset(&act, 0,
sizeof(act));
296 act.sa_handler=SIG_DFL;
297 sigaction(signo, &act,
nullptr);
302 void register_signal_handler()
304 FILE *
const output = signalOutput;
308 char *heapVariable=
static_cast<char*
>(malloc(1));
309 bStackBelowHeap = &stackVariable < heapVariable;
314 segv_stack.ss_sp = mytstack;
315 segv_stack.ss_flags = 0;
316 segv_stack.ss_size = MYSTACKSIZE;
317 if (sigaltstack(&segv_stack,
nullptr) != 0) {
319 fputs(
"could not set alternate signal stack context.\n", output);
320 std::exit(EXIT_FAILURE);
324 struct sigaction act;
325 memset(&act, 0,
sizeof(act));
326 act.sa_flags=SA_SIGINFO|SA_ONSTACK;
327 act.sa_sigaction=CppcheckSignalHandler;
328 for (std::map<int, std::string>::const_iterator sig=listofsignals.cbegin(); sig!=listofsignals.cend(); ++sig) {
329 sigaction(sig->first, &act,
nullptr);