2018-12-27 18:50:45 +03:00
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# pragma once
# define BOOST_FILESYSTEM_VERSION 3
# define BOOST_NO_CXX11_SCOPED_ENUMS
# include <mutex>
# include <system_error>
# include <boost/filesystem.hpp>
# include "crypto/crypto.h"
# include "crypto/hash.h"
# include "misc_language.h"
# include "p2p/p2p_protocol_defs.h"
2019-09-19 16:51:58 +03:00
# include "ntp.h"
2018-12-27 18:50:45 +03:00
# if defined(WIN32)
# include <dbghelp.h>
# endif
2020-07-15 18:15:11 +02:00
# ifdef NDEBUG
# define BUILD_TYPE "Release"
# else
# define BUILD_TYPE "Debug"
# endif
2018-12-27 18:50:45 +03:00
namespace tools
{
std : : string get_host_computer_name ( ) ;
std : : string get_default_data_dir ( ) ;
std : : string get_default_user_dir ( ) ;
std : : string get_current_username ( ) ;
std : : string get_os_version_string ( ) ;
2020-07-11 18:42:59 +02:00
bool copy_dir ( boost : : filesystem : : path const & source , boost : : filesystem : : path const & destination ) ;
2019-10-10 16:22:34 +03:00
bool check_remote_client_version ( const std : : string & client_ver ) ;
2018-12-27 18:50:45 +03:00
bool create_directories_if_necessary ( const std : : string & path ) ;
std : : error_code replace_file ( const std : : string & replacement_name , const std : : string & replaced_name ) ;
inline crypto : : hash get_proof_of_trust_hash ( const nodetool : : proof_of_trust & pot )
{
std : : string s ;
s . append ( reinterpret_cast < const char * > ( & pot . peer_id ) , sizeof ( pot . peer_id ) ) ;
s . append ( reinterpret_cast < const char * > ( & pot . time ) , sizeof ( pot . time ) ) ;
return crypto : : cn_fast_hash ( s . data ( ) , s . size ( ) ) ;
}
inline
crypto : : public_key get_public_key_from_string ( const std : : string & str_key )
{
crypto : : public_key k = AUTO_VAL_INIT ( k ) ;
epee : : string_tools : : hex_to_pod ( str_key , k ) ;
return k ;
}
2019-02-16 03:04:08 +03:00
bool get_log_chunk_gzipped ( uint64_t offset , uint64_t size , std : : string & output , std : : string & error ) ;
uint64_t get_log_file_size ( ) ;
2018-12-27 18:50:45 +03:00
class signal_handler
{
public :
template < typename T >
static bool install ( T t )
{
# if defined(WIN32)
bool r = TRUE = = : : SetConsoleCtrlHandler ( & win_handler , TRUE ) ;
if ( r )
{
m_handler = t ;
}
return r ;
# else
signal ( SIGINT , posix_handler ) ;
signal ( SIGTERM , posix_handler ) ;
m_handler = t ;
return true ;
# endif
}
template < typename T >
static void install_fatal ( T t )
{
# if defined(WIN32)
// NOTE: Unfortunately, there's no way to handle heap corruption signals/exceptions. More info: https://connect.microsoft.com/VisualStudio/feedback/details/664497/cant-catch-0xc0000374-exception-status-heap-corruption
: : SetUnhandledExceptionFilter ( win_unhandled_exception_handler ) ;
# else
signal ( SIGABRT , posix_fatal_handler ) ;
signal ( SIGSEGV , posix_fatal_handler ) ;
signal ( SIGILL , posix_fatal_handler ) ;
# endif
m_fatal_handler = t ;
}
static void uninstall_fatal ( )
{
# if defined(WIN32)
: : SetUnhandledExceptionFilter ( NULL ) ;
# endif
signal ( SIGABRT , SIG_DFL ) ;
signal ( SIGSEGV , SIG_DFL ) ;
signal ( SIGILL , SIG_DFL ) ;
m_fatal_handler = & noop_fatal_handler ;
}
private :
# if defined(WIN32)
static BOOL WINAPI win_handler ( DWORD type )
{
if ( CTRL_C_EVENT = = type | | CTRL_BREAK_EVENT = = type )
{
handle_signal ( ) ;
return TRUE ;
}
else
{
LOG_PRINT_RED_L0 ( " Got control signal " < < type < < " . Exiting without saving... " ) ;
return FALSE ;
}
return TRUE ;
}
/************************************************************************/
// This code borrowed from http://www.debuginfo.com/articles/effminidumps2.html
/************************************************************************/
///////////////////////////////////////////////////////////////////////////////
// This function determines whether we need data sections of the given module
//
static bool IsDataSectionNeeded ( const WCHAR * pModuleName )
{
// Check parameters
if ( pModuleName = = 0 )
{
return false ;
}
// Extract the module name
WCHAR szFileName [ _MAX_FNAME ] = L " " ;
_wsplitpath ( pModuleName , NULL , NULL , szFileName , NULL ) ;
// Compare the name with the list of known names and decide
// Note: For this to work, the executable name must be "mididump.exe"
if ( wcsicmp ( szFileName , L " mididump " ) = = 0 )
{
return true ;
}
else if ( wcsicmp ( szFileName , L " ntdll " ) = = 0 )
{
return true ;
}
// Complete
return false ;
}
///////////////////////////////////////////////////////////////////////////////
// Custom minidump callback
//
static BOOL CALLBACK MyMiniDumpCallback ( PVOID pParam , const PMINIDUMP_CALLBACK_INPUT pInput ,
PMINIDUMP_CALLBACK_OUTPUT pOutput )
{
BOOL bRet = FALSE ;
// Check parameters
if ( pInput = = 0 )
return FALSE ;
if ( pOutput = = 0 )
return FALSE ;
// Process the callbacks
switch ( pInput - > CallbackType )
{
case IncludeModuleCallback :
{
// Include the module into the dump
bRet = TRUE ;
}
break ;
case IncludeThreadCallback :
{
// Include the thread into the dump
bRet = TRUE ;
}
break ;
case ModuleCallback :
{
// Are data sections available for this module ?
if ( pOutput - > ModuleWriteFlags & ModuleWriteDataSeg )
{
// Yes, they are, but do we need them?
if ( ! IsDataSectionNeeded ( pInput - > Module . FullPath ) )
{
wprintf ( L " Excluding module data sections: %s \n " , pInput - > Module . FullPath ) ;
pOutput - > ModuleWriteFlags & = ( ~ ModuleWriteDataSeg ) ;
}
}
bRet = TRUE ;
}
break ;
case ThreadCallback :
{
// Include all thread information into the minidump
bRet = TRUE ;
}
break ;
case ThreadExCallback :
{
// Include this information
bRet = TRUE ;
}
break ;
case MemoryCallback :
{
// We do not include any information here -> return FALSE
bRet = FALSE ;
}
break ;
case CancelCallback :
break ;
}
return bRet ;
}
2019-08-29 04:37:24 +03:00
static void GenerateCrashDump ( EXCEPTION_POINTERS * pep = NULL ) ;
2018-12-27 18:50:45 +03:00
static LONG WINAPI win_unhandled_exception_handler ( _In_ struct _EXCEPTION_POINTERS * ep )
{
GenerateCrashDump ( ep ) ;
handle_fatal_signal ( ep - > ExceptionRecord - > ExceptionCode , ep - > ExceptionRecord - > ExceptionAddress ) ;
return EXCEPTION_EXECUTE_HANDLER ;
}
# else
static void posix_handler ( int /*type*/ )
{
handle_signal ( ) ;
}
# endif
static void posix_fatal_handler ( int sig_number )
{
handle_fatal_signal ( sig_number , 0 ) ;
}
static void noop_fatal_handler ( int , void * ) { }
static void handle_signal ( )
{
2020-05-17 23:15:50 +02:00
static epee : : static_helpers : : wrapper < std : : mutex > m_mutex ;
2018-12-27 18:50:45 +03:00
std : : unique_lock < std : : mutex > lock ( m_mutex ) ;
m_handler ( ) ;
}
static void handle_fatal_signal ( int sig_number , void * address )
{
2020-05-17 23:15:50 +02:00
static epee : : static_helpers : : wrapper < std : : mutex > m_mutex_fatal ;
2018-12-27 18:50:45 +03:00
std : : unique_lock < std : : mutex > lock ( m_mutex_fatal ) ;
m_fatal_handler ( sig_number , address ) ;
uninstall_fatal ( ) ;
}
private :
static std : : function < void ( void ) > m_handler ;
static std : : function < void ( int , void * ) > m_fatal_handler ;
} ;
2019-06-06 16:21:26 +03:00
2018-12-27 18:50:45 +03:00
}