]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
JIT unexpected crash detection.
authorToni Wilen <twilen@winuae.net>
Sat, 6 Oct 2018 15:41:58 +0000 (18:41 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 6 Oct 2018 15:41:58 +0000 (18:41 +0300)
cfgfile.cpp
include/newcpu.h
include/options.h
jit/exception_handler.cpp
newcpu.cpp
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/win32gui.cpp

index f10de1b68d2c3c5d837663d80ad570d43980ddac..c96691cdeddc0cbff23d99b7bccbb0213566942e 100644 (file)
@@ -1886,6 +1886,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 #ifdef USE_JIT_FPU
        cfgfile_write_bool (f, _T("compfpu"), p->compfpu);
 #endif
+       cfgfile_write_bool(f, _T("comp_catchdetect"), p->comp_catchfault);
        cfgfile_write (f, _T("cachesize"), _T("%d"), p->cachesize);
 
        for (i = 0; i < MAX_JPORTS; i++) {
@@ -5281,6 +5282,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_yesno (option, value, _T("fpu_strict"), &p->fpu_strict)
                || cfgfile_yesno (option, value, _T("comp_nf"), &p->compnf)
                || cfgfile_yesno (option, value, _T("comp_constjump"), &p->comp_constjump)
+               || cfgfile_yesno(option, value, _T("comp_catchfault"), &p->comp_catchfault)
 #ifdef USE_JIT_FPU
                || cfgfile_yesno (option, value, _T("compfpu"), &p->compfpu)
 #endif
@@ -7548,6 +7550,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type)
 #else
        p->compfpu = 0;
 #endif
+       p->comp_catchfault = true;
        p->cachesize = 0;
 
        p->gfx_framerate = 1;
index 3e49e9e6d1ad04469db5a507a406549ddb23db68..572f41bb0df04d22d70f2744a11da89b34a7246d 100644 (file)
@@ -703,6 +703,7 @@ extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr);
 extern void exception3i (uae_u32 opcode, uaecptr addr);
 extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
 extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc);
+extern void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc);
 extern void m68k_reset (void);
 extern void cpureset (void);
 extern void cpu_halt (int id);
index cf280f24057265c5d89fdcf4e710ecfce39efc1d..4510ebbbb468ac1c6cb0995972c470dd6400ed23 100644 (file)
@@ -514,6 +514,7 @@ struct uae_prefs {
        bool compfpu;
        bool comp_hardflush;
        bool comp_constjump;
+       bool comp_catchfault;
        int cachesize;
        bool fpu_strict;
        int fpu_mode;
index 2b3d89f32a19a9843da6d0daacbb16aaf4d59596..9f4698b0f6d29ffa922c523d67551227891416d3 100644 (file)
@@ -505,6 +505,11 @@ LONG WINAPI EvalException(LPEXCEPTION_POINTERS info)
        if (handle_access(address, info)) {
                return EXCEPTION_CONTINUE_EXECUTION;
        }
+       if (currprefs.comp_catchfault) {
+               // setup fake exception
+               exception2_setup(uae_p32(address) - uae_p32(NATMEM_OFFSET), info->ExceptionRecord->ExceptionInformation[0] == 0, 1, regs.s ? 4 : 0);
+               return EXCEPTION_EXECUTE_HANDLER;
+       }
        return EXCEPTION_CONTINUE_SEARCH;
 }
 
index 28ae2b5d41300de549bdbffc01c530d633ea41fb..eadf10182738059cc2ab07d66ed4650a57864ab4 100644 (file)
@@ -3654,18 +3654,27 @@ kludge_me_do:
 // address = format $2 stack frame address field
 static void ExceptionX (int nr, uaecptr address)
 {
+       uaecptr pc = m68k_getpc();
        regs.exception = nr;
        if (cpu_tracer) {
                cputrace.state = nr;
        }
        if (!regs.s) {
-               regs.instruction_pc_user_exception = m68k_getpc();
+               regs.instruction_pc_user_exception = pc;
        }
 
 #ifdef JIT
        if (currprefs.cachesize)
-               regs.instruction_pc = address == -1 ? m68k_getpc () : address;
+               regs.instruction_pc = address == -1 ? pc : address;
 #endif
+
+       if (debug_illegal && !in_rom(pc)) {
+               if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) {
+                       write_log(_T("Exception %d breakpoint\n"), nr);
+                       activate_debugger();
+               }
+       }
+
 #ifdef CPUEMU_13
        if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68010)
                Exception_ce000 (nr);
@@ -3680,12 +3689,6 @@ static void ExceptionX (int nr, uaecptr address)
                        Exception_normal (nr);
                }
 
