--- nono/debugger/debugger.cpp 2026/04/29 17:05:09 1.1.1.11 +++ nono/debugger/debugger.cpp 2026/04/29 17:05:13 1.1.1.12 @@ -45,6 +45,7 @@ #include "uimessage.h" #include "vectortable.h" #include +#include #if defined(HAVE_BSD_STDIO_H) #include #endif @@ -399,15 +400,15 @@ Debugger::Input(int c) md->BackupRegs(); switch (act) { - case CommandAction::Stay: + case CmdAct::Stay: // プロンプトに留まるならここで、次行のプロンプト? PrintPrompt(); break; - case CommandAction::Leave: + case CmdAct::Leave: // プロンプトを抜ける LeavePrompt(); break; - case CommandAction::Quit: + case CmdAct::Quit: // アプリケーション自体を終了 LeavePrompt(); UIMessage::Post(UIMessage::APPEXIT); @@ -465,7 +466,7 @@ Debugger::PrintPrompt() } // コマンド実行 -Debugger::CommandAction +Debugger::CmdAct Debugger::Command() { string_rtrim(cmdbuf); @@ -474,7 +475,7 @@ Debugger::Command() // 空行なら、直前のコマンドをもう一度。 // 前行がなければ何もせずもう一度プロンプトを表示するかね。 if (last_cmdbuf.empty()) { - return CommandAction::Stay; + return CmdAct::Stay; } cmdbuf = last_cmdbuf; } else { @@ -495,9 +496,7 @@ Debugger::Command() auto cmd = *it; // 見付かれば実行 - (this->*(cmd.func))(); - - return cmd.action; + return (this->*(cmd.func))(); } // (コマンドテーブルになくて) "r" から始まっていればレジスタ表示系 @@ -505,7 +504,7 @@ Debugger::Command() // ShowRegister() は処理したら true を返す。 // "r" 系コマンドはすべて Stay。 if (md->ShowRegister(cons, args)) { - return CommandAction::Stay; + return CmdAct::Stay; } } @@ -513,7 +512,7 @@ Debugger::Command() fprintf(cons, "%s: unknown command\n", args[0].c_str()); // この行は次回空エンターで再発行しないでいい。 last_cmdbuf.clear(); - return CommandAction::Stay; + return CmdAct::Stay; } // ブレークポイントとかを調べる。1命令ごとに呼び出される。 @@ -566,7 +565,8 @@ Debugger::IsTrace() const } // この辺のどれかがあれば MPU をトレースにする - return bc_enable || s_enable || so_enable || n_enable || is_pause; + return bc_enable || ct_enable || s_enable || so_enable || n_enable || + is_pause; } // デバッガ実行中なら命令開始前に VM スレッドから呼ばれる。 @@ -588,6 +588,16 @@ Debugger::Check() is_break = true; } } + if (ct_enable) { + if (gScheduler->GetVirtTime() >= ct_end_time) { + ct_enable = false; + is_break = true; + + // ブレークポイントメッセージに便乗して表示。 + bpointmsg += string_format("%s has passed.\n", + TimeToStr(ct_timespan).c_str()); + } + } // XXX 残りは排他動作のはず @@ -807,50 +817,51 @@ Debugger::NotifyException(int vector) // コマンド一覧。 // "r" から始まるレジスタ表示系コマンドはコード中で別処理してある。 /*static*/ std::vector Debugger::cmdtable = { - { "bi", &Debugger::cmd_bi, Debugger::CommandAction::Stay }, - { "bm", &Debugger::cmd_bm, Debugger::CommandAction::Stay }, - { "bv", &Debugger::cmd_bv, Debugger::CommandAction::Stay }, - { "bx", &Debugger::cmd_bx, Debugger::CommandAction::Stay }, - { "b", &Debugger::cmd_b, Debugger::CommandAction::Stay }, - { "brhist", &Debugger::cmd_brhist, Debugger::CommandAction::Stay }, - { "c", &Debugger::cmd_c, Debugger::CommandAction::Leave }, - { "d", &Debugger::cmd_d, Debugger::CommandAction::Stay }, - { "dt", &Debugger::cmd_dt, Debugger::CommandAction::Stay }, - { "D", &Debugger::cmd_D, Debugger::CommandAction::Stay }, - { "disp", &Debugger::cmd_disp, Debugger::CommandAction::Stay }, - { "exhist", &Debugger::cmd_exhist, Debugger::CommandAction::Stay }, - { "hb", &Debugger::cmd_hb, Debugger::CommandAction::Stay }, - { "hr", &Debugger::cmd_hr, Debugger::CommandAction::Stay }, - { "h", &Debugger::cmd_h, Debugger::CommandAction::Stay }, - { "help", &Debugger::cmd_h, Debugger::CommandAction::Stay }, - { "L", &Debugger::cmd_L, Debugger::CommandAction::Stay }, - { "m", &Debugger::cmd_m, Debugger::CommandAction::Stay }, - { "mt", &Debugger::cmd_mt, Debugger::CommandAction::Stay }, - { "M", &Debugger::cmd_M, Debugger::CommandAction::Stay }, - { "n", &Debugger::cmd_n, Debugger::CommandAction::Leave }, - { "nt", &Debugger::cmd_nt, Debugger::CommandAction::Leave }, - { "q", &Debugger::cmd_q, Debugger::CommandAction::Quit }, - { "quit", &Debugger::cmd_q, Debugger::CommandAction::Quit }, - { "reset", &Debugger::cmd_reset, Debugger::CommandAction::Leave }, - { "s", &Debugger::cmd_s, Debugger::CommandAction::Leave }, - { "st", &Debugger::cmd_st, Debugger::CommandAction::Leave }, - { "so", &Debugger::cmd_so, Debugger::CommandAction::Leave }, - { "sot", &Debugger::cmd_sot, Debugger::CommandAction::Leave }, - { "show", &Debugger::cmd_show, Debugger::CommandAction::Stay }, - { "t", &Debugger::cmd_t, Debugger::CommandAction::Leave }, - { "-", &Debugger::cmd_minus, Debugger::CommandAction::Stay }, + { "bi", &Debugger::cmd_bi, }, + { "bm", &Debugger::cmd_bm, }, + { "bv", &Debugger::cmd_bv, }, + { "bx", &Debugger::cmd_bx, }, + { "b", &Debugger::cmd_b, }, + { "brhist", &Debugger::cmd_brhist, }, + { "c", &Debugger::cmd_c, }, + { "ct", &Debugger::cmd_ct, }, + { "d", &Debugger::cmd_d, }, + { "dt", &Debugger::cmd_dt, }, + { "D", &Debugger::cmd_D, }, + { "disp", &Debugger::cmd_disp, }, + { "exhist", &Debugger::cmd_exhist, }, + { "hb", &Debugger::cmd_hb, }, + { "hr", &Debugger::cmd_hr, }, + { "h", &Debugger::cmd_h, }, + { "help", &Debugger::cmd_h, }, + { "L", &Debugger::cmd_L, }, + { "m", &Debugger::cmd_m, }, + { "mt", &Debugger::cmd_mt, }, + { "M", &Debugger::cmd_M, }, + { "n", &Debugger::cmd_n, }, + { "nt", &Debugger::cmd_nt, }, + { "q", &Debugger::cmd_q, }, + { "quit", &Debugger::cmd_q, }, + { "reset", &Debugger::cmd_reset, }, + { "s", &Debugger::cmd_s, }, + { "st", &Debugger::cmd_st, }, + { "so", &Debugger::cmd_so, }, + { "sot", &Debugger::cmd_sot, }, + { "show", &Debugger::cmd_show, }, + { "t", &Debugger::cmd_t, }, + { "-", &Debugger::cmd_minus, }, }; // ヘルプ // h : 一覧を表示 // h : 単独コマンドの詳細を表示 -void +Debugger::CmdAct Debugger::cmd_h() { if (args.size() < 2) { // 引数なしなら一覧表示。 ShowHelpList(HelpListMain); - return; + return CmdAct::Stay; } // 引数があれば個別の詳細 @@ -877,37 +888,39 @@ Debugger::cmd_h() // そうでなければこれを表示して終了 std::string disp = HelpConvert(dict.second); fprintf(cons, "%s", disp.c_str()); - return; + return CmdAct::Stay; } } } while (try_again); fprintf(cons, "invalid command name: %s\n", args[1].c_str()); + return CmdAct::Stay; } // hb : ブレークポイント系コマンドの一覧を表示 // こいつだけ結構占めるので別階層。 -void +Debugger::CmdAct Debugger::cmd_hb() { - ShowHelpList(HelpListBreakpoints); + return ShowHelpList(HelpListBreakpoints); } // hr : レジスタ表示系コマンドの一覧を表示 // CPU ごとに違うので。 -void +Debugger::CmdAct Debugger::cmd_hr() { - ShowHelpList(md->GetHelpListReg()); + return ShowHelpList(md->GetHelpListReg()); } // ヘルプ一覧を表示。 -void +Debugger::CmdAct Debugger::ShowHelpList(const HelpMessages& msgs) { fprintf(cons, "Type \"help \" for indivisual details.\n"); for (const auto& pair : msgs) { fprintf(cons, " %-16s %s\n", pair.first.c_str(), pair.second.c_str()); } + return CmdAct::Stay; } // 個別ヘルプメッセージを出力用に置換。 @@ -948,7 +961,7 @@ Debugger::HelpConvert(const std::string& Debugger::HelpListMain = { { "b*", "Set/show Breakpoints (Type \"hb\" for details)" }, { "brhist", "Show branch history" }, - { "c", "Continue" }, + { "c/ct", "Continue" }, { "d/dt/D", "Disassemble" }, { "disp", "Set register group to show" }, { "exhist", "Show exception history" }, @@ -1071,6 +1084,15 @@ Debugger::HelpDetails = { )**" }, //----- + { "ct", R"**( + Command: ct [] + + Continue until specified has elapsed. If the is + ommited, the last value is used again. The unit of is + seconds in default. You can use "msec", "usec", or "nsec" suffix. + )**" }, + + //----- { "d", R"**( Command: D
] [] Command: d [[:]
] [] @@ -1271,7 +1293,7 @@ Debugger::ParseCmdbuf() // b ... 一覧表示 // b #n ... #n を削除 // b [] ... 設定 -void +Debugger::CmdAct Debugger::cmd_b() { // 引数なしなら一覧表示 @@ -1283,7 +1305,7 @@ Debugger::cmd_b() if (args[1][0] == '#') { // # 形式なら、指定番号のブレークポイントを削除 cmd_b_delete(); - return; + return CmdAct::Stay; } return cmd_b_set(BreakpointType::Address); @@ -1291,31 +1313,31 @@ Debugger::cmd_b() // メモリブレークポイントの設定 // bm [] -void +Debugger::CmdAct Debugger::cmd_bm() { // XXX m68k では未サポート if (md->arch == DebuggerMD::Arch::M680x0) { fprintf(cons, "bm not supported yet on m68k\n"); - return; + return CmdAct::Stay; } - cmd_b_set(BreakpointType::Memory); + return cmd_b_set(BreakpointType::Memory); } // type が違うだけの各種ブレークポイント設定の共通部分。 -void +Debugger::CmdAct Debugger::cmd_b_set(BreakpointType type) { breakpoint_t bp; if (args.size() < 2) { fprintf(cons, "usage: %s []\n", args[0].c_str()); - return; + return CmdAct::Stay; } // アドレス if (!ParseAddr(args[1].c_str(), &bp.addr)) { - return; + return CmdAct::Stay; } // あればスキップカウント if (args.size() > 2) { @@ -1331,35 +1353,37 @@ Debugger::cmd_b_set(BreakpointType type) } else { fprintf(cons, "breakpoint #%d added\n", bi); } + return CmdAct::Stay; } // ブレークポイント個別削除 // (引数の先頭が '#' なことを判定したところで呼ばれる) // b # -void +Debugger::CmdAct Debugger::cmd_b_delete() { int n = atoi(&args[1][1]); if (n < 0 || n >= bpoint.size()) { fprintf(cons, "invalid breakpoint number: #%d\n", n); - return; + return CmdAct::Stay; } auto& bp = bpoint[n]; if (bp.type == BreakpointType::Unused) { fprintf(cons, "invalid breakpoint number: #%d\n", n); - return; + return CmdAct::Stay; } fprintf(cons, "breakpoint #%d removed\n", n); bp.type = BreakpointType::Unused; // 今登録されている命令ブレークの必要命令長を再計算 RecalcInstMask(); + return CmdAct::Stay; } // 命令ブレークポイントの設定 // bi [:] [] -void +Debugger::CmdAct Debugger::cmd_bi() { breakpoint_t bp; @@ -1370,7 +1394,7 @@ Debugger::cmd_bi() if (args.size() < 2) { fprintf(cons, "usage: bi [:] []\n"); - return; + return CmdAct::Stay; } // 引数をまず分離 @@ -1391,11 +1415,11 @@ Debugger::cmd_bi() // 命令部チェック if (ParseVerbHex(inststr.c_str(), &bp.inst) == false) { fprintf(cons, "%s: invalid instruction value\n", args[1].c_str()); - return; + return CmdAct::Stay; } if (instlen % (md->inst_bytes * 2) != 0) { fprintf(cons, "%s: invalid instruction length\n", args[1].c_str()); - return; + return CmdAct::Stay; } // マスク部チェック @@ -1403,12 +1427,12 @@ Debugger::cmd_bi() if (masklen != -1) { if (ParseVerbHex(maskstr.c_str(), &bp.mask) == false) { fprintf(cons, "%s: invalid mask value\n", args[1].c_str()); - return; + return CmdAct::Stay; } if (masklen != instlen) { fprintf(cons, "%s: inst:mask must be the same length\n", args[1].c_str()); - return; + return CmdAct::Stay; } } // 8バイト未満なら左詰め。 @@ -1434,18 +1458,19 @@ Debugger::cmd_bi() // 今登録されている命令ブレークの必要命令長を再計算 RecalcInstMask(); + return CmdAct::Stay; } // 例外ブレークポイントの設定 // bv [-] [] -void +Debugger::CmdAct Debugger::cmd_bv() { breakpoint_t bp; if (args.size() < 2) { fprintf(cons, "usage: be [-] []\n"); - return; + return CmdAct::Stay; } auto pos = args[1].find('-'); @@ -1453,7 +1478,7 @@ Debugger::cmd_bv() // ベクタ番号が1つなら vec1, vec2 を同値にしておく。 if (ParseVerbHex(args[1].c_str(), (uint32 *)&bp.vec1) == false) { fprintf(cons, "%s: invalid vector number\n", args[1].c_str()); - return; + return CmdAct::Stay; } bp.vec2 = bp.vec1; } else { @@ -1463,22 +1488,22 @@ Debugger::cmd_bv() if (ParseVerbHex(str1.c_str(), (uint32 *)&bp.vec1) == false) { fprintf(cons, "%s: invalid first vector number\n", args[1].c_str()); - return; + return CmdAct::Stay; } if (ParseVerbHex(str2.c_str(), (uint32 *)&bp.vec2) == false) { fprintf(cons, "%s: invalid last vector number\n", args[1].c_str()); - return; + return CmdAct::Stay; } } // 範囲チェック if (bp.vec1 < 0 || bp.vec1 >= gVectorTable->Size()) { fprintf(cons, "$%x: invalid vector number\n", bp.vec1); - return; + return CmdAct::Stay; } if (bp.vec2 < 0 || bp.vec2 >= gVectorTable->Size()) { fprintf(cons, "$%x: invalid last vector number\n", bp.vec2); - return; + return CmdAct::Stay; } // 大小が逆なら入れ替える? @@ -1516,13 +1541,16 @@ Debugger::cmd_bv() // 設定したのだから、それ以前の事象には反応すべきでない、という意味では // ここでもいいか? bv_vector = -1; + + return CmdAct::Stay; } // ブレークポイント一覧表示 -void +Debugger::CmdAct Debugger::cmd_b_list() { ShowMonitor(bpoint_monitor); + return CmdAct::Stay; } // ブレークポイント一覧 (モニタ) @@ -1606,7 +1634,7 @@ Debugger::MonitorUpdateBpoint(Monitor *, } // ブレークポイント全削除 -void +Debugger::CmdAct Debugger::cmd_bx() { for (auto& bp : bpoint) { @@ -1616,6 +1644,8 @@ Debugger::cmd_bx() // 今登録されている命令ブレークの必要命令長を再計算 RecalcInstMask(); + + return CmdAct::Stay; } // ブレークポイントを設定。 @@ -1682,19 +1712,19 @@ Debugger::RecalcInstMask() // コンソールではデフォルトで下を新しいの順とする。 を負数にすると // (行数は絶対値して) 並び順を逆にしてモニタウィンドウと同じ上を新しいの順に // する。 -void +Debugger::CmdAct Debugger::cmd_brhist() { - cmd_hist_common(md->GetBrHist()); + return cmd_hist_common(md->GetBrHist()); } -void +Debugger::CmdAct Debugger::cmd_exhist() { - cmd_hist_common(md->GetExHist()); + return cmd_hist_common(md->GetExHist()); } // ブランチ履歴、例外履歴表示の共通部分。 -void +Debugger::CmdAct Debugger::cmd_hist_common(BranchHistory& hist) { // 表示最大行数(と向き) @@ -1735,23 +1765,47 @@ Debugger::cmd_hist_common(BranchHistory& // 表示 MONITOR_UPDATE(histmon, screen); ShowTextScreen(screen); + + return CmdAct::Stay; } // 実行再開(continue): c [] // 指定があれば まで実行。 -void +Debugger::CmdAct Debugger::cmd_c() { if (args.size() > 1) { // 引数があれば if (!ParseAddr(args[1].c_str(), &bc_addr)) { - return; + return CmdAct::Stay; } // 偶数番地に丸める bc_addr &= 0xfffffffe; bc_enable = true; } + return CmdAct::Leave; +} + +// 指定仮想時間実行: ct [