@@ -254,16 +254,21 @@ static const char *signal_name(int signo)
254254 * That is very sensitive to the operating system, hardware, compiler and runtime!
255255 * The code is not meant for production environment, it's using functions not whitelisted for usage in a signal handler function.
256256 */
257- static void print_stacktrace (FILE * f, bool demangling)
257+ static void print_stacktrace (FILE * f, bool demangling, int maxdepth )
258258{
259259#if defined(USE_UNIX_BACKTRACE_SUPPORT)
260260 void *array[32 ]= {0 }; // the less resources the better...
261261 const int depth = backtrace (array, (int )GetArrayLength (array));
262+ const int offset=3 ; // the first two entries are simply within our own exception handling code, third is within libc
263+ if (maxdepth<0 )
264+ maxdepth=depth+offset;
265+ else
266+ maxdepth+=offset;
267+ printf (" maxdepth=%d\n " , maxdepth);
262268 char **symbolstrings = backtrace_symbols (array, depth);
263269 if (symbolstrings) {
264270 fputs (" Callstack:\n " , f);
265- const int offset=3 ; // the first two entries are simply within our own exception handling code, third is within libc
266- for (int i = offset; i < depth; ++i) {
271+ for (int i = offset; i < maxdepth; ++i) {
267272 const char * const symbol = symbolstrings[i];
268273 char * realname = nullptr ;
269274 const char * const firstBracketName = strchr (symbol, ' (' );
@@ -306,6 +311,22 @@ static void print_stacktrace(FILE* f, bool demangling)
306311#endif
307312}
308313
314+ /*
315+ * Neither conclusive, nor portable
316+ * Though one might to make it work beyond Linux x64
317+ * \return true if address is supposed to be on stack (contrary to heap or elswhere).
318+ * If unknown better retun false.
319+ */
320+ static bool isAddressOnStack (const void * ptr)
321+ {
322+ #if defined(__linux) && defined(__amd64)
323+ char a;
324+ return ptr > &a;
325+ #else
326+ return false ;
327+ #endif
328+ }
329+
309330/*
310331 * Entry pointer for signal handlers
311332 * It uses functions which are not safe to be called from a signal handler,
@@ -326,6 +347,7 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context)
326347 const char * const signame = signal_name (signo);
327348 const char * const sigtext = strsignal (signo);
328349 bool bPrintCallstack=true ;
350+ const bool isaddressonstack = isAddressOnStack (info->si_addr );
329351 FILE * f=CppCheckExecutor::getExceptionOutput ()==" stderr" ? stderr : stdout;
330352 fputs (" Internal error: cppcheck received signal " , f);
331353 fputs (signame, f);
@@ -420,8 +442,9 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context)
420442 default :
421443 break ;
422444 }
423- fprintf (f, " (at 0x%p).\n " ,
424- info->si_addr );
445+ fprintf (f, " (at 0x%p).%s\n " ,
446+ info->si_addr ,
447+ (isaddressonstack)?" Stackoverflow?" :" " );
425448 break ;
426449 case SIGINT :
427450 bPrintCallstack=false ;
@@ -438,17 +461,19 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context)
438461 default :
439462 break ;
440463 }
441- fprintf (f, " (%sat 0x%p).\n " ,
464+ fprintf (f, " (%sat 0x%p).%s \n " ,
442465 (type==-1 )? " " :
443466 (type==0 ) ? " reading " : " writing " ,
444- info->si_addr );
467+ info->si_addr ,
468+ (isaddressonstack)?" Stackoverflow?" :" "
469+ );
445470 break ;
446471 default :
447472 fputs (" .\n " , f);
448473 break ;
449474 }
450475 if (bPrintCallstack) {
451- print_stacktrace (f, true );
476+ print_stacktrace (f, true , - 1 /* (isaddressonstack)?8:-1 */ );
452477 fputs (" \n Please report this to the cppcheck developers!\n " , f);
453478 }
454479
@@ -681,6 +706,10 @@ static int filterException(int code, PEXCEPTION_POINTERS ex)
681706 * TODO Check for multi-threading issues!
682707 *
683708 */
709+ #if defined(USE_UNIX_SIGNAL_HANDLING)
710+ const size_t MYSTACKSIZE = 64 *1024 +SIGSTKSZ ;
711+ char mytstack[MYSTACKSIZE ];
712+ #endif
684713int CppCheckExecutor::check_wrapper (CppCheck& cppcheck, int argc, const char * const argv[])
685714{
686715#ifdef USE_WINDOWS_SEH
@@ -693,9 +722,15 @@ int CppCheckExecutor::check_wrapper(CppCheck& cppcheck, int argc, const char* co
693722 return -1 ;
694723 }
695724#elif defined(USE_UNIX_SIGNAL_HANDLING)
725+ stack_t segv_stack;
726+ segv_stack.ss_sp = mytstack;
727+ segv_stack.ss_flags = 0 ;
728+ segv_stack.ss_size = MYSTACKSIZE ;
729+ sigaltstack (&segv_stack, NULL );
730+
696731 struct sigaction act;
697732 memset (&act, 0 , sizeof (act));
698- act.sa_flags =SA_SIGINFO ;
733+ act.sa_flags =SA_SIGINFO | SA_ONSTACK ;
699734 act.sa_sigaction =CppcheckSignalHandler;
700735 for (std::size_t s=0 ; s<GetArrayLength (listofsignals); ++s) {
701736 sigaction (listofsignals[s].signalnumber , &act, NULL );
0 commit comments