-       if (debug_illegal && !in_rom (M68K_GETPC)) {
-               if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) {
-                       write_log (_T("Exception %d breakpoint\n"), nr);
-                       activate_debugger ();
-               }
-       }
        regs.exception = 0;
        if (cpu_tracer) {
                cputrace.state = 0;
@@ -5595,15 +5598,35 @@ static void m68k_run_jit(void)
 #endif
 
        for (;;) {
-               ((compiled_handler*)(pushall_call_handler))();
-               /* Whenever we return from that, we should check spcflags */
-               check_uae_int_request();
-               if (regs.spcflags) {
-                       if (do_specialties (0)) {
-                               return;
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
+               __try {
+#endif
+                       for (;;) {
+                               ((compiled_handler*)(pushall_call_handler))();
+                               /* Whenever we return from that, we should check spcflags */
+                               check_uae_int_request();
+                               if (regs.spcflags) {
+                                       if (do_specialties(0)) {
+                                               return;
+                                       }
+                               }
                        }
+
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
+               } __except (EvalException(GetExceptionInformation())) {
+                       // Something very bad happened, generate fake bus error exception
+                       // Either emulation continues normally or crashes.
+                       // Without this it would have crashed in any case..
+                       uaecptr pc = M68K_GETPC;
+                       write_log(_T("Unhandled JIT exception! PC=%08x\n"), pc);
+                       if (pc & 1)
+                               Exception(3);
+                       else
+                               Exception(2);
                }
+#endif
        }
+
 }
 #endif /* JIT */
 
@@ -8826,6 +8849,16 @@ void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
        exception3f (opcode, addr, w, i, false, pc, true);
 }
 
+void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc)
+{
+       last_addr_for_exception_3 = m68k_getpc() + bus_error_offset;
+       last_fault_for_exception_3 = addr;
+       last_writeaccess_for_exception_3 = read == 0;
+       last_instructionaccess_for_exception_3 = (fc & 1) == 0;
+       last_op_for_exception_3 = regs.opcode;
+       last_notinstruction_for_exception_3 = exception_in_exception != 0;
+}
+
 void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
 {
        if (currprefs.mmu_model) {
@@ -8836,12 +8869,7 @@ void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
                        mmu_bus_error (addr, 0, fc, read == false, size, 0, true);
                }
        } else {
-               last_addr_for_exception_3 = m68k_getpc() + bus_error_offset;
-               last_fault_for_exception_3 = addr;
-               last_writeaccess_for_exception_3 = read == 0;
-               last_instructionaccess_for_exception_3 = (fc & 1) == 0;
-               last_op_for_exception_3 = regs.opcode;
-               last_notinstruction_for_exception_3 = exception_in_exception != 0;
+               exception2_setup(addr, read, size, fc);
                THROW(2);
        }
 }
index 7a9e71df288942e5152b6e0f9a9f144532dd757b..921c0061b02f4bcaced0ab281331814eada100f4 100644 (file)
 #define IDC_SOUNDDRIVEVOLUME2           1581
 #define IDC_CS_CACHE_TEXT               1582
 #define IDC_SOUNDVOLUMEEXT2             1582
+#define IDC_JITCRASH                    1582
 #define IDC_CS_CACHE_TEXT2              1583
 #define IDC_SOUNDDRIVEVOLUMEX           1583
 #define IDC_COLLISIONS                  1584
index 1a55e996eb81d2bd6a71d7a2e6ccfaf7b2bdbfe6..eab0104aebf385f63bbbf34e5909623eb08ec353 100644 (file)
@@ -301,24 +301,25 @@ BEGIN
                     "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,145,161,236,10
     RTEXT           "Stopped M68K CPU idle mode",IDC_STATIC,180,183,121,9
     CONTROL         "",IDC_PPC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,308,177,69,21
-    GROUPBOX        "x86 Bridgeboard CPU options",IDC_STATIC,136,202,258,42
+    GROUPBOX        "x86 Bridgeboard CPU options",IDC_STATIC,136,202,258,38
     RTEXT           "CPU Speed",IDC_STATIC,147,221,55,9,SS_CENTERIMAGE
     EDITTEXT        IDC_CPUTEXT_x86,224,220,39,12,ES_CENTER | ES_READONLY
     CONTROL         "",IDC_SPEED_x86,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,278,215,108,20
