summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Stephen Oberholtzer <stevie@qrpff.net>2020-05-07 16:27:29 -0400
committer Stephen Oberholtzer <stevie@qrpff.net>2020-05-07 16:27:29 -0400
commitfd62dad94985384057e83a0853e517470ca05bd9 (patch)
tree2f8dbe452ba9f916632ede761d4b7efc1dc43ffb
parent5cf19257895bfe7daf06365e53784bc41455a530 (diff)
Debugger - add `-debuglog` option to log debug console output to file
When this option is specified, all console output is echoed to a log file. Some caveats/limitations: - The file-open process was copied from -log, so it has the same limits - Filename is hard-coded (debug.log) - File is overwritten if it exists - File is opened during emulation initialization - Thus, the file is cleared if you invoke the "Hard Reset" debugger command - Probably some other details I don't know about - Logging works as such: When a string is appended to the scrollback buffer, it is also written to the log file. Some commands forcibly wrap their output (e.g. `help` to 80 columns.) Because this wrapping is done inside the scrollback buffer, the text written to the file is not wrapped. This can be seen with `help execution`.
-rw-r--r--src/emu/debug/debugcon.cpp43
-rw-r--r--src/emu/debug/debugcon.h4
-rw-r--r--src/emu/emuopts.cpp1
-rw-r--r--src/emu/emuopts.h2
-rw-r--r--src/emu/machine.cpp10
-rw-r--r--src/emu/machine.h7
6 files changed, 61 insertions, 6 deletions
diff --git a/src/emu/debug/debugcon.cpp b/src/emu/debug/debugcon.cpp
index 2c5989a8faa..55edea82c46 100644
--- a/src/emu/debug/debugcon.cpp
+++ b/src/emu/debug/debugcon.cpp
@@ -37,6 +37,7 @@ debugger_console::debugger_console(running_machine &machine)
: m_machine(machine)
, m_console_textbuf(nullptr)
, m_errorlog_textbuf(nullptr)
+ , m_logfile(nullptr)
{
/* allocate text buffers */
m_console_textbuf = text_buffer_alloc(CONSOLE_BUF_SIZE, CONSOLE_MAX_LINES);
@@ -47,6 +48,9 @@ debugger_console::debugger_console(running_machine &machine)
if (!m_errorlog_textbuf)
return;
+ /* due to initialization order, @machine is holding our debug.log handle */
+ m_logfile = machine.steal_debuglogfile();
+
/* print the opening lines */
printf("%s debugger version %s\n", emulator_info::get_appname(), emulator_info::get_build_version());
printf("Currently targeting %s (%s)\n", m_machine.system().name, m_machine.system().type.fullname());
@@ -84,6 +88,9 @@ void debugger_console::exit()
/* free the command list */
m_commandlist.clear();
+
+ /* close the logfile, if any */
+ m_logfile = nullptr;
}
@@ -514,6 +521,34 @@ std::string debugger_console::cmderr_to_string(CMDERR error)
***************************************************************************/
+
+/*-------------------------------------------------
+ print_core - write preformatted text
+ to the debug console
+-------------------------------------------------*/
+
+void debugger_console::print_core(const char *text)
+{
+ // FIXME: this invokes strlen() twice; compute it once and pass it to text_buffer_print
+ text_buffer_print(m_console_textbuf, text);
+ if (m_logfile)
+ m_logfile->write(text, strlen(text));
+}
+
+/*-------------------------------------------------
+ print_core_wrap - write preformatted text
+ to the debug console, with wrapping
+-------------------------------------------------*/
+
+void debugger_console::print_core_wrap(const char *text, int wrapcol)
+{
+ // FIXME: this invokes strlen() twice; compute it once and pass it to text_buffer_print
+ // FIXME: also look into honoring wrapcol for the logfile
+ text_buffer_print_wrap(m_console_textbuf, text, wrapcol);
+ if (m_logfile)
+ m_logfile->write(text, strlen(text));
+}
+
/*-------------------------------------------------
vprintf - vprintfs the given arguments using
the format to the debug console
@@ -521,7 +556,7 @@ std::string debugger_console::cmderr_to_string(CMDERR error)
void debugger_console::vprintf(util::format_argument_pack<std::ostream> const &args)
{
- text_buffer_print(m_console_textbuf, util::string_format(args).c_str());
+ print_core(util::string_format(args).c_str());
/* force an update of any console views */
m_machine.debug_view().update_all(DVT_CONSOLE);
@@ -529,7 +564,7 @@ void debugger_console::vprintf(util::format_argument_pack<std::ostream> const &a
void debugger_console::vprintf(util::format_argument_pack<std::ostream> &&args)
{
- text_buffer_print(m_console_textbuf, util::string_format(std::move(args)).c_str());
+ print_core(util::string_format(std::move(args)).c_str());
/* force an update of any console views */
m_machine.debug_view().update_all(DVT_CONSOLE);
@@ -543,7 +578,7 @@ void debugger_console::vprintf(util::format_argument_pack<std::ostream> &&args)
void debugger_console::vprintf_wrap(int wrapcol, util::format_argument_pack<std::ostream> const &args)
{
- text_buffer_print_wrap(m_console_textbuf, util::string_format(args).c_str(), wrapcol);
+ print_core_wrap(util::string_format(args).c_str(), wrapcol);
/* force an update of any console views */
m_machine.debug_view().update_all(DVT_CONSOLE);
@@ -551,7 +586,7 @@ void debugger_console::vprintf_wrap(int wrapcol, util::format_argument_pack<std:
void debugger_console::vprintf_wrap(int wrapcol, util::format_argument_pack<std::ostream> &&args)
{
- text_buffer_print_wrap(m_console_textbuf, util::string_format(std::move(args)).c_str(), wrapcol);
+ print_core_wrap(util::string_format(std::move(args)).c_str(), wrapcol);
/* force an update of any console views */
m_machine.debug_view().update_all(DVT_CONSOLE);
diff --git a/src/emu/debug/debugcon.h b/src/emu/debug/debugcon.h
index e57b06a7378..ac7957e4aa1 100644
--- a/src/emu/debug/debugcon.h
+++ b/src/emu/debug/debugcon.h
@@ -118,6 +118,9 @@ private:
CMDERR internal_execute_command(bool execute, int params, char **param);
CMDERR internal_parse_command(const std::string &original_command, bool execute);
+ void print_core(const char *text); // core text output
+ void print_core_wrap(const char *text, int wrapcol); // core text output
+
struct debug_command
{
debug_command(const char *_command, u32 _flags, int _ref, int _minparams, int _maxparams, std::function<void(int, const std::vector<std::string> &)> _handler);
@@ -140,6 +143,7 @@ private:
std::forward_list<debug_command> m_commandlist;
std::unique_ptr<std::istream> m_source_file; // script source file
+ std::unique_ptr<emu_file> m_logfile; // logfile for debug console output
};
#endif // MAME_EMU_DEBUG_DEBUGCON_H
diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp
index a48a4f80811..a0ff529462e 100644
--- a/src/emu/emuopts.cpp
+++ b/src/emu/emuopts.cpp
@@ -176,6 +176,7 @@ const options_entry emu_options::s_option_entries[] =
{ OPTION_DEBUG ";d", "0", OPTION_BOOLEAN, "enable/disable debugger" },
{ OPTION_UPDATEINPAUSE, "0", OPTION_BOOLEAN, "keep calling video updates while in pause" },
{ OPTION_DEBUGSCRIPT, nullptr, OPTION_STRING, "script for debugger" },
+ { OPTION_DEBUGLOG, "0", OPTION_BOOLEAN, "write debug console output to debug.log" },
// comm options
{ nullptr, nullptr, OPTION_HEADER, "CORE COMM OPTIONS" },
diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h
index a1a23e77a2b..5a4bc3f118b 100644
--- a/src/emu/emuopts.h
+++ b/src/emu/emuopts.h
@@ -154,6 +154,7 @@
#define OPTION_OSLOG "oslog"
#define OPTION_UPDATEINPAUSE "update_in_pause"
#define OPTION_DEBUGSCRIPT "debugscript"
+#define OPTION_DEBUGLOG "debuglog"
// core misc options
#define OPTION_DRC "drc"
@@ -430,6 +431,7 @@ public:
bool oslog() const { return bool_value(OPTION_OSLOG); }
const char *debug_script() const { return value(OPTION_DEBUGSCRIPT); }
bool update_in_pause() const { return bool_value(OPTION_UPDATEINPAUSE); }
+ bool debuglog() const { return bool_value(OPTION_DEBUGLOG); }
// core misc options
bool drc() const { return bool_value(OPTION_DRC); }
diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp
index 7b86af34925..8955446ec3c 100644
--- a/src/emu/machine.cpp
+++ b/src/emu/machine.cpp
@@ -314,12 +314,20 @@ int running_machine::run(bool quiet)
m_logfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
osd_file::error filerr = m_logfile->open("error.log");
if (filerr != osd_file::error::NONE)
- throw emu_fatalerror("running_machine::run: unable to open log file");
+ throw emu_fatalerror("running_machine::run: unable to open error.log file");
using namespace std::placeholders;
add_logerror_callback(std::bind(&running_machine::logfile_callback, this, _1));
}
+ if (options().debug() && options().debuglog())
+ {
+ m_debuglogfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ osd_file::error filerr = m_debuglogfile->open("debug.log");
+ if (filerr != osd_file::error::NONE)
+ throw emu_fatalerror("running_machine::run: unable to open debug.log file");
+ }
+
// then finish setting up our local machine
start();
diff --git a/src/emu/machine.h b/src/emu/machine.h
index 205988fbbe6..53ebe7f5f87 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -264,6 +264,10 @@ private:
public:
// debugger-related information
u32 debug_flags; // the current debug flags
+ bool debug_enabled() { return (debug_flags & DEBUG_FLAG_ENABLED) != 0; }
+
+ // used by debug_console to take ownership of the debug.log file
+ std::unique_ptr<emu_file> steal_debuglogfile() { return std::move(m_debuglogfile); }
private:
class side_effects_disabler {
@@ -346,7 +350,8 @@ private:
time_t m_base_time; // real time at initial emulation time
std::string m_basename; // basename used for game-related paths
int m_sample_rate; // the digital audio sample rate
- std::unique_ptr<emu_file> m_logfile; // pointer to the active log file
+ std::unique_ptr<emu_file> m_logfile; // pointer to the active error.log file
+ std::unique_ptr<emu_file> m_debuglogfile; // pointer to the active debug.log file
// load/save management
enum class saveload_schedule