From 7bdffa55d6053138142d84dcda0663792d661319 Mon Sep 17 00:00:00 2001 From: Jose Angel Sanchez Velazquez Date: Sun, 29 Mar 2026 22:17:43 +0100 Subject: [PATCH 1/3] Added crash handler and fixed crash-on-connect bugs - Added crashhandler.h: installs SetUnhandledExceptionFilter and std::set_terminate to log exception code/address and write a timestamped minidump on crash - Fixed access violation on device connect: connection listener callbacks were called from the asio IO thread but accessed wxWidgets UI directly; wrapped in CallAfter to marshal onto the main thread - Fixed descriptor buffer overflow: read_some with a 512-byte buffer was truncating descriptors larger than 512 bytes; replaced with chunked reads into a dynamic buffer Co-Authored-By: Claude Sonnet 4.6 --- windows/src/application.cpp | 49 +++++++++++++--------- windows/src/crashhandler.h | 81 +++++++++++++++++++++++++++++++++++++ windows/src/net/server.cpp | 14 +++++-- 3 files changed, 120 insertions(+), 24 deletions(-) create mode 100644 windows/src/crashhandler.h diff --git a/windows/src/application.cpp b/windows/src/application.cpp index 81190a0..0cb0bfa 100644 --- a/windows/src/application.cpp +++ b/windows/src/application.cpp @@ -1,4 +1,5 @@ #include "application.h" +#include "crashhandler.h" #include "gui/imgadjdlg.h" #include "gui/streamconfigdlg.h" @@ -21,6 +22,8 @@ Application::Application() bool Application::OnInit() { + CrashHandler::Install(); + if (!wxApp::OnInit()) return false; @@ -162,36 +165,42 @@ void Application::BindEventListeners() void Application::OnDeviceConnected(DeviceDescriptor& descriptor) const { - mainWindow->GetTaskbarIcon()->ShowBalloon("New stream available", "Streaming device " + descriptor.name() + " available!", 10, wxICON_INFORMATION); - rtspManager->AddDescriptor(descriptor); - UpdateAvailableDevices(); + mainWindow->GetEventHandler()->CallAfter([this, descriptor]() mutable { + mainWindow->GetTaskbarIcon()->ShowBalloon("New stream available", "Streaming device " + descriptor.name() + " available!", 10, wxICON_INFORMATION); + rtspManager->AddDescriptor(descriptor); + UpdateAvailableDevices(); + }); } void Application::OnDeviceDisconnected(DeviceDescriptor& descriptor) const { - mainWindow->GetTaskbarIcon()->ShowBalloon("Stream ended", "Streaming device " + descriptor.name() + " disconnected!", 10, wxICON_INFORMATION); - - // Check if the device that just disconnected was the active streaming device - // If it was reset the canvas to blank - int streamingDeviceId = rtspManager->GetStreamingDevice(); - if (streamingDeviceId >= 0) - { - const auto& streamingDescriptor = rtspManager->GetDescriptors()[streamingDeviceId]; - if (streamingDescriptor == descriptor) - mainWindow->GetCanvas()->Clear(); - } + mainWindow->GetEventHandler()->CallAfter([this, descriptor]() mutable { + mainWindow->GetTaskbarIcon()->ShowBalloon("Stream ended", "Streaming device " + descriptor.name() + " disconnected!", 10, wxICON_INFORMATION); - // Remove from manager - rtspManager->RemoveDescriptor(descriptor); + // Check if the device that just disconnected was the active streaming device + // If it was reset the canvas to blank + int streamingDeviceId = rtspManager->GetStreamingDevice(); + if (streamingDeviceId >= 0) + { + const auto& streamingDescriptor = rtspManager->GetDescriptors()[streamingDeviceId]; + if (streamingDescriptor == descriptor) + mainWindow->GetCanvas()->Clear(); + } + + // Remove from manager + rtspManager->RemoveDescriptor(descriptor); - // Update UI list - UpdateAvailableDevices(); + // Update UI list + UpdateAvailableDevices(); + }); } void Application::OnDeviceErrorReported(DeviceDescriptor& descriptor, const Connection::ErrorReport& error) const { - auto icon = error.severity == Connection::ErrorReport::SEVERITY_WARNING ? wxICON_WARNING : wxICON_ERROR; - mainWindow->GetTaskbarIcon()->ShowBalloon(descriptor.name() + " " + error.error, error.description, 1000, icon); + mainWindow->GetEventHandler()->CallAfter([this, descriptor, error]() { + auto icon = error.severity == Connection::ErrorReport::SEVERITY_WARNING ? wxICON_WARNING : wxICON_ERROR; + mainWindow->GetTaskbarIcon()->ShowBalloon(descriptor.name() + " " + error.error, error.description, 1000, icon); + }); } void Application::UpdateAvailableDevices() const diff --git a/windows/src/crashhandler.h b/windows/src/crashhandler.h new file mode 100644 index 0000000..e84a516 --- /dev/null +++ b/windows/src/crashhandler.h @@ -0,0 +1,81 @@ +#pragma once + +#include +#include +#include +#include +#include + +#pragma comment(lib, "dbghelp.lib") + +#include "logger.h" + +extern Logger logger; + +namespace CrashHandler +{ + static std::string TimestampedDumpPath() + { + time_t now = time(nullptr); + char buf[64]; + struct tm tm_info; + localtime_s(&tm_info, &now); + strftime(buf, sizeof(buf), "vcamdroid_crash_%Y%m%d_%H%M%S.dmp", &tm_info); + return buf; + } + + static void WriteDump(EXCEPTION_POINTERS* exceptionInfo = nullptr) + { + std::string path = TimestampedDumpPath(); + + HANDLE hFile = CreateFileA(path.c_str(), GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + + if (hFile == INVALID_HANDLE_VALUE) + { + logger << "[CRASH] Failed to create dump file: " << path << "\n"; + return; + } + + MINIDUMP_EXCEPTION_INFORMATION info{}; + MINIDUMP_EXCEPTION_INFORMATION* pInfo = nullptr; + if (exceptionInfo) + { + info.ThreadId = GetCurrentThreadId(); + info.ExceptionPointers = exceptionInfo; + info.ClientPointers = TRUE; + pInfo = &info; + } + + MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, + MiniDumpWithThreadInfo, pInfo, nullptr, nullptr); + CloseHandle(hFile); + + logger << "[CRASH] Minidump written: " << path << "\n"; + } + + static LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) + { + DWORD code = exceptionInfo->ExceptionRecord->ExceptionCode; + auto addr = reinterpret_cast(exceptionInfo->ExceptionRecord->ExceptionAddress); + + logger << "[CRASH] Unhandled exception - code: 0x" << std::hex << code + << " address: 0x" << addr << std::dec << "\n"; + + WriteDump(exceptionInfo); + + return EXCEPTION_EXECUTE_HANDLER; + } + + static void TerminateHandler() + { + logger << "[CRASH] std::terminate() called - unhandled C++ exception\n"; + WriteDump(); + } + + static void Install() + { + SetUnhandledExceptionFilter(ExceptionFilter); + std::set_terminate(TerminateHandler); + } +} diff --git a/windows/src/net/server.cpp b/windows/src/net/server.cpp index fda4011..72652a9 100644 --- a/windows/src/net/server.cpp +++ b/windows/src/net/server.cpp @@ -134,11 +134,17 @@ void Server::TCPDoAccept() // We need to read this here because the connection listener // needs all the data sent by the client (trough GetConnectedDevicesInfo) // otherwise the connection would need to be passed to the connection - std::array buffer; - size_t size = socket.read_some(asio::buffer(buffer, 512)); - + std::vector buffer; + std::array chunk; + asio::error_code readEc; + size_t n; + do { + n = socket.read_some(asio::buffer(chunk), readEc); + if (n > 0) buffer.insert(buffer.end(), chunk.begin(), chunk.begin() + n); + } while (n == chunk.size() && !readEc); + // auto ipaddress = socket.remote_endpoint().address().to_string(); - auto descriptor = Serializer::DeserializeDeviceDescriptor((const uint8_t*)buffer.data(), size); + auto descriptor = Serializer::DeserializeDeviceDescriptor(buffer.data(), buffer.size()); auto conn = std::make_shared( std::move(socket), From 6c8f81812e8d0a37052539fa613affe0e89a7c9b Mon Sep 17 00:00:00 2001 From: Jose Angel Sanchez Velazquez Date: Wed, 1 Apr 2026 11:55:43 +0100 Subject: [PATCH 2/3] exclue log files from tracking --- .gitignore | 4 +++- windows/app.log | 8 -------- 2 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 windows/app.log diff --git a/.gitignore b/.gitignore index 7b264fb..67cc75a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ dist -VCamdroid \ No newline at end of file +VCamdroid +*.log +*.dmp \ No newline at end of file diff --git a/windows/app.log b/windows/app.log deleted file mode 100644 index 72cf671..0000000 --- a/windows/app.log +++ /dev/null @@ -1,8 +0,0 @@ -[SERVER] Started -[ADB:6969] Started -[SERVER] Device connected.127.0.0.1:51306 -[SERVER] Set UDP stream device: 127.0.0.1:51306 -[CONNECTION@127.0.0.1:51306] Closed with error code: asio.misc:2 -[SERVER] Closing... -[SERVER] Closed. -[ADB:6969] Failed to stop From 127b2e38547faa953da04c688fc94ff49459e4da Mon Sep 17 00:00:00 2001 From: Jose Angel Sanchez Velazquez Date: Thu, 2 Apr 2026 01:10:41 +0100 Subject: [PATCH 3/3] update softcam git subproject --- windows/3rdparty/softcam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/3rdparty/softcam b/windows/3rdparty/softcam index afb424c..66fcac8 160000 --- a/windows/3rdparty/softcam +++ b/windows/3rdparty/softcam @@ -1 +1 @@ -Subproject commit afb424c2415b04da627fa1a7b4706575c2ba3010 +Subproject commit 66fcac8726c26265fdf5da2f1ebc0b01559727c5