update command line parsing to require --var and support program arguments
This commit is contained in:
parent
6129dee91d
commit
eb88701937
64
src/main.cpp
64
src/main.cpp
@ -7,6 +7,7 @@
|
|||||||
#include <libdwarf.h>
|
#include <libdwarf.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
cxxopts::Options options("gwatch",
|
cxxopts::Options options("gwatch",
|
||||||
@ -16,15 +17,31 @@ int main(int argc, char **argv) {
|
|||||||
"var", "Variable name to watch", cxxopts::value<std::string>())(
|
"var", "Variable name to watch", cxxopts::value<std::string>())(
|
||||||
"h,help", "Print usage");
|
"h,help", "Print usage");
|
||||||
|
|
||||||
|
options.allow_unrecognised_options();
|
||||||
|
|
||||||
auto result = options.parse(argc, argv);
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
if (result.count("help") || argc < 2 || !result.count("exec")) {
|
if (result.count("help")) {
|
||||||
|
std::cout << "Usage: gwatch --var <symbol> --exec <path> [-- arg1 .. argN]" << std::endl;
|
||||||
std::cout << options.help() << std::endl;
|
std::cout << options.help() << std::endl;
|
||||||
return 0;
|
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 <symbol> --exec <path> [-- arg1 .. argN]" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
auto exec_path = result["exec"].as<std::filesystem::path>();
|
auto exec_path = result["exec"].as<std::filesystem::path>();
|
||||||
bool watch_mode = result.count("var");
|
auto var_name = result["var"].as<std::string>();
|
||||||
|
|
||||||
|
// Collect program arguments (after --)
|
||||||
|
std::vector<std::string> prog_args;
|
||||||
|
auto unmatched = result.unmatched();
|
||||||
|
for (const auto& arg : unmatched) {
|
||||||
|
prog_args.push_back(arg);
|
||||||
|
}
|
||||||
|
|
||||||
// Open the binary file
|
// Open the binary file
|
||||||
int fd = open(exec_path.c_str(), O_RDONLY);
|
int fd = open(exec_path.c_str(), O_RDONLY);
|
||||||
@ -47,42 +64,29 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the variable in debug info
|
||||||
Symbol symbol;
|
Symbol symbol;
|
||||||
|
auto var_info = symbol.find_global_var(dbg, var_name);
|
||||||
|
|
||||||
if (watch_mode) {
|
if (!var_info) {
|
||||||
// Watch mode: find the variable and set up ptrace
|
std::cerr << "Error: Variable '" << var_name << "' not found" << std::endl;
|
||||||
auto var_name = result["var"].as<std::string>();
|
|
||||||
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
|
|
||||||
dwarf_finish(dbg);
|
dwarf_finish(dbg);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
return 1;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
dwarf_finish(dbg);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
// Start watching the variable
|
||||||
|
Tracer tracer;
|
||||||
|
tracer.watch_variable(exec_path.string(), var_info->address, var_info->size, prog_args);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user