mirror of
https://github.com/holub/mame
synced 2025-04-28 19:14:55 +03:00
Added suspend and resume debugger commands (#3411)
This commit is contained in:
parent
729c0ca3ed
commit
06a09d3821
@ -163,6 +163,8 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
|
|||||||
m_console.register_command("focus", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1, _2));
|
m_console.register_command("focus", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1, _2));
|
||||||
m_console.register_command("ignore", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1, _2));
|
m_console.register_command("ignore", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1, _2));
|
||||||
m_console.register_command("observe", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1, _2));
|
m_console.register_command("observe", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1, _2));
|
||||||
|
m_console.register_command("suspend", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1, _2));
|
||||||
|
m_console.register_command("resume", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1, _2));
|
||||||
|
|
||||||
m_console.register_command("comadd", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2));
|
m_console.register_command("comadd", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2));
|
||||||
m_console.register_command("//", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2));
|
m_console.register_command("//", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2));
|
||||||
@ -1023,6 +1025,109 @@ void debugger_commands::execute_observe(int ref, const std::vector<std::string>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
execute_suspend - suspend execution on cpu
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void debugger_commands::execute_suspend(int ref, const std::vector<std::string> ¶ms)
|
||||||
|
{
|
||||||
|
/* if there are no parameters, dump the ignore list */
|
||||||
|
if (params.empty())
|
||||||
|
{
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
/* loop over all executable devices */
|
||||||
|
for (device_execute_interface &exec : execute_interface_iterator(m_machine.root_device()))
|
||||||
|
|
||||||
|
/* build up a comma-separated list */
|
||||||
|
if (exec.device().debug()->suspended())
|
||||||
|
{
|
||||||
|
if (buffer.empty())
|
||||||
|
buffer = string_format("Currently suspended device '%s'", exec.device().tag());
|
||||||
|
else
|
||||||
|
buffer.append(string_format(", '%s'", exec.device().tag()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* special message for none */
|
||||||
|
if (buffer.empty())
|
||||||
|
buffer = string_format("No currently suspended devices");
|
||||||
|
m_console.printf("%s\n", buffer.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
device_t *devicelist[MAX_COMMAND_PARAMS];
|
||||||
|
|
||||||
|
/* validate parameters */
|
||||||
|
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||||
|
if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||||
|
{
|
||||||
|
/* make sure this isn't the last live CPU */
|
||||||
|
bool gotone = false;
|
||||||
|
for (device_execute_interface &exec : execute_interface_iterator(m_machine.root_device()))
|
||||||
|
if (&exec.device() != devicelist[paramnum] && !exec.device().debug()->suspended())
|
||||||
|
{
|
||||||
|
gotone = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!gotone)
|
||||||
|
{
|
||||||
|
m_console.printf("Can't suspend all devices!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
devicelist[paramnum]->debug()->suspend(true);
|
||||||
|
m_console.printf("Suspended device '%s'\n", devicelist[paramnum]->tag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
execute_resume - Resume execution on CPU
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void debugger_commands::execute_resume(int ref, const std::vector<std::string> ¶ms)
|
||||||
|
{
|
||||||
|
/* if there are no parameters, dump the ignore list */
|
||||||
|
if (params.empty())
|
||||||
|
{
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
/* loop over all executable devices */
|
||||||
|
for (device_execute_interface &exec : execute_interface_iterator(m_machine.root_device()))
|
||||||
|
|
||||||
|
/* build up a comma-separated list */
|
||||||
|
if (exec.device().debug()->suspended())
|
||||||
|
{
|
||||||
|
if (buffer.empty())
|
||||||
|
buffer = string_format("Currently suspended device '%s'", exec.device().tag());
|
||||||
|
else
|
||||||
|
buffer.append(string_format(", '%s'", exec.device().tag()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* special message for none */
|
||||||
|
if (buffer.empty())
|
||||||
|
buffer = string_format("No currently suspended devices");
|
||||||
|
m_console.printf("%s\n", buffer.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
device_t *devicelist[MAX_COMMAND_PARAMS];
|
||||||
|
|
||||||
|
/* validate parameters */
|
||||||
|
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||||
|
if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||||
|
{
|
||||||
|
devicelist[paramnum]->debug()->suspend(false);
|
||||||
|
m_console.printf("Resumed device '%s'\n", devicelist[paramnum]->tag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
execute_comment - add a comment to a line
|
execute_comment - add a comment to a line
|
||||||
|
@ -110,6 +110,8 @@ private:
|
|||||||
void execute_focus(int ref, const std::vector<std::string> ¶ms);
|
void execute_focus(int ref, const std::vector<std::string> ¶ms);
|
||||||
void execute_ignore(int ref, const std::vector<std::string> ¶ms);
|
void execute_ignore(int ref, const std::vector<std::string> ¶ms);
|
||||||
void execute_observe(int ref, const std::vector<std::string> ¶ms);
|
void execute_observe(int ref, const std::vector<std::string> ¶ms);
|
||||||
|
void execute_suspend(int ref, const std::vector<std::string> ¶ms);
|
||||||
|
void execute_resume(int ref, const std::vector<std::string> ¶ms);
|
||||||
void execute_next(int ref, const std::vector<std::string> ¶ms);
|
void execute_next(int ref, const std::vector<std::string> ¶ms);
|
||||||
void execute_comment_add(int ref, const std::vector<std::string> ¶ms);
|
void execute_comment_add(int ref, const std::vector<std::string> ¶ms);
|
||||||
void execute_comment_del(int ref, const std::vector<std::string> ¶ms);
|
void execute_comment_del(int ref, const std::vector<std::string> ¶ms);
|
||||||
|
@ -1820,6 +1820,29 @@ void device_debug::ignore(bool ignore)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// suspend
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void device_debug::suspend(bool suspend)
|
||||||
|
{
|
||||||
|
assert(m_exec != nullptr);
|
||||||
|
|
||||||
|
if (suspend) {
|
||||||
|
m_flags |= DEBUG_FLAG_SUSPENDED;
|
||||||
|
m_exec->suspend(SUSPEND_REASON_HALT, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_flags &= ~DEBUG_FLAG_SUSPENDED;
|
||||||
|
m_exec->resume(SUSPEND_REASON_HALT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (&m_device == m_device.machine().debugger().cpu().live_cpu() && suspend)
|
||||||
|
{
|
||||||
|
assert(m_exec != nullptr);
|
||||||
|
go_next_device();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// single_step - single step the device past the
|
// single_step - single step the device past the
|
||||||
|
@ -189,6 +189,10 @@ public:
|
|||||||
void ignore(bool ignore = true);
|
void ignore(bool ignore = true);
|
||||||
bool observing() const { return ((m_flags & DEBUG_FLAG_OBSERVING) != 0); }
|
bool observing() const { return ((m_flags & DEBUG_FLAG_OBSERVING) != 0); }
|
||||||
|
|
||||||
|
// debugger suspend/unsuspend
|
||||||
|
void suspend(bool suspend = true);
|
||||||
|
bool suspended() const { return ((m_flags & DEBUG_FLAG_SUSPENDED) != 0); }
|
||||||
|
|
||||||
// single stepping
|
// single stepping
|
||||||
void single_step(int numsteps = 1);
|
void single_step(int numsteps = 1);
|
||||||
void single_step_over(int numsteps = 1);
|
void single_step_over(int numsteps = 1);
|
||||||
@ -447,6 +451,7 @@ private:
|
|||||||
static constexpr u32 DEBUG_FLAG_STOP_EXCEPTION = 0x00000800; // there is a pending stop on the next exception
|
static constexpr u32 DEBUG_FLAG_STOP_EXCEPTION = 0x00000800; // there is a pending stop on the next exception
|
||||||
static constexpr u32 DEBUG_FLAG_STOP_VBLANK = 0x00001000; // there is a pending stop on the next VBLANK
|
static constexpr u32 DEBUG_FLAG_STOP_VBLANK = 0x00001000; // there is a pending stop on the next VBLANK
|
||||||
static constexpr u32 DEBUG_FLAG_STOP_TIME = 0x00002000; // there is a pending stop at cpu->stoptime
|
static constexpr u32 DEBUG_FLAG_STOP_TIME = 0x00002000; // there is a pending stop at cpu->stoptime
|
||||||
|
static constexpr u32 DEBUG_FLAG_SUSPENDED = 0x00004000; // CPU currently suspended
|
||||||
static constexpr u32 DEBUG_FLAG_LIVE_BP = 0x00010000; // there are live breakpoints for this CPU
|
static constexpr u32 DEBUG_FLAG_LIVE_BP = 0x00010000; // there are live breakpoints for this CPU
|
||||||
|
|
||||||
static constexpr u32 DEBUG_FLAG_STEPPING_ANY = DEBUG_FLAG_STEPPING | DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT;
|
static constexpr u32 DEBUG_FLAG_STEPPING_ANY = DEBUG_FLAG_STEPPING | DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT;
|
||||||
|
@ -142,6 +142,8 @@ static const help_item static_help_list[] =
|
|||||||
" focus <CPU> -- focuses debugger only on <CPU>\n"
|
" focus <CPU> -- focuses debugger only on <CPU>\n"
|
||||||
" ignore [<CPU>[,<CPU>[,...]]] -- stops debugging on <CPU>\n"
|
" ignore [<CPU>[,<CPU>[,...]]] -- stops debugging on <CPU>\n"
|
||||||
" observe [<CPU>[,<CPU>[,...]]] -- resumes debugging on <CPU>\n"
|
" observe [<CPU>[,<CPU>[,...]]] -- resumes debugging on <CPU>\n"
|
||||||
|
" suspend [<CPU>[,<CPU>[,...]]] -- suspends execution on <CPU>\n"
|
||||||
|
" resume [<CPU>[,<CPU>[,...]]] -- resumes execution on <CPU>\n"
|
||||||
" trace {<filename>|OFF}[,<CPU>[,<detectloops>[,<action>]]] -- trace the given CPU to a file (defaults to active CPU)\n"
|
" trace {<filename>|OFF}[,<CPU>[,<detectloops>[,<action>]]] -- trace the given CPU to a file (defaults to active CPU)\n"
|
||||||
" traceover {<filename>|OFF}[,<CPU>[,<detectloops>[,<action>]]] -- trace the given CPU to a file, but skip subroutines (defaults to active CPU)\n"
|
" traceover {<filename>|OFF}[,<CPU>[,<detectloops>[,<action>]]] -- trace the given CPU to a file, but skip subroutines (defaults to active CPU)\n"
|
||||||
" traceflush -- flushes all open trace files\n"
|
" traceflush -- flushes all open trace files\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user