Skip to content

Commit 52c88a8

Browse files
authored
Debugger: Add dbg.logexec option to log debugger script execution output (fixes #1121) (#1122)
* Fixes issue #1121 * make exec log output more conform Prompt UI * removed double run(command) * Use red when not able to write exec output to file * Added `logExec` as debug command + updated documentation * allow for toggling logExec in script * dbg.logexec checked at start of exec run * Added dbg.script command line parameter
1 parent 9d7d1d2 commit 52c88a8

File tree

6 files changed

+82
-2
lines changed

6 files changed

+82
-2
lines changed

docs/debugger.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ <h2><a name="Startup">Startup</a></h2>
300300
the current settings. You can also manually edit the file and add more commands.
301301
</br></br>
302302
</li>
303+
<li>
304+
Script specified via "-dbg.script" command line parameter</br>
305+
You can specify a custom script file to be executed at debugger startup using
306+
the <b>-dbg.script &lt;file&gt;</b> command line parameter. This script will be
307+
executed after "autoexec.script" and "&lt;rom_filename&gt;.script" (if present),
308+
allowing you to override or extend their settings for specific debugging sessions.
309+
</br></br>
310+
</li>
303311
<li>
304312
"&lt;rom_filename&gt;.cfg"</br>
305313
This file is described in <a href="#DistellaConfiguration">
@@ -1007,6 +1015,7 @@ <h3><a name="PromptCommands">Prompt Commands</a></h3>
10071015
loadAllStates - Load all emulator states
10081016
loadState - Load emulator state xx (0-9)
10091017
logBreaks - Logs breaks and traps and continues emulation
1018+
logExec - Logs script execution output to file when enabled
10101019
logTrace - Logs emulation (note: emulation may slow down and the log becomes huge soon)
10111020
n - Negative Flag: set (0 or 1), or toggle (no arg)
10121021
palette - Show current TIA palette

docs/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,6 +3436,18 @@ <h2><b><a name="CommandLine">Using the Command Line</a></b></h2>
34363436
<td>Debugger considers/ignores 'ghost' reads for trap addresses</td>
34373437
</tr>
34383438

3439+
<tr>
3440+
<td><pre>-dbg.logexec &lt;0|1&gt;</pre></td>
3441+
<td>Log script execution output to file. When enabled, the 'exec' command
3442+
writes all command results to [script_path].output.txt</td>
3443+
</tr>
3444+
3445+
<tr>
3446+
<td><pre>-dbg.script &lt;file&gt;</pre></td>
3447+
<td>Execute the specified script file on debugger startup. The script will be
3448+
executed after autoexec.script and [romname].script (if present)</td>
3449+
</tr>
3450+
34393451
<tr>
34403452
<td><pre>-dbg.uhex &lt;0|1&gt;</pre></td>
34413453
<td>Lower-/uppercase HEX display</td>

src/debugger/Debugger.cxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ string Debugger::autoExec(StringList* history)
180180
const FSNode romname(path);
181181
buf << myParser->exec(romname, history) << '\n';
182182

183+
// Also, script specified via -dbg.script command line parameter
184+
const string scriptPath = myOSystem.settings().getString("dbg.script");
185+
if(!scriptPath.empty())
186+
{
187+
const FSNode script(scriptPath);
188+
buf << myParser->exec(script, history) << '\n';
189+
}
190+
183191
// Init builtins
184192
for(const auto& func: ourBuiltinFunctions)
185193
{

src/debugger/DebuggerParser.cxx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,27 +132,54 @@ string DebuggerParser::run(string_view command)
132132
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133133
string DebuggerParser::exec(const FSNode& file, StringList* history)
134134
{
135+
const bool logExec = settings.getBool("dbg.logexec");
136+
135137
if(file.exists())
136138
{
137139
stringstream in;
138140
try { file.read(in); }
139141
catch(...) { return red("script file \'" + file.getShortPath() + "\' not found"); }
140142

141143
ostringstream buf;
144+
stringstream logBuf; // used to log the results of commands, if enabled
142145
int count = 0;
143146
string command;
144147
while( !in.eof() )
145148
{
146149
if(!getline(in, command))
147150
break;
148151

152+
// skip empty/comment lines
153+
command = BSPF::trim(command);
154+
if(command.empty() || command[0] == ';')
155+
continue;
156+
149157
++execDepth;
150-
run(command);
158+
if(logExec)
159+
{
160+
logBuf << "> " << command << '\n';
161+
const string result = run(command);
162+
if(!result.empty() && result != "_EXIT_DEBUGGER" && result != "_NO_PROMPT")
163+
logBuf << result << '\n';
164+
}
165+
else
166+
{
167+
run(command);
168+
}
151169
--execDepth;
152170
if (history != nullptr)
153171
history->push_back(command);
154172
count++;
155173
}
174+
175+
// write execution log if enabled
176+
if(logExec && !logBuf.str().empty())
177+
{
178+
const FSNode logNode(file.getPath() + ".output.txt");
179+
try { logNode.write(logBuf);}
180+
catch(...) { buf << red("\nUnable to write exec output to file \'" + logNode.getShortPath() + "\'\n"); }
181+
}
182+
156183
buf << "\nExecuted " << count << " command" << (count != 1 ? "s" : "") << " from \""
157184
<< file.getShortPath() << "\"";
158185

@@ -1844,6 +1871,15 @@ void DebuggerParser::executeLogBreaks()
18441871
commandResult << "logBreaks " << (enable ? "enabled" : "disabled");
18451872
}
18461873

1874+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1875+
void DebuggerParser::executeLogExec()
1876+
{
1877+
const bool enable = !settings.getBool("dbg.logexec");
1878+
1879+
settings.setValue("dbg.logexec", enable);
1880+
commandResult << "logExec " << (enable ? "enabled" : "disabled");
1881+
}
1882+
18471883
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18481884
void DebuggerParser::executeLogTrace()
18491885
{
@@ -3421,6 +3457,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
34213457
std::mem_fn(&DebuggerParser::executeLogBreaks)
34223458
},
34233459

3460+
{
3461+
"logExec",
3462+
"Toggle script execution logging to file",
3463+
"Example: logExec (no parameters)",
3464+
false,
3465+
true,
3466+
{ Parameters::ARG_END_ARGS },
3467+
std::mem_fn(&DebuggerParser::executeLogExec)
3468+
},
3469+
34243470
{
34253471
"logTrace",
34263472
"Toggle emulation logging",

src/debugger/DebuggerParser.hxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class DebuggerParser
103103
std::array<Parameters, 10> parms;
104104
std::function<void (DebuggerParser*)> executor;
105105
};
106-
using CommandArray = std::array<Command, 111>;
106+
using CommandArray = std::array<Command, 112>;
107107
static CommandArray commands;
108108

109109
struct Trap
@@ -214,6 +214,7 @@ class DebuggerParser
214214
void executeLoadConfig();
215215
void executeLoadState();
216216
void executeLogBreaks();
217+
void executeLogExec();
217218
void executeLogTrace();
218219
void executeN();
219220
void executePalette();

src/emucore/Settings.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,10 @@ Settings::Settings()
235235
setPermanent("dbg.uhex", "false");
236236
setPermanent("dbg.ghostreadstrap", "true");
237237
setPermanent("dbg.logbreaks", "false");
238+
setPermanent("dbg.logexec", "false");
238239
setPermanent("dbg.logtrace", "false");
239240
setPermanent("dbg.autosave", "false");
241+
setPermanent("dbg.script", "");
240242
setPermanent("dis.resolve", "true");
241243
setPermanent("dis.gfxformat", "2");
242244
setPermanent("dis.showaddr", "true");
@@ -737,8 +739,10 @@ void Settings::usage()
737739
<< " -dbg.ghostreadstrap <1|0> Debugger traps on 'ghost' reads\n"
738740
<< " -dbg.uhex <0|1> Lower-/uppercase HEX display\n"
739741
<< " -dbg.logbreaks <0|1> Log breaks and traps and continue emulation\n"
742+
<< " -dbg.logexec <0|1> Log script execution output to file\n"
740743
<< " -dbg.logtrace <0|1> Log emulation\n"
741744
<< " -dbg.autosave <0|1> Automatically save breaks, traps etc.\n"
745+
<< " -dbg.script <file> Execute script file on debugger startup\n"
742746
<< " -break <address> Set a breakpoint at 'address'\n"
743747
<< " -debug Start in debugger mode\n\n"
744748
<< " -bs <arg> Sets the 'Cartridge.Type' (bankswitch) property\n"

0 commit comments

Comments
 (0)