-    GROUPBOX        "Advanced JIT Settings",IDC_STATIC,136,245,258,70
-    RTEXT           "Cache size:",IDC_STATIC,143,261,66,10,SS_CENTERIMAGE
-    CONTROL         "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,212,255,115,20
-    EDITTEXT        IDC_CACHETEXT,331,260,30,12,ES_CENTER | ES_READONLY
-    CONTROL         "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,281,71,11
-    CONTROL         "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,281,71,11
-    CONTROL         "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,281,84,11
-    CONTROL         "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,143,299,72,10
-    CONTROL         "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,221,299,72,10
-    CONTROL         "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,299,68,11
+    GROUPBOX        "Advanced JIT Settings",IDC_STATIC,136,241,258,74
+    RTEXT           "Cache size:",IDC_STATIC,143,260,66,10,SS_CENTERIMAGE
+    CONTROL         "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,212,250,115,20
+    EDITTEXT        IDC_CACHETEXT,331,255,30,12,ES_CENTER | ES_READONLY
+    CONTROL         "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,273,71,11
+    CONTROL         "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,273,71,11
+    CONTROL         "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,273,84,11
+    CONTROL         "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,143,288,72,10
+    CONTROL         "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,221,288,72,10
+    CONTROL         "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,288,68,11
     GROUPBOX        "MMU",IDC_STATIC,2,168,129,42,BS_LEFT
     CONTROL         "Data cache emulation [] 68030, 040 and 060 optional data cache emulation. Requires More compatible option.",IDC_CPUDATACACHE,
                     "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,123,119,12
     COMBOBOX        IDC_FPU_MODE,7,299,112,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Catch unexpected exceptions",IDC_JITCRASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,300,115,11
 END
 
 IDD_FLOPPY DIALOGEX 0, 0, 396, 261
index 070c1ab949865fcc0bbc63c7fe06fd0d43224b64..1410c7f2b94b145fc18f9bef3861dbbbb3072285 100644 (file)
@@ -12090,6 +12090,7 @@ static void enable_for_cpudlg (HWND hDlg)
        ew(hDlg, IDC_HARDFLUSH, enable);
        ew(hDlg, IDC_CONSTJUMP, enable);
        ew(hDlg, IDC_JITFPU, enable);
+       ew(hDlg, IDC_JITCRASH, enable);
        ew(hDlg, IDC_NOFLAGS, enable);
        ew(hDlg, IDC_CS_CACHE_TEXT, enable);
        ew(hDlg, IDC_CACHE, enable);
@@ -12172,11 +12173,12 @@ static void values_to_cpudlg (HWND hDlg)
        _stprintf (buffer, _T("%d MB"), workprefs.cachesize / 1024 );
        SetDlgItemText (hDlg, IDC_CACHETEXT, buffer);
 
-       CheckDlgButton (hDlg, IDC_NOFLAGS, workprefs.compnf);
-       CheckDlgButton (hDlg, IDC_JITFPU, workprefs.compfpu);
-       CheckDlgButton (hDlg, IDC_HARDFLUSH, workprefs.comp_hardflush);
-       CheckDlgButton (hDlg, IDC_CONSTJUMP, workprefs.comp_constjump);
-       CheckDlgButton (hDlg, IDC_JITENABLE, workprefs.cachesize > 0);
+       CheckDlgButton(hDlg, IDC_JITCRASH, workprefs.comp_catchfault);
+       CheckDlgButton(hDlg, IDC_NOFLAGS, workprefs.compnf);
+       CheckDlgButton(hDlg, IDC_JITFPU, workprefs.compfpu);
+       CheckDlgButton(hDlg, IDC_HARDFLUSH, workprefs.comp_hardflush);
+       CheckDlgButton(hDlg, IDC_CONSTJUMP, workprefs.comp_constjump);
+       CheckDlgButton(hDlg, IDC_JITENABLE, workprefs.cachesize > 0);
        bool mmu = ((workprefs.cpu_model == 68060 && workprefs.mmu_model == 68060) ||
                (workprefs.cpu_model == 68040 && workprefs.mmu_model == 68040) ||
                (workprefs.cpu_model == 68030 && workprefs.mmu_model == 68030)) &&
@@ -12286,10 +12288,11 @@ static void values_from_cpudlg (HWND hDlg)
        workprefs.comptrustlong = newtrust;
        workprefs.comptrustnaddr= newtrust;
 
-       workprefs.compnf            = ischecked (hDlg, IDC_NOFLAGS);
-       workprefs.compfpu           = ischecked (hDlg, IDC_JITFPU);
-       workprefs.comp_hardflush    = ischecked (hDlg, IDC_HARDFLUSH);
-       workprefs.comp_constjump    = ischecked (hDlg, IDC_CONSTJUMP);
+       workprefs.comp_catchfault   = ischecked(hDlg, IDC_JITCRASH);
+       workprefs.compnf            = ischecked(hDlg, IDC_NOFLAGS);
+       workprefs.compfpu           = ischecked(hDlg, IDC_JITFPU);
+       workprefs.comp_hardflush    = ischecked(hDlg, IDC_HARDFLUSH);
+       workprefs.comp_constjump    = ischecked(hDlg, IDC_CONSTJUMP);
 
 #ifdef JIT
        oldcache = workprefs.cachesize;