Skip to content

Commit 52b64c6

Browse files
committed
Add fine-grained Win startup constructor tracing
1 parent b4e4de7 commit 52b64c6

17 files changed

+137
-3
lines changed

src/gui/audio_engine.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
#define _USE_MATH_DEFINES // For M_PI on MSVC
22
#include <cmath>
33
#include "audio_engine.hpp"
4+
#include "gui/startup_trace.hpp"
45
#include "ultra/logging.hpp"
56
#include <cstring>
67
#include <algorithm>
78

89
namespace ultra {
910
namespace gui {
1011

11-
AudioEngine::AudioEngine() = default;
12+
AudioEngine::AudioEngine() {
13+
startupTrace("AudioEngine", "ctor");
14+
}
1215

1316
AudioEngine::~AudioEngine() {
1417
shutdown();

src/gui/main_gui.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Uses Dear ImGui with SDL2 + OpenGL 2.1 for maximum compatibility
33

44
#include "app.hpp"
5+
#include "startup_trace.hpp"
56

67
#include "imgui.h"
78
#include "imgui_impl_sdl2.h"
@@ -150,6 +151,9 @@ LONG WINAPI startupUnhandledExceptionFilter(EXCEPTION_POINTERS* ex) {
150151
int main(int argc, char* argv[]) {
151152
initStartupLog();
152153
#ifdef _WIN32
154+
if (!g_startup_log_path.empty()) {
155+
_putenv_s("ULTRA_STARTUP_LOG", g_startup_log_path.c_str());
156+
}
153157
SetUnhandledExceptionFilter(startupUnhandledExceptionFilter);
154158
#endif
155159
std::set_terminate([]() {

src/gui/modem/modem_engine.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Constructor, destructor, configuration, and TX functions
33

44
#include "modem_engine.hpp"
5+
#include "gui/startup_trace.hpp"
56
#include "ultra/logging.hpp"
67
#include <cstring>
78
#include <algorithm>
@@ -12,7 +13,9 @@ namespace ultra {
1213
namespace gui {
1314

1415
ModemEngine::ModemEngine() {
16+
startupTrace("ModemEngine", "ctor-enter");
1517
config_ = presets::balanced();
18+
startupTrace("ModemEngine", "presets-balanced");
1619

1720
// CRITICAL: Disable pilots for DQPSK mode - uses all 30 carriers for data
1821
// This doubles throughput (30 data carriers vs 15 with pilots)
@@ -36,6 +39,7 @@ ModemEngine::ModemEngine() {
3639
chirp_cfg.use_dual_chirp = true; // Enable dual chirp for CFO estimation
3740
chirp_cfg.tx_cfo_hz = config_.tx_cfo_hz; // Pass TX CFO for simulation
3841
chirp_sync_ = std::make_unique<sync::ChirpSync>(chirp_cfg);
42+
startupTrace("ModemEngine", "chirp-sync-created");
3943

4044
// Multi-Carrier DPSK (for fading channels - frequency diversity)
4145
// Using level8: 8 carriers, 93.75 baud, DQPSK (~735 bps)
@@ -50,16 +54,20 @@ ModemEngine::ModemEngine() {
5054

5155
// Initialize StreamingEncoder (unified TX path)
5256
streaming_encoder_ = std::make_unique<StreamingEncoder>();
57+
startupTrace("ModemEngine", "streaming-encoder-created");
5358
streaming_encoder_->setOFDMConfig(config_);
5459
streaming_encoder_->setMCDPSKCarriers(mc_dpsk_config_.num_carriers);
60+
startupTrace("ModemEngine", "streaming-encoder-configured");
5561

5662
// Initialize audio filters
5763
rebuildFilters();
64+
startupTrace("ModemEngine", "filters-built");
5865

5966
// ========================================================================
6067
// Initialize StreamingDecoder (primary RX path)
6168
// ========================================================================
6269
streaming_decoder_ = std::make_unique<StreamingDecoder>();
70+
startupTrace("ModemEngine", "streaming-decoder-created");
6371
streaming_decoder_->setLogPrefix(log_prefix_);
6472

6573
// Set callbacks to wire into existing ModemEngine callbacks
@@ -99,15 +107,18 @@ ModemEngine::ModemEngine() {
99107
// When connected, use the negotiated waveform
100108
protocol::WaveformMode decoder_mode = connected_ ? waveform_mode_ : protocol::WaveformMode::MC_DPSK;
101109
streaming_decoder_->setMode(decoder_mode, connected_);
110+
startupTrace("ModemEngine", "decoder-mode-set");
102111

103112
// Sync MC-DPSK carrier count with ModemEngine's config
104113
streaming_decoder_->setMCDPSKCarriers(mc_dpsk_config_.num_carriers);
114+
startupTrace("ModemEngine", "decoder-carriers-set");
105115

106116
LOG_MODEM(INFO, "[%s] StreamingDecoder initialized (MC-DPSK: %d carriers)",
107117
log_prefix_.c_str(), mc_dpsk_config_.num_carriers);
108118

109119
// Defer RX decode thread startup until audio is actually fed.
110120
// This reduces startup-time failure surface on low-end systems.
121+
startupTrace("ModemEngine", "ctor-exit");
111122
}
112123

113124
ModemEngine::~ModemEngine() {

src/gui/modem/streaming_decoder.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// - FFT-based correlation for speed when signal present
1414

1515
#include "streaming_decoder.hpp"
16+
#include "gui/startup_trace.hpp"
1617
#include "waveform/ofdm_cox_waveform.hpp"
1718
#include "waveform/ofdm_chirp_waveform.hpp"
1819
#include "fec/frame_interleaver.hpp" // Frame-level interleaving for 4-CW frames
@@ -126,12 +127,18 @@ static void dumpBufferSnapshot(const std::vector<float>& buffer, size_t write_po
126127
}
127128

128129
StreamingDecoder::StreamingDecoder() {
130+
startupTrace("StreamingDecoder", "ctor-enter");
129131
buffer_.resize(MAX_BUFFER_SAMPLES, 0.0f);
132+
startupTrace("StreamingDecoder", "buffer-resized");
130133
waveform_ = WaveformFactory::create(protocol::WaveformMode::MC_DPSK);
134+
startupTrace("StreamingDecoder", "waveform-created");
131135
interleaver_ = std::make_unique<ChannelInterleaver>(16, v2::LDPC_CODEWORD_BITS);
136+
startupTrace("StreamingDecoder", "interleaver-created");
132137
codec_ = fec::CodecFactory::create(fec::CodecType::LDPC, CodeRate::R1_4);
138+
startupTrace("StreamingDecoder", "codec-created");
133139

134140
LOG_MODEM(INFO, "StreamingDecoder: Initialized (buffer=%zu samples)", MAX_BUFFER_SAMPLES);
141+
startupTrace("StreamingDecoder", "ctor-exit");
135142
}
136143

137144
StreamingDecoder::~StreamingDecoder() {

src/gui/startup_trace.hpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#pragma once
2+
3+
#include <chrono>
4+
#include <cstdio>
5+
#include <cstdlib>
6+
#include <cstring>
7+
#include <filesystem>
8+
#include <mutex>
9+
#include <string>
10+
11+
namespace ultra {
12+
namespace gui {
13+
14+
inline void startupTrace(const char* component, const char* phase) {
15+
#ifdef _WIN32
16+
static std::mutex trace_mutex;
17+
std::lock_guard<std::mutex> lock(trace_mutex);
18+
19+
namespace fs = std::filesystem;
20+
21+
std::string line;
22+
{
23+
using namespace std::chrono;
24+
auto now = system_clock::now();
25+
auto ms = duration_cast<milliseconds>(now.time_since_epoch()).count();
26+
char buf[512];
27+
std::snprintf(
28+
buf, sizeof(buf), "[%lld][STARTUP][%s] %s\n",
29+
static_cast<long long>(ms),
30+
component ? component : "<unknown>",
31+
phase ? phase : "<unknown>"
32+
);
33+
line = buf;
34+
}
35+
36+
std::string env_log;
37+
if (const char* p = std::getenv("ULTRA_STARTUP_LOG")) {
38+
env_log = p;
39+
}
40+
41+
fs::path log_path;
42+
if (!env_log.empty()) {
43+
log_path = fs::path(env_log);
44+
} else if (const char* temp = std::getenv("TEMP")) {
45+
log_path = fs::path(temp) / "ProjectUltra" / "startup.log";
46+
} else {
47+
log_path = fs::path("startup.log");
48+
}
49+
50+
std::error_code ec;
51+
if (!log_path.parent_path().empty()) {
52+
fs::create_directories(log_path.parent_path(), ec);
53+
}
54+
55+
if (FILE* f = std::fopen(log_path.string().c_str(), "a")) {
56+
std::fwrite(line.data(), 1, line.size(), f);
57+
std::fflush(f);
58+
std::fclose(f);
59+
}
60+
#else
61+
(void)component;
62+
(void)phase;
63+
#endif
64+
}
65+
66+
} // namespace gui
67+
} // namespace ultra
68+

src/gui/widgets/constellation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
#include "constellation.hpp"
22
#include "imgui.h"
3+
#include "gui/startup_trace.hpp"
34
#include <cmath>
45

56
namespace ultra {
67
namespace gui {
78

9+
ConstellationWidget::ConstellationWidget() {
10+
startupTrace("ConstellationWidget", "ctor");
11+
}
12+
813
void ConstellationWidget::render(const std::vector<std::complex<float>>& symbols,
914
Modulation mod) {
1015
// Show symbol count for debugging

src/gui/widgets/constellation.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace gui {
1010

1111
class ConstellationWidget {
1212
public:
13+
ConstellationWidget();
1314
void render(const std::vector<std::complex<float>>& symbols, Modulation mod);
1415

1516
private:

src/gui/widgets/controls.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
#include "controls.hpp"
22
#include "imgui.h"
3+
#include "gui/startup_trace.hpp"
34
#include <cstdio>
45

56
namespace ultra {
67
namespace gui {
78

9+
ControlsWidget::ControlsWidget() {
10+
startupTrace("ControlsWidget", "ctor");
11+
}
12+
813
// Helper to get modulation name
914
static const char* getModulationName(Modulation mod) {
1015
switch (mod) {

src/gui/widgets/controls.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ControlsWidget {
1313
None
1414
};
1515

16-
ControlsWidget() = default;
16+
ControlsWidget();
1717

1818
// Render channel status panel
1919
// data_mod/data_rate are the protocol's negotiated mode (displayed as current mode)

src/gui/widgets/file_browser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
#include <algorithm>
44
#include <cstdlib>
55
#include <filesystem>
6+
#include "gui/startup_trace.hpp"
67

78
namespace fs = std::filesystem;
89

910
namespace ultra {
1011
namespace gui {
1112

1213
FileBrowser::FileBrowser() {
14+
startupTrace("FileBrowser", "ctor-enter");
1315
current_path_ = getHomeDirectory();
16+
startupTrace("FileBrowser", "ctor-exit");
1417
}
1518

1619
std::string FileBrowser::getHomeDirectory() {

0 commit comments

Comments
 (0)