1616 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1717 */
1818
19- #include " cppcheckexecutorsig .h"
19+ #include " signalhandler .h"
2020
2121#if defined(USE_UNIX_SIGNAL_HANDLING)
2222
23- #include " cppcheckexecutor.h"
24-
2523#ifdef USE_UNIX_BACKTRACE_SUPPORT
2624#include " stacktrace.h"
2725#endif
@@ -57,6 +55,12 @@ static constexpr size_t MYSTACKSIZE = 16*1024+SIGSTKSZ; // wild guess about a re
5755#endif
5856static char mytstack[MYSTACKSIZE]= {0 }; // alternative stack for signal handler
5957static bool bStackBelowHeap=false ; // lame attempt to locate heap vs. stack address space. See CppCheckExecutor::check_wrapper()
58+ static FILE* signalOutput = stdout;
59+
60+ void set_signal_handler_output (FILE* f)
61+ {
62+ signalOutput = f;
63+ }
6064
6165/* *
6266 * \param[in] ptr address to be examined.
@@ -121,27 +125,21 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context)
121125
122126 const Signalmap_t::const_iterator it=listofsignals.find (signo);
123127 const char * const signame = (it==listofsignals.end ()) ? " unknown" : it->second .c_str ();
124- #ifdef USE_UNIX_BACKTRACE_SUPPORT
125- bool lowMem=false ; // was low-memory condition detected? Be careful then! Avoid allocating much more memory then.
126- #endif
127128 bool unexpectedSignal=true ; // unexpected indicates program failure
128129 bool terminate=true ; // exit process/thread
129130 const bool isAddressOnStack = IsAddressOnStack (info->si_addr );
130- FILE* output = CppCheckExecutor::getExceptionOutput () ;
131+ FILE * const output = signalOutput ;
131132 switch (signo) {
132133 case SIGABRT:
133134 fputs (" Internal error: cppcheck received signal " , output);
134135 fputs (signame, output);
135136 fputs (
136137#ifdef NDEBUG
137- " - out of memory? \n " ,
138+ " - abort \n " ,
138139#else
139- " - out of memory or assertion? \n " ,
140+ " - abort or assertion\n " ,
140141#endif
141142 output);
142- #ifdef USE_UNIX_BACKTRACE_SUPPORT
143- lowMem=true ; // educated guess
144- #endif
145143 break ;
146144 case SIGBUS:
147145 fputs (" Internal error: cppcheck received signal " , output);
@@ -281,7 +279,9 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context)
281279 break ;
282280 }
283281#ifdef USE_UNIX_BACKTRACE_SUPPORT
284- print_stacktrace (output, true , -1 , lowMem);
282+ // flush otherwise the trace might be printed earlier
283+ fflush (output);
284+ print_stacktrace (output, 1 , true , -1 , true );
285285#endif
286286 if (unexpectedSignal) {
287287 fputs (" \n Please report this to the cppcheck developers!\n " , output);
@@ -298,8 +298,10 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context)
298298 }
299299}
300300
301- int check_wrapper_sig (CppCheckExecutor& executor, int (CppCheckExecutor::*f)( const Settings&) const , const Settings& settings )
301+ void register_signal_handler ( )
302302{
303+ FILE * const output = signalOutput;
304+
303305 // determine stack vs. heap
304306 char stackVariable;
305307 char *heapVariable=static_cast <char *>(malloc (1 ));
@@ -311,7 +313,11 @@ int check_wrapper_sig(CppCheckExecutor& executor, int (CppCheckExecutor::*f)(con
311313 segv_stack.ss_sp = mytstack;
312314 segv_stack.ss_flags = 0 ;
313315 segv_stack.ss_size = MYSTACKSIZE;
314- sigaltstack (&segv_stack, nullptr );
316+ if (sigaltstack (&segv_stack, nullptr ) != 0 ) {
317+ // TODO: log errno
318+ fputs (" could not set alternate signal stack context.\n " , output);
319+ std::exit (EXIT_FAILURE);
320+ }
315321
316322 // install signal handler
317323 struct sigaction act;
@@ -321,7 +327,6 @@ int check_wrapper_sig(CppCheckExecutor& executor, int (CppCheckExecutor::*f)(con
321327 for (std::map<int , std::string>::const_iterator sig=listofsignals.cbegin (); sig!=listofsignals.cend (); ++sig) {
322328 sigaction (sig->first , &act, nullptr );
323329 }
324- return (executor.*f)(settings);
325330}
326331
327332#endif
0 commit comments