]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Debugger updates, catch application's unhandled exceptions.
authorToni Wilen <twilen@winuae.net>
Sun, 3 Jun 2018 16:16:29 +0000 (19:16 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 3 Jun 2018 16:16:29 +0000 (19:16 +0300)
cfgfile.cpp
debug.cpp
debugmem.cpp
filesys.cpp
include/debug.h
include/debugmem.h
include/newcpu.h
include/options.h
newcpu.cpp

index 85cc3dcccd31ced11b405353dbbcd0b5cb0f80c4..27f3f846864b7b64588aecfa7fc4534f01e0d5dd 100644 (file)
@@ -1617,6 +1617,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write_str (f, _T("use_gui"), guimode1[p->start_gui]);
        cfgfile_write_bool (f, _T("use_debugger"), p->start_debugger);
        cfgfile_write_multichoice(f, _T("debugging_features"), debugfeatures, p->debugging_features);
+       cfgfile_dwrite_str(f, _T("debugging_options"), p->debugging_options);
 
        cfgfile_write_rom (f, &p->path_rom, p->romfile, _T("kickstart_rom_file"));
        cfgfile_write_rom (f, &p->path_rom, p->romextfile, _T("kickstart_ext_rom_file"));
@@ -3087,6 +3088,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                || cfgfile_pathext (option, value, _T("floppy1soundext"), p->floppyslots[1].dfxclickexternal, sizeof p->floppyslots[1].dfxclickexternal / sizeof (TCHAR))
                || cfgfile_pathext (option, value, _T("floppy2soundext"), p->floppyslots[2].dfxclickexternal, sizeof p->floppyslots[2].dfxclickexternal / sizeof (TCHAR))
                || cfgfile_pathext (option, value, _T("floppy3soundext"), p->floppyslots[3].dfxclickexternal, sizeof p->floppyslots[3].dfxclickexternal / sizeof (TCHAR))
+               || cfgfile_string(option, value, _T("debugging_options"), p->debugging_options, sizeof p->debugging_options / sizeof(TCHAR))
                || cfgfile_string (option, value, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR))
                || cfgfile_string (option, value, _T("config_info"), p->info, sizeof p->info / sizeof (TCHAR))
                || cfgfile_string (option, value, _T("config_description"), p->description, sizeof p->description / sizeof (TCHAR)))
index 5dd026cc4b39d26cc6b05cd7c4d5794c5be87780..3274ad79a2e535649026eb789cd8fe5c5a160e1b 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -134,6 +134,14 @@ void activate_debugger_new(void)
        debug_pc = M68K_GETPC;
 }
 
+void activate_debugger_new_pc(uaecptr pc, int len)
+{
+       activate_debugger();
+       trace_mode = TRACE_RANGE_PC;
+       trace_param1 = pc;
+       trace_param2 = pc + len;
+}
+
 bool debug_enforcer(void)
 {
        if (!break_if_enforcer)
index 1304f3143a96e76af75272eca529f868c72dc626..6c50fe2df13ae215b4d9e9f9da3de90ea4fd3e97 100644 (file)
@@ -241,6 +241,15 @@ bool debugmem_break(int type)
        return true;
 }
 
