Fix handling of SIGSEGV and SIGABRT in nano_node (#3502)
The handling of SIGSEGV and SIGABRT did not have the desired effect of generating stack traces of the source code that caused the signal. That's because the signals were handled by the signal manager, which first switches stack context to one that is safe to execute any code. However, for SIGSEGV and SIGABRT we want to print the stacktrace of the problem and therefore we cannot switch context. So, I am setting the handling of SIGSEGV and SIGABRT to use the classic signal function, like before the signal manager was introduced.
This commit is contained in:
		
					parent
					
						
							
								fb49976f02
							
						
					
				
			
			
				commit
				
					
						6063f5f011
					
				
			
		
					 3 changed files with 20 additions and 15 deletions
				
			
		| 
						 | 
					@ -49,14 +49,6 @@ void nano::signal_manager::register_signal_handler (int signum, std::function<vo
 | 
				
			||||||
	log (boost::str (boost::format ("Registered signal handler for signal %d") % signum));
 | 
						log (boost::str (boost::format ("Registered signal handler for signal %d") % signum));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::function<void (int)> nano::signal_manager::get_debug_files_handler (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return [] (int) {
 | 
					 | 
				
			||||||
		nano::dump_crash_stacktrace ();
 | 
					 | 
				
			||||||
		nano::create_load_memory_address_files ();
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void nano::signal_manager::base_handler (nano::signal_manager::signal_descriptor descriptor, const boost::system::error_code & error, int signum)
 | 
					void nano::signal_manager::base_handler (nano::signal_manager::signal_descriptor descriptor, const boost::system::error_code & error, int signum)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!error)
 | 
						if (!error)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,9 +33,6 @@ public:
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	void register_signal_handler (int signum, std::function<void (int)> handler, bool repeat);
 | 
						void register_signal_handler (int signum, std::function<void (int)> handler, bool repeat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** returns a signal handler that prints a stacktrace and creates some debug files */
 | 
					 | 
				
			||||||
	std::function<void (int)> get_debug_files_handler (void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	struct signal_descriptor final
 | 
						struct signal_descriptor final
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,16 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					void nano_abort_signal_handler (int signum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// create some debugging log files
 | 
				
			||||||
 | 
						nano::dump_crash_stacktrace ();
 | 
				
			||||||
 | 
						nano::create_load_memory_address_files ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// re-raise signal to call the default handler and exit
 | 
				
			||||||
 | 
						raise (signum);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
volatile sig_atomic_t sig_int_or_term = 0;
 | 
					volatile sig_atomic_t sig_int_or_term = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384;
 | 
					constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384;
 | 
				
			||||||
| 
						 | 
					@ -39,10 +49,14 @@ static void load_and_set_bandwidth_params (std::shared_ptr<nano::node> const & n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::node_flags const & flags)
 | 
					void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::node_flags const & flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// Override segmentation fault and aborting.
 | 
						// We catch signal SIGSEGV and SIGABRT not via the signal manager because we want these signal handlers
 | 
				
			||||||
	nano::signal_manager sigman;
 | 
						// to be executed in the stack of the code that caused the signal, so we can dump the stacktrace.
 | 
				
			||||||
	sigman.register_signal_handler (SIGSEGV, sigman.get_debug_files_handler (), false);
 | 
						struct sigaction sa = {};
 | 
				
			||||||
	sigman.register_signal_handler (SIGABRT, sigman.get_debug_files_handler (), false);
 | 
						sa.sa_handler = nano_abort_signal_handler;
 | 
				
			||||||
 | 
						sigemptyset (&sa.sa_mask);
 | 
				
			||||||
 | 
						sa.sa_flags = SA_RESETHAND;
 | 
				
			||||||
 | 
						sigaction (SIGSEGV, &sa, NULL);
 | 
				
			||||||
 | 
						sigaction (SIGABRT, &sa, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	boost::filesystem::create_directories (data_path);
 | 
						boost::filesystem::create_directories (data_path);
 | 
				
			||||||
	boost::system::error_code error_chmod;
 | 
						boost::system::error_code error_chmod;
 | 
				
			||||||
| 
						 | 
					@ -155,6 +169,8 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::
 | 
				
			||||||
					sig_int_or_term = 1;
 | 
										sig_int_or_term = 1;
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									nano::signal_manager sigman;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// keep trapping Ctrl-C to avoid a second Ctrl-C interrupting tasks started by the first
 | 
									// keep trapping Ctrl-C to avoid a second Ctrl-C interrupting tasks started by the first
 | 
				
			||||||
				sigman.register_signal_handler (SIGINT, &nano::signal_handler, true);
 | 
									sigman.register_signal_handler (SIGINT, &nano::signal_handler, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue