diff --git a/README.md b/README.md index e28f4ed7fffdb08e8546aea7c67994447467316b..dab96a8166084d47a0928fd5017d1f3421fe84de 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,14 @@ ./tdbg ./example -b main ./tdbg ./example -b example.c:54 -b example.c:60 ``` +Example with auto run: + +```sh +./tdbg -run ./example +./tdbg -run ./example arg1 arg2 arg3 +./tdbg -run ./example -e MYENV=qwe -- arg1 arg2 arg3 +``` + ### Interactive Commands | Key | Action | diff --git a/tdbg.cpp b/tdbg.cpp index 08b47f4f6a4eb5edd78a170a9dfc77026037ebdc..3daede15ecfe4d250d47b8387d3c9618afdb60f9 100644 --- a/tdbg.cpp +++ b/tdbg.cpp @@ -665,7 +665,7 @@ draw_box(x, y, w, h, "Help / Keybinds"); int ty = y + 2; int tx = x + 3; - + auto d = [&](const std::string& key, const std::string& desc) { draw_text(tx, ty, TB_YELLOW | TB_BOLD, TB_DEFAULT, key); draw_text(tx + 13, ty, TB_DEFAULT, TB_DEFAULT, desc); @@ -712,11 +712,56 @@ draw_text(1, height - 1, TB_BLACK, TB_WHITE, state_str); } +SBProcess launch_target(SBTarget& target, const std::string& target_path, const std::vector& debuggee_args, const std::vector& target_env, std::vector& log_buffer) { + if (target.GetNumBreakpoints() == 0) { + SBBreakpoint bp = target.BreakpointCreateByName("main"); + if (bp.IsValid() && bp.GetNumLocations() > 0) { + log_msg(log_buffer, "No breakpoints. Added breakpoint at 'main'"); + } else { + log_msg(log_buffer, "No breakpoints. Failed to add breakpoint at 'main'"); + } + } + log_msg(log_buffer, "Launching..."); + + std::vector launch_argv; + launch_argv.push_back(target_path.c_str()); + for (const auto& arg : debuggee_args) { + launch_argv.push_back(arg.c_str()); + } + launch_argv.push_back(nullptr); + + std::vector launch_env; + for (const auto& env : target_env) { + launch_env.push_back(env.c_str()); + } + launch_env.push_back(nullptr); + + SBLaunchInfo launch_info(launch_argv.data()); + launch_info.SetEnvironmentEntries(launch_env.data(), true); + launch_info.SetWorkingDirectory("."); + + SBError error; + SBProcess process = target.Launch(launch_info, error); + + if (!process.IsValid() || error.Fail()) { + std::string err_msg = "Launch failed"; + if (error.GetCString()) { + err_msg += ": "; + err_msg += error.GetCString(); + } + log_msg(log_buffer, err_msg); + } else { + log_msg(log_buffer, "Launched"); + } + return process; +} + int main(int argc, char** argv) { std::vector target_env; std::vector startup_breakpoints; std::vector debuggee_args; std::string target_path; + bool auto_run = false; for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; @@ -724,6 +769,8 @@ if (arg == "-e" && i + 1 < argc) { target_env.push_back(argv[++i]); } else if (arg == "-b" && i + 1 < argc) { startup_breakpoints.push_back(argv[++i]); + } else if (arg == "-run") { + auto_run = true; } else if (arg == "--") { for (int j = i + 1; j < argc; ++j) { debuggee_args.push_back(argv[j]); @@ -737,7 +784,7 @@ } } if (target_path.empty()) { - std::cerr << "Usage: " << argv[0] << " [-e KEY=VALUE] [-b BREAKPOINT] ... [-- arg1 arg2 ...]\n"; + std::cerr << "Usage: " << argv[0] << " [-e KEY=VALUE] [-b BREAKPOINT] [-run] ... [-- arg1 arg2 ...]\n"; return 1; } @@ -767,9 +814,12 @@ log_msg(log_buffer, "Failed to set startup breakpoint: " + bp_spec); } } - SBProcess process; - SBThread thread; + SBProcess process; + if (auto_run) { + process = launch_target(target, target_path, debuggee_args, target_env, log_buffer); + } + SBThread thread; TermboxGuard tb_guard; bool running = true; @@ -848,47 +898,8 @@ if (mode == INPUT_MODE_NORMAL) { if (ev.ch == 'q') { running = false; } else if (ev.ch == 'r') { - if (!process.IsValid()) { - if (target.GetNumBreakpoints() == 0) { - SBBreakpoint bp = target.BreakpointCreateByName("main"); - if (bp.IsValid() && bp.GetNumLocations() > 0) { - log_msg(log_buffer, "No breakpoints. Added breakpoint at 'main'"); - } else { - log_msg(log_buffer, "No breakpoints. Failed to add breakpoint at 'main'"); - } - } - log_msg(log_buffer, "Launching..."); - - std::vector launch_argv; - launch_argv.push_back(target_path.c_str()); - for (const auto& arg : debuggee_args) { - launch_argv.push_back(arg.c_str()); - } - launch_argv.push_back(nullptr); - - std::vector launch_env; - for (const auto& env : target_env) { - launch_env.push_back(env.c_str()); - } - launch_env.push_back(nullptr); - - SBLaunchInfo launch_info(launch_argv.data()); - launch_info.SetEnvironmentEntries(launch_env.data(), true); - launch_info.SetWorkingDirectory("."); - - SBError error; - process = target.Launch(launch_info, error); - - if (!process.IsValid() || error.Fail()) { - std::string err_msg = "Launch failed"; - if (error.GetCString()) { - err_msg += ": "; - err_msg += error.GetCString(); - } - log_msg(log_buffer, err_msg); - } else { - log_msg(log_buffer, "Launched"); - } + if (!process.IsValid() || process.GetState() == eStateExited) { + process = launch_target(target, target_path, debuggee_args, target_env, log_buffer); } else { log_msg(log_buffer, "Already running"); } @@ -916,7 +927,7 @@ case 'o': if (thread.IsValid()) thread.StepOut(); break; case 'c': process.Continue(); break; } } - + if (ev.key == TB_KEY_ARROW_LEFT && (ev.mod & TB_MOD_CTRL)) { layout_config.sidebar_width = std::min(width - 20, layout_config.sidebar_width + 2); } else if (ev.key == TB_KEY_ARROW_RIGHT && (ev.mod & TB_MOD_CTRL)) {