+static bool debugmem_break_pc(int type, uaecptr pc, int len)
+{
+       if (inhibit_break & (1 << type))
+               return false;
+       last_break = type;
+       activate_debugger_new_pc(pc, len);
+       return true;
+}
+
 bool debugmem_inhibit_break(int mode)
 {
        if (mode < 0) {
@@ -880,14 +889,14 @@ static struct debugmemallocs *debugmem_allocate(uae_u32 size, uae_u32 flags, uae
                memset(dm2->state, ((flags & DEBUGMEM_INITIALIZED) ? DEBUGMEM_INITIALIZED : 0) | DEBUGMEM_INUSE, PAGE_SIZE);
                uae_u8 filler = (flags & DEBUGMEM_INITIALIZED) ? 0x00 : 0x99;
                memset(debugmem_bank.baseaddr + (offset + startoffset + j) * PAGE_SIZE, filler, PAGE_SIZE);
-               if (j == (size + PAGE_SIZE - 1) / PAGE_SIZE - 1) {
-                       if (size & PAGE_SIZE_MASK) {
-                               dm2->unused_end = PAGE_SIZE - (size & PAGE_SIZE_MASK);
-                               dm2->flags |= DEBUGMEM_PARTIAL;
-                               memset(dm2->state + (PAGE_SIZE - dm2->unused_end), 0, dm2->unused_end);
-                               memset(debugmem_bank.baseaddr + (offset + startoffset + j) * PAGE_SIZE + (PAGE_SIZE - dm2->unused_end), 0x97, dm2->unused_end);
-                       }
-               }
+if (j == (size + PAGE_SIZE - 1) / PAGE_SIZE - 1) {
+       if (size & PAGE_SIZE_MASK) {
+               dm2->unused_end = PAGE_SIZE - (size & PAGE_SIZE_MASK);
+               dm2->flags |= DEBUGMEM_PARTIAL;
+               memset(dm2->state + (PAGE_SIZE - dm2->unused_end), 0, dm2->unused_end);
+               memset(debugmem_bank.baseaddr + (offset + startoffset + j) * PAGE_SIZE + (PAGE_SIZE - dm2->unused_end), 0x97, dm2->unused_end);
+       }
+}
        }
        debugmemptr = offset * PAGE_SIZE + extrasize + ((size + PAGE_SIZE - 1) & ~PAGE_SIZE_MASK);
        return dm;
@@ -946,7 +955,7 @@ uaecptr debugmem_allocmem(int mode, uae_u32 size, uae_u32 flags, uae_u32 caller)
 
 uae_u32 debugmem_freemem(int mode, uaecptr addr, uae_u32 size, uae_u32 caller)
 {
-       if (!debugmem_bank.baseaddr || addr < debugmem_bank.start)
+       if (!debugmem_bank.baseaddr || addr < debugmem_bank.start || addr >= debugmem_bank.start + debugmem_bank.allocated_size)
                return 0;
        if (mode > 0) {
                addr -= 4;
@@ -959,6 +968,28 @@ uae_u32 debugmem_freemem(int mode, uaecptr addr, uae_u32 size, uae_u32 caller)
        return 1;
 }
 
+void debugmem_trap(uaecptr stack)
+{
+       uae_u32 code = get_long(stack);
+       uae_u16 sr = get_word(stack + 4);
+       uae_u32 pc = get_long(stack + 6);
+       int format = 0;
+       console_out_f(_T("Trap #%d: SR=%04x PC=%08x"), code, sr, pc);
+       if (currprefs.cpu_model > 68000) {
+               uae_u16 sff = get_word(stack + 10);
+               console_out_f(_T(" Format=%04x"), sff);
+               format = sff >> 12;
+               if (format > 0) {
+                       uae_u32 addr = get_word(stack + 12);
+                       console_out_f(_T(" Address=%08x"), addr);
+               }
+       }
+       console_out_f(_T("\n"));
+       // always return back to faulted instruction
+       put_long(stack + 6, regs.instruction_pc_user_exception);
+       debugmem_break_pc(13, regs.instruction_pc_user_exception, 2);
+}
+
 static struct debugmemallocs *debugmem_reserve(uaecptr addr, uae_u32 size, uae_u32 parentid)
 {
        struct debugmemallocs *dm = getallocblock();
@@ -1103,8 +1134,12 @@ static struct stab *findstab(uae_u8 type, int *idxp)
 static void parse_stabs(void)
 {
        TCHAR *path = NULL;
+       TCHAR *pathprefix = NULL;
        struct stab *s;
        int idx;
+       static int pmindex;
+
+       pathprefix = cfgfile_option_get(currprefs.debugging_options, _T("pathprefix"));
 
        idx = 0;
        for (;;) {
@@ -1122,25 +1157,61 @@ static void parse_stabs(void)
                if (!s)
                        break;
                if (s->type == N_SO && s->string && s->string[_tcslen(s->string) - 1] != '/') {
-                       struct debugcodefile *cf = loadcodefile(NULL, s->string);
-                       if (!cf) {
-                               cf = loadcodefile(path, s->string);
-                               if (!cf) {
+                       int pm = pmindex;
+                       struct debugcodefile *cf = NULL;
+                       for (int pmi = 0; pmi <= 5; pmi++, pm++) {
+                               TCHAR path2[MAX_DPATH];
+                               TCHAR *f = NULL, *p = NULL;
+                               if (pm > 5)
+                                       pm = 0;
+                               if (pm == 5) {
+                                       // wsl path
                                        if (!_tcsnicmp(path, _T("/mnt/"), 5)) {
                                                TCHAR path2[MAX_DPATH];
                                                _stprintf(path2, _T("%c:/%s"), path[5], path + 7);
-                                               cf = loadcodefile(path2, s->string);
-                                       } else if (!_tcsnicmp(path, _T("/cygdrive/"), 10)) {
+                                               f = s->string;
+                                               p = path2;
+                                       }
+                               } else if (pm == 4) {
+                                       // cygwin path
+                                       if (!_tcsnicmp(path, _T("/cygdrive/"), 10)) {
                                                TCHAR path2[MAX_DPATH];
                                                _stprintf(path2, _T("%c:/%s"), path[10], path + 12);
-                                               cf = loadcodefile(path2, s->string);
+                                               f = s->string;
+                                               p = path2;
+                                       }
+                               } else if (pm == 3) {
+                                       // pathprefix + path + file
+                                       if (pathprefix) {
+                                               _stprintf(path2, _T("%s%s"), pathprefix, path);
+                                               f = s->string;
+                                               p = path2;
                                        }
-                                       if (!cf) {
-                                               console_out_f(_T("Failed to load '%s'\n"), s->string);
-                                               continue;
+                               } else if (pm == 2) {
+                                       // pathprefix + file
+                                       if (pathprefix) {
+                                               _stprintf(path2, _T("%s%s"), pathprefix, s->string);
+                                               f = path2;
                                        }
+                               } else if (pm == 1) {
+                                       // path + file
+                                       f = s->string;
+                                       p = path;
+                               } else {
+                                       // file
+                                       f = s->string;
                                }
+                               if (f) {
+                                       cf = loadcodefile(p, f);
+                                       if (cf)
+                                               break;
+                               }
+                       }
+                       if (!cf) {
+                               console_out_f(_T("Failed to load '%s'\n"), s->string);
+                               continue;
                        }
+                       pmindex = pm;
                        int linecnt = 0;
                        struct debugsymbol *last_func = NULL;
                        while (idx < stabscount) {
@@ -1272,6 +1343,7 @@ static void parse_stabs(void)
 
        }
        */
+       xfree(pathprefix);
 }
 
 uaecptr debugmem_reloc(uaecptr exeaddress, uae_u32 len, uaecptr task, uae_u32 *stack)
@@ -1885,6 +1957,17 @@ static bool debugger_load_library(const TCHAR *name)
                                p += len;
                        }
                        break;
+                       case 0x3f0: // HUNK_SYMBOL
+                       {
+                               for (;;) {
+                                       int size = gl(p);
+                                       p += 4;
+                                       if (!size)
+                                               break;
+                                       p += 4 * size + 4;
+                               }
+                       }
+                       break;
                        default:
                        console_out_f(_T("Unknown hunk %08x\n"), hunk);
                        goto end;
index d9d66573c1e63b5533041f7302fd70018a4999ad..5a93b483244043834b437ad98d070a2fd52283ea 100644 (file)
@@ -8973,8 +8973,12 @@ static uae_u32 REGPARAM2 mousehack_done (TrapContext *ctx)
        } else if (mode == 209) {
                // called if segtrack was enabled
                return 0;
+       } else if (mode == 210) {
+               // debug trapcode
+               debugmem_trap(trap_get_areg(ctx, 0));
        } else if (mode == 299) {
                return debugmem_exit();
+
        } else {
                write_log (_T("Unknown mousehack hook %d\n"), mode);
        }
index 404a7d6f3944f73be8a9e20c9ebe6021cd3f47a8..725579bebc20066feec5a0f738507cc6675447b8 100644 (file)
@@ -32,6 +32,7 @@ extern void debug (void);
 extern void debugger_change (int mode);
 extern void activate_debugger(void);
 extern void activate_debugger_new(void);
+extern void activate_debugger_new_pc(uaecptr pc, int len);
 extern void deactivate_debugger (void);
 extern int notinrom (void);
 extern const TCHAR *debuginfo (int);
index 0699ce59adcdc3a1c6e30a53762f10a956f768df..25a633050f8716391dabd30ba2c9de4535d7acb1 100644 (file)
@@ -3,6 +3,7 @@ uaecptr debugmem_reloc(uaecptr exeaddress, uae_u32 len, uaecptr task, uae_u32 *s
 void debugmem_init(void);
 uaecptr debugmem_allocmem(int mode, uae_u32 size, uae_u32 flags, uae_u32 caller);
 uae_u32 debugmem_freemem(int mode, uaecptr addr, uae_u32 size, uae_u32 caller);
+void debugmem_trap(uaecptr addr);
 void debugmem_addsegs(TrapContext *ctx, uaecptr seg, uaecptr name, uae_u32 lock);
 void debugmem_remsegs(uaecptr seg);
 uae_u32 debugmem_exit(void);
index 8ceb3938d66e5b7f789ff8f2affc17eff7e3528f..27a903e070c947ea3084bf4fd782b63713db516e 100644 (file)
@@ -171,6 +171,7 @@ struct regstruct
        uae_u8 *pc_oldp;
        uae_u16 opcode;
        uae_u32 instruction_pc;
+       uae_u32 instruction_pc_user_exception;
 
        uae_u16 irc, ir, db;
        volatile uae_atomic spcflags;
index c4524bc9cda72c943de3bbaa8720666c16a4d56b..a28db4f362f86f40ae3ce5639ec2f2495a5d4cc7 100644 (file)
@@ -457,6 +457,7 @@ struct uae_prefs {
 
        bool start_debugger;
        int debugging_features;
+       TCHAR debugging_options[MAX_DPATH];
        bool start_gui;
 
        KbdLang keyboard_lang;
index 6a1c2fb3e34c56832a8d46980327ebf03e494e5e..e148b71d0ac65fdbafcd27425c8e3e08f90f231f 100644 (file)
@@ -3650,6 +3650,9 @@ static void ExceptionX (int nr, uaecptr address)
        if (cpu_tracer) {
                cputrace.state = nr;
        }
+       if (!regs.s) {
+               regs.instruction_pc_user_exception = m68k_getpc();
+       }
 
 #ifdef JIT
        if (currprefs.cachesize)