"Fossies" - the Fresh Open Source Software Archive

Member "src/Main/FatalErrorHandler.cpp" (10 Oct 2018, 7359 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "FatalErrorHandler.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2  Derived from source code of TrueCrypt 7.1a, which is
    3  Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
    4  by the TrueCrypt License 3.0.
    5 
    6  Modifications and additions to the original source code (contained in this file)
    7  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
    8  and are governed by the Apache License 2.0 the full text of which is
    9  contained in the file License.txt included in VeraCrypt binary and source
   10  code distribution packages.
   11 */
   12 
   13 #include "System.h"
   14 #include <wx/stackwalk.h>
   15 
   16 #include "Main.h"
   17 #include "Application.h"
   18 #include "UserInterface.h"
   19 #include "GraphicUserInterface.h"
   20 #include "Volume/Crc32.h"
   21 
   22 #ifdef TC_UNIX
   23 #include <signal.h>
   24 #endif
   25 
   26 #ifdef TC_MACOSX
   27 #   include <sys/ucontext.h>
   28 #elif defined (TC_BSD)
   29 #   include <ucontext.h>
   30 #endif
   31 
   32 #include "FatalErrorHandler.h"
   33 
   34 namespace VeraCrypt
   35 {
   36     static terminate_handler DefaultTerminateHandler;
   37 
   38     struct FatalErrorReport
   39     {
   40         bool UnhandledException;
   41     };
   42 
   43 #ifdef TC_UNIX
   44     static void OnFatalProgramErrorSignal (int, siginfo_t *signalInfo, void *contextArg)
   45     {
   46         TC_UNUSED_VAR ucontext_t *context = (ucontext_t *) contextArg;
   47         uint64 faultingInstructionAddress = 0;
   48 
   49 #ifdef TC_LINUX
   50 #   ifdef REG_EIP
   51         faultingInstructionAddress = context->uc_mcontext.gregs[REG_EIP];
   52 #   elif defined (REG_RIP)
   53         faultingInstructionAddress = context->uc_mcontext.gregs[REG_RIP];
   54 #   endif
   55 
   56 #elif defined (TC_MACOSX)
   57 #   ifdef __x86_64__
   58         faultingInstructionAddress = context->uc_mcontext->__ss.__rip;
   59 #   else
   60         faultingInstructionAddress = context->uc_mcontext->__ss.__eip;
   61 #   endif
   62 
   63 #endif
   64         wstringstream vars;
   65 
   66         vars << L"cpus=" << wxThread::GetCPUCount();
   67         vars << L"&cksum=" << hex << FatalErrorHandler::GetAppChecksum() << dec;
   68         vars << L"&err=" << signalInfo->si_signo;
   69         vars << L"&addr=" << hex << faultingInstructionAddress << dec;
   70         vars << FatalErrorHandler::GetCallStack (16);
   71 
   72         wxString url = Gui->GetHomepageLinkURL (L"err-report", vars.str());
   73         url.Replace (L"=0x", L"=");
   74         url.Replace (L"=0X0x", L"=0x");
   75         url.Replace (L"=0X", L"=0x");
   76 
   77         wxString msg = L"A critical error has occurred and VeraCrypt must be terminated. If this is caused by a bug in VeraCrypt, we would like to fix it. To help us, you can send us an automatically generated error report containing the following items:\n\n- Program version\n- Operating system version\n- Hardware architecture\n- Checksum of VeraCrypt executable\n- Error category\n- Error address\n";
   78 #if wxUSE_STACKWALKER == 1
   79         msg += L"- VeraCrypt call stack\n";
   80 #endif
   81         msg += L"\nIf you select 'Yes', the following URL (which contains the entire error report) will be opened in your default Internet browser.\n\n";
   82 
   83 #ifdef __WXGTK__
   84         wxString fUrl = url;
   85         fUrl.Replace (L"&st", L" &st");
   86         msg += fUrl;
   87 #else
   88         msg += url;
   89 #endif
   90 
   91         msg += L"\n\nDo you want to send us the error report?";
   92 
   93         if (Gui->AskYesNo (msg, true))
   94             wxLaunchDefaultBrowser (url, wxBROWSER_NEW_WINDOW);
   95 
   96         _exit (1);
   97     }
   98 #endif // TC_UNIX
   99 
  100     void FatalErrorHandler::Deregister()
  101     {
  102 #ifdef TC_UNIX
  103         signal (SIGILL, SIG_DFL);
  104         signal (SIGFPE, SIG_DFL);
  105         signal (SIGSEGV, SIG_DFL);
  106         signal (SIGBUS, SIG_DFL);
  107         signal (SIGSYS, SIG_DFL);
  108 #endif
  109 
  110 #ifndef TC_WINDOWS
  111         std::set_terminate (DefaultTerminateHandler);
  112 #endif
  113     }
  114 
  115     uint32 FatalErrorHandler::GetAppChecksum ()
  116     {
  117         uint32 checkSum = 0;
  118         try
  119         {
  120             File executable;
  121             executable.Open (Application::GetExecutablePath());
  122 
  123             Buffer executableData (executable.Length());
  124             executable.ReadCompleteBuffer (executableData);
  125             checkSum = Crc32::ProcessBuffer (executableData);
  126         }
  127         catch (...) { }
  128 
  129         return checkSum;
  130     }
  131 
  132     wstring FatalErrorHandler::GetCallStack (int depth)
  133     {
  134 #if wxUSE_STACKWALKER == 1
  135 
  136         class StackWalker : public wxStackWalker
  137         {
  138         public:
  139             StackWalker () : FrameCount (0) { }
  140 
  141             void OnStackFrame (const wxStackFrame &frame)
  142             {
  143                 if (FrameCount >= 32)
  144                     return;
  145 
  146                 StackVars << L"&st" << FrameCount++ << L"=";
  147 
  148                 wxString functionName = frame.GetName();
  149                 if (!functionName.empty() && !frame.GetModule().empty())
  150                 {
  151                     int p = functionName.Find (L"(");
  152                     if (p != wxNOT_FOUND)
  153                         functionName = functionName.Mid (0, p);
  154 
  155                     for (size_t i = 0; i < functionName.size(); ++i)
  156                     {
  157                         if (!isalnum (functionName[i]))
  158                             functionName[i] = L'_';
  159                     }
  160 
  161                     while (functionName.Replace (L"__", L"_"));
  162 
  163                     StackVars << wstring (functionName);
  164                 }
  165                 else
  166                     StackVars << "0X" << hex << frame.GetAddress() << dec;
  167             }
  168 
  169             int FrameCount;
  170             wstringstream StackVars;
  171         };
  172 
  173         StackWalker stackWalker;
  174         stackWalker.Walk (2);
  175 
  176         return stackWalker.StackVars.str();
  177 
  178 #else // wxUSE_STACKWALKER
  179 
  180         return wstring();
  181 
  182 #endif // wxUSE_STACKWALKER
  183     }
  184 
  185     void FatalErrorHandler::OnTerminate ()
  186     {
  187         try
  188         {
  189             throw;
  190         }
  191         catch (UserAbort&)
  192         {
  193         }
  194         catch (Exception &e)
  195         {
  196             wxString vars;
  197 
  198             wxString exName = StringConverter::ToWide (StringConverter::GetTypeName (typeid (e)));
  199             if (exName.find (L"VeraCrypt::") != string::npos)
  200                 exName = exName.Mid (11);
  201 
  202             wxString exPos = StringConverter::ToWide (e.what());
  203             if (exPos.find (L"VeraCrypt::") != string::npos)
  204                 exPos = exPos.Mid (11);
  205 
  206             vars << L"cpus=" << wxThread::GetCPUCount();
  207             vars << wxString::Format (L"&cksum=%x", GetAppChecksum());
  208             vars << L"&exception=" << exName;
  209             vars << L"&exlocation=" << exPos;
  210             vars << FatalErrorHandler::GetCallStack (16);
  211 
  212             vars.Replace (L"::", L".");
  213             vars.Replace (L":", L".");
  214 
  215             wxString url = Gui->GetHomepageLinkURL (L"err-report", vars);
  216             url.Replace (L"=0x", L"=");
  217             url.Replace (L"=0X0x", L"=0x");
  218             url.Replace (L"=0X", L"=0x");
  219 
  220             wxString msg = L"An unhandled exception has occurred and VeraCrypt must be terminated. If this is caused by a bug in VeraCrypt, we would like to fix it. To help us, you can send us an automatically generated error report containing the following items:\n\n- Program version\n- Operating system version\n- Hardware architecture\n- Checksum of VeraCrypt executable\n- Error description\n- Error location\n";
  221 #if wxUSE_STACKWALKER == 1
  222             msg += L"- VeraCrypt call stack\n";
  223 #endif
  224             msg += L"\nIf you select 'Yes', the following URL (which contains the entire error report) will be opened in your default Internet browser.\n\n";
  225 
  226 #ifdef __WXGTK__
  227             wxString fUrl = url;
  228             fUrl.Replace (L"&st", L" &st");
  229             msg += fUrl;
  230 #else
  231             msg += url;
  232 #endif
  233 
  234             msg += L"\n\nDo you want to send us the error report?";
  235 
  236             if (Gui->AskYesNo (msg, true))
  237                 wxLaunchDefaultBrowser (url, wxBROWSER_NEW_WINDOW);
  238 
  239         }
  240         catch (exception &e)
  241         {
  242             Gui->ShowError (e);
  243         }
  244         catch (...)
  245         {
  246             Gui->ShowError (_("Unknown exception occurred."));
  247         }
  248 
  249         _exit (1);
  250     }
  251 
  252     void FatalErrorHandler::Register ()
  253     {
  254 #ifndef TC_WINDOWS
  255          // OnUnhandledException() seems to be called only on Windows
  256         DefaultTerminateHandler = std::set_terminate (OnTerminate);
  257 #endif
  258 
  259 #ifdef TC_UNIX
  260         struct sigaction action;
  261         Memory::Zero (&action, sizeof (action));
  262         action.sa_flags = SA_SIGINFO;
  263         action.sa_sigaction = OnFatalProgramErrorSignal;
  264 
  265         throw_sys_if (sigaction (SIGILL, &action, nullptr) == -1);
  266         throw_sys_if (sigaction (SIGFPE, &action, nullptr) == -1);
  267         throw_sys_if (sigaction (SIGSEGV, &action, nullptr) == -1);
  268         throw_sys_if (sigaction (SIGBUS, &action, nullptr) == -1);
  269         throw_sys_if (sigaction (SIGSYS, &action, nullptr) == -1);
  270 #endif
  271     }
  272 }