From eb8870193715f61fbedea4e1ebb010c24147adec Mon Sep 17 00:00:00 2001 From: Gabriel Ionita Date: Sun, 26 Oct 2025 17:15:00 +0100 Subject: [PATCH] update command line parsing to require --var and support program arguments --- src/main.cpp | 64 ++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0ecae8d..2f804aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include int main(int argc, char **argv) { cxxopts::Options options("gwatch", @@ -16,15 +17,31 @@ int main(int argc, char **argv) { "var", "Variable name to watch", cxxopts::value())( "h,help", "Print usage"); + options.allow_unrecognised_options(); + auto result = options.parse(argc, argv); - if (result.count("help") || argc < 2 || !result.count("exec")) { + if (result.count("help")) { + std::cout << "Usage: gwatch --var --exec [-- arg1 .. argN]" << std::endl; std::cout << options.help() << std::endl; return 0; } + if (!result.count("exec") || !result.count("var")) { + std::cerr << "Error: Both --exec and --var are required" << std::endl; + std::cerr << "Usage: gwatch --var --exec [-- arg1 .. argN]" << std::endl; + return 1; + } + auto exec_path = result["exec"].as(); - bool watch_mode = result.count("var"); + auto var_name = result["var"].as(); + + // Collect program arguments (after --) + std::vector prog_args; + auto unmatched = result.unmatched(); + for (const auto& arg : unmatched) { + prog_args.push_back(arg); + } // Open the binary file int fd = open(exec_path.c_str(), O_RDONLY); @@ -47,42 +64,29 @@ int main(int argc, char **argv) { return 1; } + // Find the variable in debug info Symbol symbol; + auto var_info = symbol.find_global_var(dbg, var_name); - if (watch_mode) { - // Watch mode: find the variable and set up ptrace - auto var_name = result["var"].as(); - auto var_info = symbol.find_global_var(dbg, var_name); - - if (!var_info) { - std::cerr << "Error: Variable '" << var_name << "' not found" << std::endl; - dwarf_finish(dbg); - close(fd); - return 1; - } - - std::cout << "Watching variable: " << var_info->name << std::endl; - std::cout << "Address: 0x" << std::hex << var_info->address << std::dec << std::endl; - std::cout << "Size: " << var_info->size << " bytes" << std::endl; - std::cout << std::string(50, '-') << std::endl; - - // Close DWARF resources before forking + if (!var_info) { + std::cerr << "Error: Variable '" << var_name << "' not found" << std::endl; dwarf_finish(dbg); close(fd); - - // Start watching the variable - Tracer tracer; - tracer.watch_variable(exec_path.string(), var_info->address, var_info->size); - - return 0; - } else { - // List mode: show all global integer variables - symbol.list_global_integer_vars(dbg); + return 1; } - // Cleanup + std::cout << "Watching variable: " << var_info->name << std::endl; + std::cout << "Address: 0x" << std::hex << var_info->address << std::dec << std::endl; + std::cout << "Size: " << var_info->size << " bytes" << std::endl; + std::cout << std::string(50, '-') << std::endl; + + // Close DWARF resources before forking dwarf_finish(dbg); close(fd); + // Start watching the variable + Tracer tracer; + tracer.watch_variable(exec_path.string(), var_info->address, var_info->size, prog_args); + return 0; }