--- hatari/src/debug/debugui.c 2019/04/09 08:54:23 1.1.1.7 +++ hatari/src/debug/debugui.c 2019/04/09 08:56:50 1.1.1.9 @@ -29,6 +29,7 @@ const char DebugUI_fileid[] = "Hatari de #include "m68000.h" #include "memorySnapShot.h" #include "options.h" +#include "reset.h" #include "screen.h" #include "statusbar.h" #include "str.h" @@ -43,8 +44,7 @@ const char DebugUI_fileid[] = "Hatari de #include "evaluate.h" #include "history.h" #include "symbols.h" - -int bExceptionDebugging; +#include "vars.h" FILE *debugOutput; @@ -113,17 +113,25 @@ static void DebugUI_SetLogDefault(void) */ static int DebugUI_SetLogFile(int nArgc, char *psArgs[]) { - File_Close(debugOutput); - debugOutput = NULL; + if (debugOutput != stderr) + { + fprintf(stderr, "Debug log closed.\n"); + File_Close(debugOutput); + } + debugOutput = stderr; if (nArgc > 1) - debugOutput = File_Open(psArgs[1], "w"); - - if (debugOutput) - fprintf(stderr, "Debug log '%s' opened.\n", psArgs[1]); - else - debugOutput = stderr; - + { + if ((debugOutput = File_Open(psArgs[1], "w"))) + { + fprintf(stderr, "Debug log '%s' opened.\n", psArgs[1]); + } + else + { + fprintf(stderr, "Debug log '%s' opening FAILED.\n", psArgs[1]); + debugOutput = stderr; + } + } return DEBUGGER_CMDDONE; } @@ -331,7 +339,7 @@ static int DebugUI_SetOptions(int argc, } arg = argv[1]; - for (i = 0; i < ARRAYSIZE(bases); i++) + for (i = 0; i < ARRAY_SIZE(bases); i++) { if (strcasecmp(bases[i].name, arg) == 0) { @@ -414,6 +422,29 @@ static int DebugUI_Rename(int argc, char /** + * Command: Reset emulation + */ +static char *DebugUI_MatchReset(const char *text, int state) +{ + static const char* types[] = { "cold", "hard", "soft", "warm" }; + return DebugUI_MatchHelper(types, ARRAY_SIZE(types), text, state); +} +static int DebugUI_Reset(int argc, char *argv[]) +{ + if (argc != 2) + return DebugUI_PrintCmdHelp(argv[0]); + + if (strcmp(argv[1], "soft") == 0 || strcmp(argv[1], "warm") == 0) + Reset_Warm(); + else if (strcmp(argv[1], "cold") == 0 || strcmp(argv[1], "hard") == 0) + Reset_Cold(); + else + return DebugUI_PrintCmdHelp(argv[0]); + return DEBUGGER_END; +} + + +/** * Command: Read debugger commands from a file */ static int DebugUI_CommandsFromFile(int argc, char *argv[]) @@ -583,25 +614,20 @@ static int DebugUI_ParseCommand(const ch delim = " \t"; /* Separate arguments and put the pointers into psArgs */ - for (nArgc = 1; nArgc < ARRAYSIZE(psArgs); nArgc++) + for (nArgc = 1; nArgc < ARRAY_SIZE(psArgs); nArgc++) { psArgs[nArgc] = strtok(NULL, delim); if (psArgs[nArgc] == NULL) break; } - if (!debugOutput) { - /* make sure also calls from control.c work */ - DebugUI_SetLogDefault(); - } - /* ... and execute the function */ retval = debugCommand[i].pFunction(nArgc, psArgs); /* Save commando string if it can be repeated */ if (retval == DEBUGGER_CMDCONT) { if (psArgs[0] != sLastCmd) - strncpy(sLastCmd, psArgs[0], sizeof(sLastCmd)); + strlcpy(sLastCmd, psArgs[0], sizeof(sLastCmd)); } else sLastCmd[0] = '\0'; @@ -788,8 +814,7 @@ static char *DebugUI_GetCommand(char *in */ static void DebugUI_FreeCommand(char *input) { - if (input) - free(input); + free(input); } /** @@ -829,14 +854,14 @@ static const dbgcommand_t uicommand[] = "\n" "\tChange Hatari work directory.", false }, - { DebugUI_Evaluate, Symbols_MatchCpuAddress, + { DebugUI_Evaluate, Vars_MatchCpuVariable, "evaluate", "e", "evaluate an expression", "\n" "\tEvaluate an expression and show the result. Expression can\n" - "\tinclude CPU register and symbol names, those are replaced\n" - "\tby their values. Supported operators in expressions are,\n" - "\tin the decending order of precedence:\n" + "\tinclude CPU register & symbol and Hatari variable names.\n" + "\tThose are replaced by their values. Supported operators in\n" + "\texpressions are, in the decending order of precedence:\n" "\t\t(), +, -, ~, *, /, +, -, >>, <<, ^, &, |\n" "\tParenthesis will fetch a _long_ value from the address\n" "\tto what the value inside it evaluates to. Prefixes can be\n" @@ -855,7 +880,7 @@ static const dbgcommand_t uicommand[] = { History_Parse, History_Match, "history", "hi", "show last CPU/DSP PC values & executed instructions", - "cpu|dsp|on|off| [limit]\n" + "cpu|dsp|on|off| [limit]|save \n" "\t'cpu' and 'dsp' enable instruction history tracking for just given\n" "\tprocessor, 'on' tracks them both, 'off' will disable history.\n" "\tOptional 'limit' will set how many past instructions are tracked.\n" @@ -895,14 +920,18 @@ static const dbgcommand_t uicommand[] = "old new\n" "\tRenames file with 'old' name to 'new'.", false }, + { DebugUI_Reset, DebugUI_MatchReset, + "reset", "", + "reset emulation", + "\n", + false }, { DebugUI_SetOptions, Opt_MatchOption, "setopt", "o", "set Hatari command line and debugger options", "[bin|dec|hex|]\n" - "\tSet Hatari options. For example to enable exception catching,\n" - "\tuse following command line option: 'setopt --debug'. Special\n" - "\t'bin', 'dec' and 'hex' arguments change the default number base\n" - "\tused in debugger.", + "\tSpecial 'bin', 'dec' and 'hex' arguments change the default\n" + "\tnumber base used in debugger. lists available command\n" + "\tline options, 'setopt --help' their descriptions.", false }, { DebugUI_DoMemorySnap, NULL, "stateload", "", @@ -924,6 +953,13 @@ static const dbgcommand_t uicommand[] = "\tsettings. For example, to enable CPU disassembly and VBL\n" "\ttracing, use:\n\t\ttrace cpu_disasm,video_hbl", false }, + { Vars_List, NULL, + "variables", "v", + "List builtin symbols / variables", + "\n" + "\tList Hatari debugger builtin symbols / variables and their values.\n" + "\tThey're accepted by breakpoints and evaluate command.", + false }, { DebugUI_QuitEmu, NULL, "quit", "q", "quit emulator", @@ -945,6 +981,9 @@ void DebugUI_Init(void) if (debugCommands) return; + if (!debugOutput) + DebugUI_SetLogDefault(); + /* if you want disassembly or memdumping to start/continue from * specific address, you can set them in these functions. */ @@ -952,7 +991,7 @@ void DebugUI_Init(void) cpucmds = DebugCpu_Init(&cpucmd); /* on first time copy the command structures to a single table */ - debugCommands = ARRAYSIZE(uicommand); + debugCommands = ARRAY_SIZE(uicommand); debugCommand = malloc(sizeof(dbgcommand_t) * (dspcmds + cpucmds + debugCommands)); assert(debugCommand); @@ -995,6 +1034,15 @@ void DebugUI(debug_reason_t reason) static const char *welcome = "\n----------------------------------------------------------------------" "\nYou have entered debug mode. Type c to continue emulation, h for help.\n"; + static bool recursing; + + if (recursing) + { + fprintf(stderr, "WARNING: recursive call to DebugUI (through profiler debug option?)!\n"); + recursing = false; + return; + } + recursing = true; History_Mark(reason); @@ -1052,10 +1100,11 @@ void DebugUI(debug_reason_t reason) DebugUI_FreeCommand(psCmd); Log_SetAlertLevel(alertLevel); - DebugUI_SetLogDefault(); DebugCpu_SetDebugging(); DebugDsp_SetDebugging(); + + recursing = false; } @@ -1092,8 +1141,7 @@ bool DebugUI_ParseFile(const char *path, if (chdir(dir) != 0) { perror("ERROR"); - if (olddir) - free(olddir); + free(olddir); free(dir); fclose(fp); return false; @@ -1190,10 +1238,11 @@ void DebugUI_Exceptions(int nr, long pc) { EXCEPT_ZERODIV, "Div by zero" }, /* 5 */ { EXCEPT_CHK, "CHK" }, /* 6 */ { EXCEPT_TRAPV, "TRAPV" }, /* 7 */ - { EXCEPT_PRIVILEGE, "Privilege violation" } /* 8 */ + { EXCEPT_PRIVILEGE, "Privilege violation" }, /* 8 */ + { EXCEPT_TRACE, "Trace" } /* 9 */ }; nr -= 2; - if (nr < 0 || nr >= ARRAYSIZE(ex)) + if (nr < 0 || nr >= ARRAY_SIZE(ex)) return; if (!(ExceptionDebugMask & ex[nr].flag)) return;