21 #if defined(USE_UNIX_SIGNAL_HANDLING)
25 #ifdef USE_UNIX_BACKTRACE_SUPPORT
39 #if defined(__linux__) && defined(REG_ERR)
40 #include <sys/syscall.h>
43 #if defined(__APPLE__)
44 # define _XOPEN_SOURCE
45 # include <ucontext.h>
48 #elif !defined(__OpenBSD__) && !defined(__HAIKU__)
49 # include <ucontext.h>
53 #ifdef __USE_DYNAMIC_STACK_SIZE
54 static constexpr
size_t MYSTACKSIZE = 16*1024+32768;
56 static constexpr
size_t MYSTACKSIZE = 16*1024+SIGSTKSZ;
58 static char mytstack[MYSTACKSIZE]= {0};
59 static bool bStackBelowHeap=
false;
66 static bool IsAddressOnStack(
const void* ptr)
82 #define DECLARE_SIGNAL(x) std::make_pair(x, #x)
83 using Signalmap_t = std::map<int, std::string>;
84 static const Signalmap_t listofsignals = {
85 DECLARE_SIGNAL(SIGABRT),
86 DECLARE_SIGNAL(SIGBUS),
87 DECLARE_SIGNAL(SIGFPE),
88 DECLARE_SIGNAL(SIGILL),
89 DECLARE_SIGNAL(SIGINT),
90 DECLARE_SIGNAL(SIGQUIT),
91 DECLARE_SIGNAL(SIGSEGV),
92 DECLARE_SIGNAL(SIGSYS),
94 DECLARE_SIGNAL(SIGUSR1),
106 static void CppcheckSignalHandler(
int signo, siginfo_t * info,
void * context)
111 #if defined(__linux__) && defined(REG_ERR)
112 const auto*
const uc =
reinterpret_cast<const ucontext_t*
>(context);
113 killid = (pid_t) syscall(SYS_gettid);
115 type = (int)uc->uc_mcontext.gregs[REG_ERR] & 2;
122 const Signalmap_t::const_iterator it=listofsignals.find(signo);
123 const char *
const signame = (it==listofsignals.end()) ?
"unknown" : it->second.c_str();
124 #ifdef USE_UNIX_BACKTRACE_SUPPORT
127 bool unexpectedSignal=
true;
129 const bool isAddressOnStack = IsAddressOnStack(info->si_addr);
133 fputs(
"Internal error: cppcheck received signal ", output);
134 fputs(signame, output);
137 " - out of memory?\n",
139 " - out of memory or assertion?\n",
142 #ifdef USE_UNIX_BACKTRACE_SUPPORT
147 fputs(
"Internal error: cppcheck received signal ", output);
148 fputs(signame, output);
149 switch (info->si_code) {
151 fputs(
" - BUS_ADRALN", output);
154 fputs(
" - BUS_ADRERR", output);
157 fputs(
" - BUS_OBJERR", output);
161 fputs(
" - BUS_MCEERR_AR", output);
166 fputs(
" - BUS_MCEERR_AO", output);
172 fprintf(output,
" (at 0x%lx).\n",
173 (
unsigned long)info->si_addr);
176 fputs(
"Internal error: cppcheck received signal ", output);
177 fputs(signame, output);
178 switch (info->si_code) {
180 fputs(
" - FPE_INTDIV", output);
183 fputs(
" - FPE_INTOVF", output);
186 fputs(
" - FPE_FLTDIV", output);
189 fputs(
" - FPE_FLTOVF", output);
192 fputs(
" - FPE_FLTUND", output);
195 fputs(
" - FPE_FLTRES", output);
198 fputs(
" - FPE_FLTINV", output);
201 fputs(
" - FPE_FLTSUB", output);
206 fprintf(output,
" (at 0x%lx).\n",
207 (
unsigned long)info->si_addr);
210 fputs(
"Internal error: cppcheck received signal ", output);
211 fputs(signame, output);
212 switch (info->si_code) {
214 fputs(
" - ILL_ILLOPC", output);
217 fputs(
" - ILL_ILLOPN", output);
220 fputs(
" - ILL_ILLADR", output);
223 fputs(
" - ILL_ILLTRP", output);
226 fputs(
" - ILL_PRVOPC", output);
229 fputs(
" - ILL_PRVREG", output);
232 fputs(
" - ILL_COPROC", output);
235 fputs(
" - ILL_BADSTK", output);
240 fprintf(output,
" (at 0x%lx).%s\n",
241 (
unsigned long)info->si_addr,
242 (isAddressOnStack)?
" Stackoverflow?":
"");
245 unexpectedSignal=
false;
246 fputs(
"cppcheck received signal ", output);
247 fputs(signame, output);
248 fputs(
".\n", output);
251 fputs(
"Internal error: cppcheck received signal ", output);
252 fputs(signame, output);
253 switch (info->si_code) {
255 fputs(
" - SEGV_MAPERR", output);
258 fputs(
" - SEGV_ACCERR", output);
263 fprintf(output,
" (%sat 0x%lx).%s\n",
266 (type==0) ?
"reading " :
"writing ",
267 (
unsigned long)info->si_addr,
268 (isAddressOnStack)?
" Stackoverflow?":
""
272 fputs(
"cppcheck received signal ", output);
273 fputs(signame, output);
274 fputs(
".\n", output);
278 fputs(
"Internal error: cppcheck received signal ", output);
279 fputs(signame, output);
280 fputs(
".\n", output);
283 #ifdef USE_UNIX_BACKTRACE_SUPPORT
284 print_stacktrace(output,
true, -1, lowMem);
286 if (unexpectedSignal) {
287 fputs(
"\nPlease report this to the cppcheck developers!\n", output);
293 struct sigaction act;
294 memset(&act, 0,
sizeof(act));
295 act.sa_handler=SIG_DFL;
296 sigaction(signo, &act,
nullptr);
305 char *heapVariable=
static_cast<char*
>(malloc(1));
306 bStackBelowHeap = &stackVariable < heapVariable;
311 segv_stack.ss_sp = mytstack;
312 segv_stack.ss_flags = 0;
313 segv_stack.ss_size = MYSTACKSIZE;
314 sigaltstack(&segv_stack,
nullptr);
317 struct sigaction act;
318 memset(&act, 0,
sizeof(act));
319 act.sa_flags=SA_SIGINFO|SA_ONSTACK;
320 act.sa_sigaction=CppcheckSignalHandler;
321 for (std::map<int, std::string>::const_iterator sig=listofsignals.cbegin(); sig!=listofsignals.cend(); ++sig) {
322 sigaction(sig->first, &act,
nullptr);
324 return (executor.*f)(settings);
This class works as an example of how CppCheck can be used in external programs without very little k...
static FILE * getExceptionOutput()
This is just a container for general settings so that we don't need to pass individual values to func...