From 60f5cb62b1bc14a4bd3f0833c79c986a6ecc590a Mon Sep 17 00:00:00 2001 From: taynpg Date: Wed, 25 Jun 2025 10:54:04 +0800 Subject: [PATCH] xp-sp3: change grammer to support Qt5.6.3 for xp with sp3 system. --- .vscode/settings.json | 7 +- CMakeLists.txt | 20 +-- ClientCore/ClientCore.cpp | 10 +- ClientCore/ClientCore.h | 39 ++---- ClientCore/FileTrans.cpp | 31 ++--- ClientCore/FileTrans.h | 5 +- ClientCore/RemoteFile.cpp | 4 +- Console/main.cpp | 1 + Gui/Control/ConnectControl.cpp | 2 +- Gui/Control/ConnectControl.h | 1 - Gui/Control/FileControl.h | 5 +- Gui/Control/LogControl.cpp | 15 ++- Gui/Control/LogControl.h | 7 + Gui/Control/cpTableWidget.cpp | 1 + Gui/frelayGUI.cpp | 33 ++--- Gui/main.cpp | 2 +- Protocol/Protocol.cxx | 11 +- Protocol/Protocol.h | 4 +- Server/Server.cpp | 6 +- Struct/InfoClient.h | 5 +- Struct/InfoDirFile.h | 12 +- Test/BaseTest.cpp | 18 +++ Test/CMakeLists.txt | 13 +- Util/Util.cpp | 4 +- crashelper/include/backward.hpp | 231 +++++++++++++------------------- crashelper/src/crashelper.cxx | 9 +- 26 files changed, 250 insertions(+), 246 deletions(-) create mode 100644 Test/BaseTest.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json index 4c394e3..496b033 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,15 +24,16 @@ "-Wno-dev" ], "cmake.environment": { - "QT_LIB_ROOT": "D:/Dev/Qt6/msvc2022_64", - "PATH": "${env:PATH};D:/Dev/Qt6/msvc2022_64/bin" + "QT_LIB_ROOT": "C:/Qt/Qt5.6.3/5.6.3/mingw49_32", + "PATH": "${env:PATH};C:/Qt/Qt5.6.3/5.6.3/mingw49_32/bin" }, // "cmake.environment": { // "QT_LIB_ROOT": "C:/Qt/Qt5.14.2/5.14.2/msvc2017_64", // "PATH": "${env:PATH};C:/Qt/Qt5.14.2/5.14.2/msvc2017_64/bin" // }, "cmake.configureSettings": { - "CMAKE_PREFIX_PATH": "${env:QT_LIB_ROOT}" + "CMAKE_PREFIX_PATH": "${env:QT_LIB_ROOT}", + "XP_PLATFORM_SUPPORT": "ON" }, "cmake.options.statusBarVisibility": "visible", "cmake.generator": "Ninja", diff --git a/CMakeLists.txt b/CMakeLists.txt index c07aec8..e28fd6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.16) -project(frelay VERSION 0.1.3 LANGUAGES CXX) +project(frelay VERSION 0.1.4 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(PROJECT_URL "https://github.com/taynpg/frelay") -set(QT_DEFAULT_MAJOR_VERSION 6) +set(QT_DEFAULT_MAJOR_VERSION 5) set(QAPPLICATION_CLASS QApplication) if (MSVC) @@ -19,15 +19,11 @@ add_definitions(-DCOMPILER_USE_MINGW) endif() if(WIN32) -execute_process(COMMAND cmd /c ver - OUTPUT_VARIABLE VER_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE) -if(VER_OUTPUT MATCHES "XP") - message(STATUS "Windows XP platform.") - add_definitions(-D_WIN32_WINNT=0x0501) +if(DEFINED XP_PLATFORM_SUPPORT) +message(STATUS "For Windows XP platform.") +add_definitions(-D_WIN32_WINNT=0x0501) else() - message(STATUS "Windows NT platform.") - add_definitions(-D_WIN32_WINNT=0x0601) +add_definitions(-D_WIN32_WINNT=0x0601) endif() endif() @@ -39,7 +35,11 @@ include_directories(${PROJECT_BINARY_DIR}) add_definitions(-DFMT_HEADER_ONLY) include_directories(3rd) add_subdirectory(3rd/SingleApplication-3.5.2) + +if(NOT DEFINED COMPILER_USE_MINGW) add_subdirectory(crashelper) +endif() + add_subdirectory(Protocol) add_subdirectory(Server) add_subdirectory(ClientCore) diff --git a/ClientCore/ClientCore.cpp b/ClientCore/ClientCore.cpp index 3bfa32d..c9fa676 100644 --- a/ClientCore/ClientCore.cpp +++ b/ClientCore/ClientCore.cpp @@ -18,6 +18,11 @@ ClientCore::~ClientCore() { } +bool ClientCore::SendFrame(QSharedPointer frame) +{ + return Send(frame); +} + void ClientCore::DoConnect(const QString& ip, quint16 port) { // qDebug() << "doConnect thread:" << QThread::currentThread(); @@ -31,11 +36,6 @@ void ClientCore::DoConnect(const QString& ip, quint16 port) bool ClientCore::Connect(const QString& ip, quint16 port) { - QMutexLocker locker(&conMutex_); - if (!locker.isLocked()) { - qWarning() << QString(tr("%1:%2 already connecting...")).arg(ip).arg(port); - return false; - } socket_->connectToHost(ip, port); if (!socket_->waitForConnected(3000)) { qCritical() << QString(tr("%1:%2 connect failed...")).arg(ip).arg(port); diff --git a/ClientCore/ClientCore.h b/ClientCore/ClientCore.h index e605d22..369cb5b 100644 --- a/ClientCore/ClientCore.h +++ b/ClientCore/ClientCore.h @@ -9,13 +9,14 @@ #include #include #include +#include #include #include #include -#include #include #include #include +#include #include class ClientCore : public QObject @@ -26,6 +27,9 @@ public: ClientCore(QObject* parent = nullptr); ~ClientCore(); +public slots: + bool SendFrame(QSharedPointer frame); + public: void Instance(); bool Connect(const QString& ip, quint16 port); @@ -46,30 +50,15 @@ public: f->type = type; return f; } - /* - When calling syncInvoke of ClientCore, the ClientCore should not be in the GUI's event loop thread. - In other words, if a ClientCore instance is created in the GUI thread, it should be moved to another thread; - otherwise, it will cause a deadlock and freeze the interface. - */ - template static bool syncInvoke(QObject* context, Callable&& func) + static bool syncInvoke(ClientCore* context, QSharedPointer frame) { - auto promise = QSharedPointer>::create(); - QFuture future = promise->future(); - - QMetaObject::invokeMethod( - context, - [func = std::forward(func), promise]() mutable { - try { - promise->addResult(func()); - } catch (...) { - promise->addResult(false); - } - promise->finish(); - }, - Qt::QueuedConnection); - - future.waitForFinished(); - return future.result(); + bool result = false; + bool success = QMetaObject::invokeMethod(context, "SendFrame", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result), + Q_ARG(QSharedPointer, frame)); + if (!success) { + return false; + } + return result; } signals: @@ -114,7 +103,7 @@ public: QTcpSocket* socket_{}; QByteArray recvBuffer_; - bool connected_{ false }; + bool connected_{false}; LocalFile localFile_; }; diff --git a/ClientCore/FileTrans.cpp b/ClientCore/FileTrans.cpp index 2b75a4e..1bb1ba4 100644 --- a/ClientCore/FileTrans.cpp +++ b/ClientCore/FileTrans.cpp @@ -49,7 +49,7 @@ void FileTrans::ReqSendFile(const TransTask& task) } auto frame = clientCore_->GetBuffer(info, FBT_CLI_REQ_SEND, task.remoteId); - if (!ClientCore::syncInvoke(clientCore_, [this, frame]() { return clientCore_->Send(frame); })) { + if (!ClientCore::syncInvoke(clientCore_, frame)) { qCritical() << QString(tr("send req send failed: %1")).arg(info.msg); sendTask_->state = TaskState::STATE_NONE; sendTask_->file.close(); @@ -79,7 +79,7 @@ void FileTrans::ReqDownFile(const TransTask& task) return; } auto frame = clientCore_->GetBuffer(info, FBT_CLI_REQ_DOWN, task.remoteId); - if (!ClientCore::syncInvoke(clientCore_, [this, frame]() { return clientCore_->Send(frame); })) { + if (!ClientCore::syncInvoke(clientCore_, frame)) { qCritical() << QString(tr("send req send failed: %1")).arg(info.msg); downTask_->state = TaskState::STATE_NONE; downTask_->file.close(); @@ -154,7 +154,7 @@ void FileTrans::fbtReqSend(QSharedPointer frame) if (downTask_->state == TaskState::STATE_RUNNING) { info.msg = QString(tr("busy...")); auto f = clientCore_->GetBuffer(info, FBT_CLI_CANOT_SEND, frame->fid); - ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); }); + ClientCore::syncInvoke(clientCore_, f); return; } @@ -165,7 +165,7 @@ void FileTrans::fbtReqSend(QSharedPointer frame) info.msg = QString(tr("open file failed: %1")).arg(newerPath); qCritical() << info.msg; auto f = clientCore_->GetBuffer(info, FBT_CLI_CANOT_SEND, frame->fid); - if (!ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); })) { + if (!ClientCore::syncInvoke(clientCore_, f)) { qCritical() << QString(tr("open recv file:%2 failed, and reply %2 failed.")).arg(info.msg, f->fid); downTask_->file.close(); return; @@ -180,7 +180,7 @@ void FileTrans::fbtReqSend(QSharedPointer frame) info.msg = QString(tr("open recv file success: %1")).arg(newerPath); qInfo() << info.msg; auto f = clientCore_->GetBuffer(info, FBT_CLI_CAN_SEND, frame->fid); - if (!ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); })) { + if (!ClientCore::syncInvoke(clientCore_, f)) { qCritical() << QString(tr("open recv file:%2 success, but reply %2 failed.")).arg(info.msg, frame->fid); downTask_->file.close(); return; @@ -217,7 +217,7 @@ void FileTrans::fbtReqDown(QSharedPointer frame) // reply fileinfo auto f = clientCore_->GetBuffer(info, FBT_CLI_FILE_INFO, frame->fid); - if (!ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); })) { + if (!ClientCore::syncInvoke(clientCore_, f)) { qCritical() << QString(tr("send file %1 info failed.")).arg(info.fromPath); doTask->file.close(); return; @@ -237,7 +237,7 @@ void FileTrans::fbtTransDone(QSharedPointer frame) info.msg = QString(tr("recv file:%1 success.")).arg(downTask_->file.fileName()); qInfo() << info.msg; auto f = clientCore_->GetBuffer(info, FBT_CLI_CAN_DOWN, frame->fid); - ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); }); + ClientCore::syncInvoke(clientCore_, f); return; } qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg); @@ -272,7 +272,7 @@ void FileTrans::fbtFileBuffer(QSharedPointer frame) InfoMsg info; info.msg = downTask_->file.errorString(); auto f = clientCore_->GetBuffer(info, FBT_CLI_TRANS_FAILED, frame->fid); - ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); }); + ClientCore::syncInvoke(clientCore_, f); downTask_->file.close(); } downTask_->tranSize += ws; @@ -351,12 +351,13 @@ void SendThread::run() // shoule add abort action mark. } - QMetaObject::invokeMethod(cliCore_, [this, frame] { - frame->sendRet = cliCore_->Send(frame); - if (frame->call) { - frame->call(frame); - } - }); + // QMetaObject::invokeMethod(cliCore_, [this, frame] { + // frame->sendRet = cliCore_->Send(frame); + // if (frame->call) { + // frame->call(frame); + // } + // }); + ++curSendCount_; if (!isSuccess_) { @@ -372,7 +373,7 @@ void SendThread::run() InfoMsg info; auto f = cliCore_->GetBuffer(info, FBT_CLI_TRANS_DONE, task_->task.remoteId); - ClientCore::syncInvoke(cliCore_, [this, f]() { return cliCore_->Send(f); }); + ClientCore::syncInvoke(cliCore_, f); task_->file.close(); task_->state = TaskState::STATE_FINISH; } diff --git a/ClientCore/FileTrans.h b/ClientCore/FileTrans.h index 5da2260..8358baa 100644 --- a/ClientCore/FileTrans.h +++ b/ClientCore/FileTrans.h @@ -2,11 +2,10 @@ #define FILETRANS_H #include +#include #include #include #include -#include -#include #include "ClientCore.h" @@ -50,7 +49,7 @@ public: void sendCall(QSharedPointer frame); private: - bool isSuccess_{ false }; + bool isSuccess_{false}; ClientCore* cliCore_; quint32 curSendCount_{0}; QSharedPointer task_; diff --git a/ClientCore/RemoteFile.cpp b/ClientCore/RemoteFile.cpp index 5183f59..54a9ea6 100644 --- a/ClientCore/RemoteFile.cpp +++ b/ClientCore/RemoteFile.cpp @@ -19,7 +19,7 @@ bool RemoteFile::GetHome() { InfoMsg info; auto frame = cliCore_->GetBuffer(info, FBT_CLI_ASK_HOME, cliCore_->GetRemoteID()); - return ClientCore::syncInvoke(cliCore_, [this, frame]() { return cliCore_->Send(frame); }); + return ClientCore::syncInvoke(cliCore_, frame); } bool RemoteFile::GetDirFile(const QString& dir) @@ -27,5 +27,5 @@ bool RemoteFile::GetDirFile(const QString& dir) InfoMsg info; info.msg = dir; auto frame = cliCore_->GetBuffer(info, FBT_CLI_ASK_DIRFILE, cliCore_->GetRemoteID()); - return ClientCore::syncInvoke(cliCore_, [this, frame]() { return cliCore_->Send(frame); }); + return ClientCore::syncInvoke(cliCore_, frame); } \ No newline at end of file diff --git a/Console/main.cpp b/Console/main.cpp index ccd81d0..dfdf50a 100644 --- a/Console/main.cpp +++ b/Console/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "Console.h" diff --git a/Gui/Control/ConnectControl.cpp b/Gui/Control/ConnectControl.cpp index 7d64907..bae809b 100644 --- a/Gui/Control/ConnectControl.cpp +++ b/Gui/Control/ConnectControl.cpp @@ -110,7 +110,7 @@ void Connecter::RefreshClient() auto frame = QSharedPointer::create(); frame->data = infoPack(info); frame->type = FBT_SER_MSG_ASKCLIENTS; - auto sendRet = ClientCore::syncInvoke(clientCore_, [this, frame]() { return clientCore_->Send(frame); }); + auto sendRet = ClientCore::syncInvoke(clientCore_, frame); if (!sendRet) { qCritical() << QString(tr("send ask client list failed.")); return; diff --git a/Gui/Control/ConnectControl.h b/Gui/Control/ConnectControl.h index a02cc63..eeb4d9f 100644 --- a/Gui/Control/ConnectControl.h +++ b/Gui/Control/ConnectControl.h @@ -47,7 +47,6 @@ private: private: Ui::Connecter* ui; bool connceted_{false}; - std::thread thContext_; std::function remoteCall_; ClientCore* clientCore_; diff --git a/Gui/Control/FileControl.h b/Gui/Control/FileControl.h index d5a6c6a..312c20e 100644 --- a/Gui/Control/FileControl.h +++ b/Gui/Control/FileControl.h @@ -4,10 +4,11 @@ #include #include #include +#include +#include #include #include -#include -#include +#include namespace Ui { class FileManager; diff --git a/Gui/Control/LogControl.cpp b/Gui/Control/LogControl.cpp index 7ac4ff5..66361a3 100644 --- a/Gui/Control/LogControl.cpp +++ b/Gui/Control/LogControl.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include @@ -17,9 +19,11 @@ LogPrint::LogPrint(QWidget* parent) : QWidget(parent), ui(new Ui::LogPrint) void LogPrint::InitControl() { +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) isLightMode_ = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Light; styleHints_ = QGuiApplication::styleHints(); connect(styleHints_, &QStyleHints::colorSchemeChanged, this, &LogPrint::ColorChange); +#endif ui->pedText->setReadOnly(true); } @@ -29,13 +33,19 @@ std::string LogPrint::now_str() auto time_t_now = std::chrono::system_clock::to_time_t(now); auto milliseconds = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + // std::ostringstream timestamp; + // timestamp << std::put_time(std::localtime(&time_t_now), "%H:%M:%S") << "." << std::setfill('0') << std::setw(3) + // << milliseconds.count() << " "; + + char timeStr[20]; + std::strftime(timeStr, sizeof(timeStr), "%H:%M:%S", std::localtime(&time_t_now)); std::ostringstream timestamp; - timestamp << std::put_time(std::localtime(&time_t_now), "%H:%M:%S") << "." << std::setfill('0') << std::setw(3) - << milliseconds.count() << " "; + timestamp << timeStr << "." << std::setfill('0') << std::setw(3) << milliseconds.count() << " "; return timestamp.str(); } +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) void LogPrint::ColorChange(Qt::ColorScheme scheme) { if (scheme == Qt::ColorScheme::Dark) { @@ -45,6 +55,7 @@ void LogPrint::ColorChange(Qt::ColorScheme scheme) } RePrintLog(); } +#endif LogPrint::~LogPrint() { diff --git a/Gui/Control/LogControl.h b/Gui/Control/LogControl.h index 2bd2a22..cf49a20 100644 --- a/Gui/Control/LogControl.h +++ b/Gui/Control/LogControl.h @@ -36,7 +36,10 @@ public: public: std::string now_str(); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) void ColorChange(Qt::ColorScheme scheme); +#endif private: void InitControl(); @@ -51,7 +54,11 @@ private: QMap lightMap_; QMap darkMap_; QVector logEntries_; + +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) QStyleHints* styleHints_{}; +#endif + QStandardItemModel* model_; }; diff --git a/Gui/Control/cpTableWidget.cpp b/Gui/Control/cpTableWidget.cpp index f8cd150..e4c3ed1 100644 --- a/Gui/Control/cpTableWidget.cpp +++ b/Gui/Control/cpTableWidget.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "GuiUtil/Public.h" diff --git a/Gui/frelayGUI.cpp b/Gui/frelayGUI.cpp index aca9a10..fd197c4 100644 --- a/Gui/frelayGUI.cpp +++ b/Gui/frelayGUI.cpp @@ -92,25 +92,20 @@ void frelayGUI::ControlLayout() void frelayGUI::ControlMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg) { - QMetaObject::invokeMethod( - qApp, - [type, msg]() { - switch (type) { - case QtDebugMsg: - logPrint->Debug(msg); - break; - case QtInfoMsg: - logPrint->Info(msg); - break; - case QtWarningMsg: - logPrint->Warn(msg); - break; - default: - logPrint->Error(msg); - break; - } - }, - Qt::QueuedConnection); + switch (type) { + case QtDebugMsg: + logPrint->Debug(msg); + break; + case QtInfoMsg: + logPrint->Info(msg); + break; + case QtWarningMsg: + logPrint->Warn(msg); + break; + default: + logPrint->Error(msg); + break; + } } void frelayGUI::HandleTask(const QVector& tasks) diff --git a/Gui/main.cpp b/Gui/main.cpp index ec35e28..d9036d7 100644 --- a/Gui/main.cpp +++ b/Gui/main.cpp @@ -20,9 +20,9 @@ int main(int argc, char* argv[]) #else backward::SetDumpLogSavePath(configDir + QDir::separator() + "dumplog"); #endif + CRASHELPER_MARK_ENTRY(); #endif - CRASHELPER_MARK_ENTRY(); SingleApplication a(argc, argv); #ifdef _WIN32 diff --git a/Protocol/Protocol.cxx b/Protocol/Protocol.cxx index bbbcd5b..97e6b0e 100644 --- a/Protocol/Protocol.cxx +++ b/Protocol/Protocol.cxx @@ -1,5 +1,6 @@ #include "Protocol.h" +#include #include #include @@ -14,12 +15,12 @@ QSharedPointer Protocol::ParseBuffer(QByteArray& buffer) int headerPos = buffer.indexOf(protocolHeader); if (headerPos == -1) { - return nullptr; + return QSharedPointer(); } const int minFrameSize = protocolHeader.size() + sizeof(uint16_t) + 32 + 32 + sizeof(uint32_t) + protocolTail.size(); if (buffer.size() - headerPos < minFrameSize) { - return nullptr; + return QSharedPointer(); } QDataStream stream(buffer.mid(headerPos)); @@ -29,7 +30,7 @@ QSharedPointer Protocol::ParseBuffer(QByteArray& buffer) header.resize(protocolHeader.size()); stream.readRawData(header.data(), protocolHeader.size()); if (header != protocolHeader) { - return nullptr; + return QSharedPointer(); } FrameBufferType type; @@ -51,7 +52,7 @@ QSharedPointer Protocol::ParseBuffer(QByteArray& buffer) int totalFrameSize = minFrameSize - protocolTail.size() + dataLen; if (buffer.size() - headerPos < totalFrameSize) { - return nullptr; + return QSharedPointer(); } QByteArray data; if (dataLen > 0) { @@ -62,7 +63,7 @@ QSharedPointer Protocol::ParseBuffer(QByteArray& buffer) tail.resize(protocolTail.size()); stream.readRawData(tail.data(), protocolTail.size()); if (tail != protocolTail) { - return nullptr; + return QSharedPointer(); } auto frame = QSharedPointer::create(); frame->type = type; diff --git a/Protocol/Protocol.h b/Protocol/Protocol.h index 766c9a1..dafc1a4 100644 --- a/Protocol/Protocol.h +++ b/Protocol/Protocol.h @@ -2,9 +2,10 @@ #define PROTOCOL_H #include +#include #include #include -#include +#include constexpr quint32 CHUNK_BUF_SIZE = 1 * 1024 * 1024; @@ -54,5 +55,4 @@ public: static QByteArray PackBuffer(const QSharedPointer& frame); }; - #endif // PROTOCOL_H diff --git a/Server/Server.cpp b/Server/Server.cpp index bc1ef78..1fd75b0 100644 --- a/Server/Server.cpp +++ b/Server/Server.cpp @@ -63,7 +63,8 @@ void Server::onNewConnection() client->socket = clientSocket; client->socket->setProperty("clientId", clientId); client->id = clientId; - client->connectTime = QDateTime::currentSecsSinceEpoch(); + // client->connectTime = QDateTime::currentSecsSinceEpoch(); + client->connectTime = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000; connect(clientSocket, &QTcpSocket::readyRead, this, &Server::onReadyRead); connect(clientSocket, &QTcpSocket::disconnected, this, &Server::onClientDisconnected); @@ -198,7 +199,8 @@ bool Server::sendData(QTcpSocket* socket, QSharedPointer frame) void Server::monitorClients() { - qint64 now = QDateTime::currentSecsSinceEpoch(); + // qint64 now = QDateTime::currentSecsSinceEpoch(); + qint64 now = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000; QWriteLocker locker(&rwLock_); for (auto it = clients_.begin(); it != clients_.end();) { diff --git a/Struct/InfoClient.h b/Struct/InfoClient.h index 272d42f..d768c5a 100644 --- a/Struct/InfoClient.h +++ b/Struct/InfoClient.h @@ -30,14 +30,15 @@ struct InfoClientVec { void serialize(QDataStream& data) const { - data << vec.size(); + uint32_t size = static_cast(vec.size()); + data << size; for (const auto& info : vec) { data << info; } } void deserialize(QDataStream& data) { - qsizetype size; + uint32_t size = 0; data >> size; vec.resize(size); for (quint32 i = 0; i < size; ++i) { diff --git a/Struct/InfoDirFile.h b/Struct/InfoDirFile.h index 93f7e04..feea9b8 100644 --- a/Struct/InfoDirFile.h +++ b/Struct/InfoDirFile.h @@ -19,12 +19,15 @@ struct DirFileInfo { void serialize(QDataStream& data) const { - data << name << size << type << fullPath << permission << lastModified; + uint32_t t = static_cast(type); + data << name << size << t << fullPath << permission << lastModified; } void deserialize(QDataStream& data) { - data >> name >> size >> type >> fullPath >> permission >> lastModified; + uint32_t t = 0; + data >> name >> size >> t >> fullPath >> permission >> lastModified; + type = static_cast(t); } }; @@ -37,7 +40,8 @@ struct DirFileInfoVec { void serialize(QDataStream& data) const { - data << vec.size(); + uint32_t size = static_cast(vec.size()); + data << size; for (const auto& info : vec) { data << info; } @@ -45,7 +49,7 @@ struct DirFileInfoVec { } void deserialize(QDataStream& data) { - qsizetype size; + uint32_t size = 0; data >> size; vec.resize(size); for (quint32 i = 0; i < size; ++i) { diff --git a/Test/BaseTest.cpp b/Test/BaseTest.cpp new file mode 100644 index 0000000..6d96019 --- /dev/null +++ b/Test/BaseTest.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +void DateTimeTest() +{ + qDebug() << QDateTime::currentDateTime().toMSecsSinceEpoch(); +} + +int main(int argc, char** argv) +{ + QCoreApplication app(argc, argv); + + qDebug() << "Running..."; + DateTimeTest(); + + return app.exec(); +} \ No newline at end of file diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 93d3031..0a31571 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -1,13 +1,24 @@ cmake_minimum_required(VERSION 3.16) project(frelayTest LANGUAGES CXX) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) + set(MSOURCES msgTest.h msgTest.cpp protocolTest.cpp infoTest.h infoTest.cpp ) add_executable(frelayTest ${MSOURCES}) -target_link_libraries(frelayTest PRIVATE Protocol Util) \ No newline at end of file +target_link_libraries(frelayTest PRIVATE Protocol Util) + +add_executable(frelayBaseTest BaseTest.cpp) +target_link_libraries(frelayBaseTest Qt${QT_VERSION_MAJOR}::Core) diff --git a/Util/Util.cpp b/Util/Util.cpp index cbf6a50..2c32b52 100644 --- a/Util/Util.cpp +++ b/Util/Util.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -77,9 +78,6 @@ void Util::InitLogger(const QString& logPath, const QString& mark) spdlog::register_logger(logger); } -#include -#include - // do not check exit QString Util::Get2FilePath(const QString& file, const QString& directory) { diff --git a/crashelper/include/backward.hpp b/crashelper/include/backward.hpp index 5e3feb9..6aa4cdd 100644 --- a/crashelper/include/backward.hpp +++ b/crashelper/include/backward.hpp @@ -335,21 +335,19 @@ #if defined(BACKWARD_SYSTEM_WINDOWS) +#include #include #include #include - -#include typedef SSIZE_T ssize_t; #ifndef NOMINMAX #define NOMINMAX #endif -#include -#include - #include #include +#include +#include #ifndef __clang__ #undef NOINLINE @@ -1293,8 +1291,7 @@ public: for (;;) { // NOTE: this only works if PDBs are already loaded! SetLastError(0); - if (!StackWalk64(machine_type_, process, thd_, &s, ctx_, NULL, SymFunctionTableAccess64, SymGetModuleBase64, - NULL)) + if (!StackWalk64(machine_type_, process, thd_, &s, ctx_, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; if (s.AddrReturn.Offset == 0) @@ -1797,13 +1794,11 @@ private: static void find_in_section_trampoline(bfd*, asection* section, void* data) { find_sym_context* context = static_cast(data); - context->self->find_in_section(reinterpret_cast(context->addr), - reinterpret_cast(context->base_addr), context->fobj, section, - context->result); + context->self->find_in_section(reinterpret_cast(context->addr), reinterpret_cast(context->base_addr), + context->fobj, section, context->result); } - void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject* fobj, asection* section, - find_sym_result& result) + void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject* fobj, asection* section, find_sym_result& result) { if (result.found) return; @@ -1844,8 +1839,8 @@ private: } if (!result.found && fobj->dynamic_symtab) { - result.found = bfd_find_nearest_line(fobj->handle.get(), section, fobj->dynamic_symtab.get(), - addr - sec_addr, &result.filename, &result.funcname, &result.line); + result.found = bfd_find_nearest_line(fobj->handle.get(), section, fobj->dynamic_symtab.get(), addr - sec_addr, + &result.filename, &result.funcname, &result.line); } #if defined(__clang__) #pragma clang diagnostic pop @@ -2490,62 +2485,61 @@ private: // We go the preprocessor way to avoid having to create templated // classes or using gelf (which might throw a compiler error if 64 bit // is not supported -#define ELF_GET_DATA(ARCH) \ - Elf_Scn* elf_section = 0; \ - Elf_Data* elf_data = 0; \ - Elf##ARCH##_Shdr* section_header = 0; \ - Elf_Scn* symbol_section = 0; \ - size_t symbol_count = 0; \ - size_t symbol_strings = 0; \ - Elf##ARCH##_Sym* symbol = 0; \ - const char* section_name = 0; \ - \ - while ((elf_section = elf_nextscn(elf_handle.get(), elf_section)) != NULL) { \ - section_header = elf##ARCH##_getshdr(elf_section); \ - if (section_header == NULL) { \ - return r; \ - } \ - \ - if ((section_name = elf_strptr(elf_handle.get(), shdrstrndx, section_header->sh_name)) == NULL) { \ - return r; \ - } \ - \ - if (cstrings_eq(section_name, ".gnu_debuglink")) { \ - elf_data = elf_getdata(elf_section, NULL); \ - if (elf_data && elf_data->d_size > 0) { \ - debuglink = std::string(reinterpret_cast(elf_data->d_buf)); \ - } \ - } \ - \ - switch (section_header->sh_type) { \ - case SHT_SYMTAB: \ - symbol_section = elf_section; \ - symbol_count = section_header->sh_size / section_header->sh_entsize; \ - symbol_strings = section_header->sh_link; \ - break; \ - \ - /* We use .dynsyms as a last resort, we prefer .symtab */ \ - case SHT_DYNSYM: \ - if (!symbol_section) { \ - symbol_section = elf_section; \ - symbol_count = section_header->sh_size / section_header->sh_entsize; \ - symbol_strings = section_header->sh_link; \ - } \ - break; \ - } \ - } \ - \ - if (symbol_section && symbol_count && symbol_strings) { \ - elf_data = elf_getdata(symbol_section, NULL); \ - symbol = reinterpret_cast(elf_data->d_buf); \ - for (size_t i = 0; i < symbol_count; ++i) { \ - int type = ELF##ARCH##_ST_TYPE(symbol->st_info); \ - if (type == STT_FUNC && symbol->st_value > 0) { \ - r.symbol_cache[symbol->st_value] = \ - std::string(elf_strptr(elf_handle.get(), symbol_strings, symbol->st_name)); \ - } \ - ++symbol; \ - } \ +#define ELF_GET_DATA(ARCH) \ + Elf_Scn* elf_section = 0; \ + Elf_Data* elf_data = 0; \ + Elf##ARCH##_Shdr* section_header = 0; \ + Elf_Scn* symbol_section = 0; \ + size_t symbol_count = 0; \ + size_t symbol_strings = 0; \ + Elf##ARCH##_Sym* symbol = 0; \ + const char* section_name = 0; \ + \ + while ((elf_section = elf_nextscn(elf_handle.get(), elf_section)) != NULL) { \ + section_header = elf##ARCH##_getshdr(elf_section); \ + if (section_header == NULL) { \ + return r; \ + } \ + \ + if ((section_name = elf_strptr(elf_handle.get(), shdrstrndx, section_header->sh_name)) == NULL) { \ + return r; \ + } \ + \ + if (cstrings_eq(section_name, ".gnu_debuglink")) { \ + elf_data = elf_getdata(elf_section, NULL); \ + if (elf_data && elf_data->d_size > 0) { \ + debuglink = std::string(reinterpret_cast(elf_data->d_buf)); \ + } \ + } \ + \ + switch (section_header->sh_type) { \ + case SHT_SYMTAB: \ + symbol_section = elf_section; \ + symbol_count = section_header->sh_size / section_header->sh_entsize; \ + symbol_strings = section_header->sh_link; \ + break; \ + \ + /* We use .dynsyms as a last resort, we prefer .symtab */ \ + case SHT_DYNSYM: \ + if (!symbol_section) { \ + symbol_section = elf_section; \ + symbol_count = section_header->sh_size / section_header->sh_entsize; \ + symbol_strings = section_header->sh_link; \ + } \ + break; \ + } \ + } \ + \ + if (symbol_section && symbol_count && symbol_strings) { \ + elf_data = elf_getdata(symbol_section, NULL); \ + symbol = reinterpret_cast(elf_data->d_buf); \ + for (size_t i = 0; i < symbol_count; ++i) { \ + int type = ELF##ARCH##_ST_TYPE(symbol->st_info); \ + if (type == STT_FUNC && symbol->st_value > 0) { \ + r.symbol_cache[symbol->st_value] = std::string(elf_strptr(elf_handle.get(), symbol_strings, symbol->st_name)); \ + } \ + ++symbol; \ + } \ } if (e_ident[EI_CLASS] == ELFCLASS32) { @@ -2639,8 +2633,7 @@ private: if (dwarf_srclines_b(die, 0, &table_count, &de.line_context, &error) == DW_DLV_OK) { // Get the source lines for this line context, to be deallocated // later - if (dwarf_srclines_from_linecontext(de.line_context, &de.line_buffer, &de.line_count, &error) == - DW_DLV_OK) { + if (dwarf_srclines_from_linecontext(de.line_context, &de.line_buffer, &de.line_count, &error) == DW_DLV_OK) { // Add all the addresses to our map for (int i = 0; i < de.line_count; i++) { @@ -2832,8 +2825,7 @@ private: if (dwarf_get_ranges_a(dwarf, offset, die, &ranges, &ranges_count, &byte_count, &error) == DW_DLV_OK) { has_ranges = ranges_count != 0; for (int i = 0; i < ranges_count; i++) { - if (ranges[i].dwr_addr1 != 0 && pc >= ranges[i].dwr_addr1 + low_pc && - pc < ranges[i].dwr_addr2 + low_pc) { + if (ranges[i].dwr_addr1 != 0 && pc >= ranges[i].dwr_addr1 + low_pc && pc < ranges[i].dwr_addr2 + low_pc) { result = true; break; } @@ -2908,8 +2900,7 @@ private: std::string result; bool found = false; - while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, &tu_signature, 0, &next_cu_header, 0, &error) == - DW_DLV_OK) { + while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, &tu_signature, 0, &next_cu_header, 0, &error) == DW_DLV_OK) { if (strncmp(signature.signature, tu_signature.signature, 8) == 0) { Dwarf_Die type_cu_die = 0; @@ -3072,8 +3063,8 @@ private: } // Resolve the function return type and parameters - static void set_function_parameters(std::string& function_name, std::vector& ns, - dwarf_fileobject& fobj, Dwarf_Die die) + static void set_function_parameters(std::string& function_name, std::vector& ns, dwarf_fileobject& fobj, + Dwarf_Die die) { Dwarf_Debug dwarf = fobj.dwarf_handle.get(); Dwarf_Error error = DW_DLE_NE; @@ -3335,8 +3326,8 @@ private: } template - static bool deep_first_search_by_pc(dwarf_fileobject& fobj, Dwarf_Die parent_die, Dwarf_Addr pc, - std::vector& ns, CB cb) + static bool deep_first_search_by_pc(dwarf_fileobject& fobj, Dwarf_Die parent_die, Dwarf_Addr pc, std::vector& ns, + CB cb) { Dwarf_Die current_die = 0; Dwarf_Debug dwarf = fobj.dwarf_handle.get(); @@ -3371,8 +3362,7 @@ private: bool declaration = false; Dwarf_Attribute attr_mem; - if (tag != DW_TAG_class_type && - dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) == DW_DLV_OK) { + if (tag != DW_TAG_class_type && dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) == DW_DLV_OK) { Dwarf_Bool flag = 0; if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) { declaration = flag != 0; @@ -3501,8 +3491,7 @@ private: Dwarf_Half tag = 0; returnDie = 0; - while (!found && - dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, &next_cu_header, 0, &error) == DW_DLV_OK) { + while (!found && dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, &next_cu_header, 0, &error) == DW_DLV_OK) { if (returnDie) dwarf_dealloc(dwarf, returnDie, DW_DLA_DIE); @@ -3643,8 +3632,7 @@ private: details::handle _symbols; }; -template <> -class TraceResolverImpl : public TraceResolverDarwinImpl +template <> class TraceResolverImpl : public TraceResolverDarwinImpl { }; @@ -3712,8 +3700,7 @@ public: EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); module_handles.resize(cbNeeded / sizeof(HMODULE)); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); - std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), - get_mod_info(process)); + std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), get_mod_info(process)); void* base = modules[0].base_address; IMAGE_NT_HEADERS* h = ImageNtHeader(base); image_type = h->FileHeader.Machine; @@ -3742,9 +3729,8 @@ public: char* lpMsgBuf; DWORD dw = GetLastError(); - if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&lpMsgBuf, 0, NULL)) { + if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&lpMsgBuf, 0, NULL)) { std::fprintf(stderr, "%s\n", lpMsgBuf); LocalFree(lpMsgBuf); } @@ -3959,8 +3945,8 @@ public: return src_file.get_lines(start, context_size); } - lines_t get_combined_snippet(const std::string& filename_a, unsigned line_a, const std::string& filename_b, - unsigned line_b, unsigned context_size) + lines_t get_combined_snippet(const std::string& filename_a, unsigned line_a, const std::string& filename_b, unsigned line_b, + unsigned context_size) { SourceFile& src_file_a = get_src_file(filename_a); SourceFile& src_file_b = get_src_file(filename_b); @@ -4007,11 +3993,7 @@ private: /*************** PRINTER ***************/ namespace ColorMode { -enum type { - automatic, - never, - always -}; +enum type { automatic, never, always }; } // namespace ColorMode class cfile_streambuf : public std::streambuf @@ -4055,11 +4037,7 @@ private: #ifdef BACKWARD_SYSTEM_LINUX namespace Color { -enum type { - yellow = 33, - purple = 35, - reset = 39 -}; +enum type { yellow = 33, purple = 35, reset = 39 }; } // namespace Color class Colorize @@ -4111,11 +4089,7 @@ private: #else // ndef BACKWARD_SYSTEM_LINUX namespace Color { -enum type { - yellow = 0, - purple = 0, - reset = 0 -}; +enum type { yellow = 0, purple = 0, reset = 0 }; } // namespace Color class Colorize @@ -4148,11 +4122,7 @@ public: int trace_context_size; Printer() - : snippet(true), - color_mode(ColorMode::automatic), - address(false), - object(false), - inliner_context_size(5), + : snippet(true), color_mode(ColorMode::automatic), address(false), object(false), inliner_context_size(5), trace_context_size(7) { } @@ -4211,8 +4181,7 @@ private: } } - template - void print_stacktrace(IT begin, IT end, std::ostream& os, size_t thread_id, Colorize& colorize) + template void print_stacktrace(IT begin, IT end, std::ostream& os, size_t thread_id, Colorize& colorize) { print_header(os, thread_id); for (; begin != end; ++begin) { @@ -4235,8 +4204,7 @@ private: bool already_indented = true; if (!trace.source.filename.size() || object) { - os << " Object \"" << trace.object_filename << "\", at " << trace.addr << ", in " << trace.object_function - << "\n"; + os << " Object \"" << trace.object_filename << "\", at " << trace.addr << ", in " << trace.object_function << "\n"; already_indented = false; } @@ -4263,14 +4231,13 @@ private: } } - void print_snippet(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, - Colorize& colorize, Color::type color_code, int context_size) + void print_snippet(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, Colorize& colorize, + Color::type color_code, int context_size) { using namespace std; typedef SnippetFactory::lines_t lines_t; - lines_t lines = - _snippets.get_snippet(source_loc.filename, source_loc.line, static_cast(context_size)); + lines_t lines = _snippets.get_snippet(source_loc.filename, source_loc.line, static_cast(context_size)); for (lines_t::const_iterator it = lines.begin(); it != lines.end(); ++it) { if (it->first == source_loc.line) { @@ -4286,11 +4253,9 @@ private: } } - void print_source_loc(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, - void* addr = nullptr) + void print_source_loc(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, void* addr = nullptr) { - os << indent << "Source \"" << source_loc.filename << "\", line " << source_loc.line << ", in " - << source_loc.function; + os << indent << "Source \"" << source_loc.filename << "\", line " << source_loc.line << ", in " << source_loc.function; if (address && addr != nullptr) { os << " [" << addr << "]"; @@ -4484,9 +4449,9 @@ private: class SignalHandling { private: - static inline std::function crash_path_getter_ = nullptr; - static inline std::function crash_use_handler_ = nullptr; - static inline std::function user_sig_handler_ = nullptr; + static std::function crash_path_getter_; + static std::function crash_use_handler_; + static std::function user_sig_handler_; public: static void register_crash_path(std::function&& crash_path_getter) @@ -4562,12 +4527,7 @@ private: return &data; } - enum class crash_status { - running, - crashed, - normal_exit, - ending - }; + enum class crash_status { running, crashed, normal_exit, ending }; static crash_status& crashed() { @@ -4637,8 +4597,7 @@ private: } } - static inline void __cdecl invalid_parameter_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, - uintptr_t) + static inline void __cdecl invalid_parameter_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t) { crash_handler(signal_skip_recs); abort(); diff --git a/crashelper/src/crashelper.cxx b/crashelper/src/crashelper.cxx index 3e5478f..c733f2f 100644 --- a/crashelper/src/crashelper.cxx +++ b/crashelper/src/crashelper.cxx @@ -8,6 +8,12 @@ #include #include +#include "backward.hpp" + +std::function backward::SignalHandling::crash_path_getter_ = nullptr; +std::function backward::SignalHandling::crash_use_handler_ = nullptr; +std::function backward::SignalHandling::user_sig_handler_ = nullptr; + namespace backward { class crashHelper @@ -126,8 +132,7 @@ void UseExceptionHandler(EXCEPTION_POINTERS* exception) QString fullPath = QDir(h.dumpSavePath_).absoluteFilePath(dumpName); QString fullFailedPath = QDir(h.dumpSavePath_).absoluteFilePath(dumpFailedLog); - HANDLE hFile = - CreateFile(fullPath.toStdWString().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile = CreateFile(fullPath.toStdString().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { QFile file(fullFailedPath); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {