1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#include "core/application.h"
#include "core/log.h"
#include "debugger/debugger.h"
#include <algorithm>
#include <charconv>
#include <cstdlib>
#include <filesystem>
#include <span>
#include <string_view>
namespace
{
// dev aid: HSDBG_WINDOW=<w>x<h> sizes the window, and HSDBG_BREAK=<file>:<line>
// plants a breakpoint and launches as soon as the target loads, so a capture
// (HSDBG_CAPTURE) lands on a stopped target with every panel populated
auto dev_window_size(Hsdbg::ApplicationSpec& spec) -> void
{
const char* text = std::getenv("HSDBG_WINDOW");
if (text == nullptr)
return;
const std::string_view value(text);
const size_t x = value.find('x');
if (x == std::string_view::npos)
return;
std::from_chars(value.data(), value.data() + x, spec.width);
std::from_chars(value.data() + x + 1, value.data() + value.size(), spec.height);
}
auto dev_break_and_launch(Hsdbg::Debugger& debugger) -> void
{
const char* text = std::getenv("HSDBG_BREAK");
if (text == nullptr || !debugger.has_target())
return;
const std::string_view value(text);
const size_t colon = value.rfind(':');
if (colon == std::string_view::npos)
return;
uint32_t line = 0;
std::from_chars(value.data() + colon + 1, value.data() + value.size(), line);
// pick the target's own path for the file so it matches what lldb reports
const std::string_view name = value.substr(0, colon);
const std::span<const std::filesystem::path> files = debugger.source_files();
const auto known = std::ranges::find_if(files, [&](const std::filesystem::path& candidate)
{
return candidate.filename() == name;
});
debugger.add_breakpoint(known != files.end() ? *known : std::filesystem::path(name), line);
Hsdbg::LaunchSpec launch;
launch.executable = debugger.target_path();
if (const auto result = debugger.launch(launch); !result)
Hsdbg::Log::error("{}", result.error());
}
}
auto main(int argc, char** argv) -> int
{
const std::span arguments(argv, static_cast<size_t>(argc));
Hsdbg::ApplicationSpec spec;
spec.name = "hsdbg";
spec.width = 1600;
spec.height = 900;
dev_window_size(spec);
Hsdbg::Application app(spec);
if (arguments.size() > 1)
{
if (const auto result = app.debugger().load_target(arguments[1]); !result)
Hsdbg::Log::error("{}", result.error());
dev_break_and_launch(app.debugger());
}
app.run();
return 0;
}
|