xp-sp3: change grammer to support Qt5.6.3 for xp with sp3 system.

This commit is contained in:
2025-06-25 10:54:04 +08:00
parent 1f9275ed72
commit 60f5cb62b1
26 changed files with 250 additions and 246 deletions

View File

@@ -24,15 +24,16 @@
"-Wno-dev" "-Wno-dev"
], ],
"cmake.environment": { "cmake.environment": {
"QT_LIB_ROOT": "D:/Dev/Qt6/msvc2022_64", "QT_LIB_ROOT": "C:/Qt/Qt5.6.3/5.6.3/mingw49_32",
"PATH": "${env:PATH};D:/Dev/Qt6/msvc2022_64/bin" "PATH": "${env:PATH};C:/Qt/Qt5.6.3/5.6.3/mingw49_32/bin"
}, },
// "cmake.environment": { // "cmake.environment": {
// "QT_LIB_ROOT": "C:/Qt/Qt5.14.2/5.14.2/msvc2017_64", // "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" // "PATH": "${env:PATH};C:/Qt/Qt5.14.2/5.14.2/msvc2017_64/bin"
// }, // },
"cmake.configureSettings": { "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.options.statusBarVisibility": "visible",
"cmake.generator": "Ninja", "cmake.generator": "Ninja",

View File

@@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.16) 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 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PROJECT_URL "https://github.com/taynpg/frelay") set(PROJECT_URL "https://github.com/taynpg/frelay")
set(QT_DEFAULT_MAJOR_VERSION 6) set(QT_DEFAULT_MAJOR_VERSION 5)
set(QAPPLICATION_CLASS QApplication) set(QAPPLICATION_CLASS QApplication)
if (MSVC) if (MSVC)
@@ -19,15 +19,11 @@ add_definitions(-DCOMPILER_USE_MINGW)
endif() endif()
if(WIN32) if(WIN32)
execute_process(COMMAND cmd /c ver if(DEFINED XP_PLATFORM_SUPPORT)
OUTPUT_VARIABLE VER_OUTPUT message(STATUS "For Windows XP platform.")
OUTPUT_STRIP_TRAILING_WHITESPACE) add_definitions(-D_WIN32_WINNT=0x0501)
if(VER_OUTPUT MATCHES "XP")
message(STATUS "Windows XP platform.")
add_definitions(-D_WIN32_WINNT=0x0501)
else() else()
message(STATUS "Windows NT platform.") add_definitions(-D_WIN32_WINNT=0x0601)
add_definitions(-D_WIN32_WINNT=0x0601)
endif() endif()
endif() endif()
@@ -39,7 +35,11 @@ include_directories(${PROJECT_BINARY_DIR})
add_definitions(-DFMT_HEADER_ONLY) add_definitions(-DFMT_HEADER_ONLY)
include_directories(3rd) include_directories(3rd)
add_subdirectory(3rd/SingleApplication-3.5.2) add_subdirectory(3rd/SingleApplication-3.5.2)
if(NOT DEFINED COMPILER_USE_MINGW)
add_subdirectory(crashelper) add_subdirectory(crashelper)
endif()
add_subdirectory(Protocol) add_subdirectory(Protocol)
add_subdirectory(Server) add_subdirectory(Server)
add_subdirectory(ClientCore) add_subdirectory(ClientCore)

View File

@@ -18,6 +18,11 @@ ClientCore::~ClientCore()
{ {
} }
bool ClientCore::SendFrame(QSharedPointer<FrameBuffer> frame)
{
return Send(frame);
}
void ClientCore::DoConnect(const QString& ip, quint16 port) void ClientCore::DoConnect(const QString& ip, quint16 port)
{ {
// qDebug() << "doConnect thread:" << QThread::currentThread(); // 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) 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); socket_->connectToHost(ip, port);
if (!socket_->waitForConnected(3000)) { if (!socket_->waitForConnected(3000)) {
qCritical() << QString(tr("%1:%2 connect failed...")).arg(ip).arg(port); qCritical() << QString(tr("%1:%2 connect failed...")).arg(ip).arg(port);

View File

@@ -9,13 +9,14 @@
#include <Protocol.h> #include <Protocol.h>
#include <QDataStream> #include <QDataStream>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher>
#include <QHostAddress> #include <QHostAddress>
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QPromise>
#include <QQueue> #include <QQueue>
#include <QTcpSocket> #include <QTcpSocket>
#include <QThread> #include <QThread>
#include <QtConcurrent/QtConcurrentRun>
#include <array> #include <array>
class ClientCore : public QObject class ClientCore : public QObject
@@ -26,6 +27,9 @@ public:
ClientCore(QObject* parent = nullptr); ClientCore(QObject* parent = nullptr);
~ClientCore(); ~ClientCore();
public slots:
bool SendFrame(QSharedPointer<FrameBuffer> frame);
public: public:
void Instance(); void Instance();
bool Connect(const QString& ip, quint16 port); bool Connect(const QString& ip, quint16 port);
@@ -46,30 +50,15 @@ public:
f->type = type; f->type = type;
return f; return f;
} }
/* static bool syncInvoke(ClientCore* context, QSharedPointer<FrameBuffer> frame)
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 <typename Callable> static bool syncInvoke(QObject* context, Callable&& func)
{ {
auto promise = QSharedPointer<QPromise<bool>>::create(); bool result = false;
QFuture<bool> future = promise->future(); bool success = QMetaObject::invokeMethod(context, "SendFrame", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result),
Q_ARG(QSharedPointer<FrameBuffer>, frame));
QMetaObject::invokeMethod( if (!success) {
context, return false;
[func = std::forward<Callable>(func), promise]() mutable { }
try { return result;
promise->addResult(func());
} catch (...) {
promise->addResult(false);
}
promise->finish();
},
Qt::QueuedConnection);
future.waitForFinished();
return future.result();
} }
signals: signals:
@@ -114,7 +103,7 @@ public:
QTcpSocket* socket_{}; QTcpSocket* socket_{};
QByteArray recvBuffer_; QByteArray recvBuffer_;
bool connected_{ false }; bool connected_{false};
LocalFile localFile_; LocalFile localFile_;
}; };

View File

@@ -49,7 +49,7 @@ void FileTrans::ReqSendFile(const TransTask& task)
} }
auto frame = clientCore_->GetBuffer(info, FBT_CLI_REQ_SEND, task.remoteId); 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); qCritical() << QString(tr("send req send failed: %1")).arg(info.msg);
sendTask_->state = TaskState::STATE_NONE; sendTask_->state = TaskState::STATE_NONE;
sendTask_->file.close(); sendTask_->file.close();
@@ -79,7 +79,7 @@ void FileTrans::ReqDownFile(const TransTask& task)
return; return;
} }
auto frame = clientCore_->GetBuffer(info, FBT_CLI_REQ_DOWN, task.remoteId); 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); qCritical() << QString(tr("send req send failed: %1")).arg(info.msg);
downTask_->state = TaskState::STATE_NONE; downTask_->state = TaskState::STATE_NONE;
downTask_->file.close(); downTask_->file.close();
@@ -154,7 +154,7 @@ void FileTrans::fbtReqSend(QSharedPointer<FrameBuffer> frame)
if (downTask_->state == TaskState::STATE_RUNNING) { if (downTask_->state == TaskState::STATE_RUNNING) {
info.msg = QString(tr("busy...")); info.msg = QString(tr("busy..."));
auto f = clientCore_->GetBuffer(info, FBT_CLI_CANOT_SEND, frame->fid); 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; return;
} }
@@ -165,7 +165,7 @@ void FileTrans::fbtReqSend(QSharedPointer<FrameBuffer> frame)
info.msg = QString(tr("open file failed: %1")).arg(newerPath); info.msg = QString(tr("open file failed: %1")).arg(newerPath);
qCritical() << info.msg; qCritical() << info.msg;
auto f = clientCore_->GetBuffer(info, FBT_CLI_CANOT_SEND, frame->fid); 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); qCritical() << QString(tr("open recv file:%2 failed, and reply %2 failed.")).arg(info.msg, f->fid);
downTask_->file.close(); downTask_->file.close();
return; return;
@@ -180,7 +180,7 @@ void FileTrans::fbtReqSend(QSharedPointer<FrameBuffer> frame)
info.msg = QString(tr("open recv file success: %1")).arg(newerPath); info.msg = QString(tr("open recv file success: %1")).arg(newerPath);
qInfo() << info.msg; qInfo() << info.msg;
auto f = clientCore_->GetBuffer(info, FBT_CLI_CAN_SEND, frame->fid); 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); qCritical() << QString(tr("open recv file:%2 success, but reply %2 failed.")).arg(info.msg, frame->fid);
downTask_->file.close(); downTask_->file.close();
return; return;
@@ -217,7 +217,7 @@ void FileTrans::fbtReqDown(QSharedPointer<FrameBuffer> frame)
// reply fileinfo // reply fileinfo
auto f = clientCore_->GetBuffer(info, FBT_CLI_FILE_INFO, frame->fid); 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); qCritical() << QString(tr("send file %1 info failed.")).arg(info.fromPath);
doTask->file.close(); doTask->file.close();
return; return;
@@ -237,7 +237,7 @@ void FileTrans::fbtTransDone(QSharedPointer<FrameBuffer> frame)
info.msg = QString(tr("recv file:%1 success.")).arg(downTask_->file.fileName()); info.msg = QString(tr("recv file:%1 success.")).arg(downTask_->file.fileName());
qInfo() << info.msg; qInfo() << info.msg;
auto f = clientCore_->GetBuffer(info, FBT_CLI_CAN_DOWN, frame->fid); 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; return;
} }
qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg); qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg);
@@ -272,7 +272,7 @@ void FileTrans::fbtFileBuffer(QSharedPointer<FrameBuffer> frame)
InfoMsg info; InfoMsg info;
info.msg = downTask_->file.errorString(); info.msg = downTask_->file.errorString();
auto f = clientCore_->GetBuffer(info, FBT_CLI_TRANS_FAILED, frame->fid); 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_->file.close();
} }
downTask_->tranSize += ws; downTask_->tranSize += ws;
@@ -351,12 +351,13 @@ void SendThread::run()
// shoule add abort action mark. // shoule add abort action mark.
} }
QMetaObject::invokeMethod(cliCore_, [this, frame] { // QMetaObject::invokeMethod(cliCore_, [this, frame] {
frame->sendRet = cliCore_->Send(frame); // frame->sendRet = cliCore_->Send(frame);
if (frame->call) { // if (frame->call) {
frame->call(frame); // frame->call(frame);
} // }
}); // });
++curSendCount_; ++curSendCount_;
if (!isSuccess_) { if (!isSuccess_) {
@@ -372,7 +373,7 @@ void SendThread::run()
InfoMsg info; InfoMsg info;
auto f = cliCore_->GetBuffer(info, FBT_CLI_TRANS_DONE, task_->task.remoteId); 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_->file.close();
task_->state = TaskState::STATE_FINISH; task_->state = TaskState::STATE_FINISH;
} }

View File

@@ -2,11 +2,10 @@
#define FILETRANS_H #define FILETRANS_H
#include <QFile> #include <QFile>
#include <QFuture>
#include <QMap> #include <QMap>
#include <QMutex> #include <QMutex>
#include <QVector> #include <QVector>
#include <QFuture>
#include <QPromise>
#include "ClientCore.h" #include "ClientCore.h"
@@ -50,7 +49,7 @@ public:
void sendCall(QSharedPointer<FrameBuffer> frame); void sendCall(QSharedPointer<FrameBuffer> frame);
private: private:
bool isSuccess_{ false }; bool isSuccess_{false};
ClientCore* cliCore_; ClientCore* cliCore_;
quint32 curSendCount_{0}; quint32 curSendCount_{0};
QSharedPointer<DoTransTask> task_; QSharedPointer<DoTransTask> task_;

View File

@@ -19,7 +19,7 @@ bool RemoteFile::GetHome()
{ {
InfoMsg info; InfoMsg info;
auto frame = cliCore_->GetBuffer(info, FBT_CLI_ASK_HOME, cliCore_->GetRemoteID()); 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) bool RemoteFile::GetDirFile(const QString& dir)
@@ -27,5 +27,5 @@ bool RemoteFile::GetDirFile(const QString& dir)
InfoMsg info; InfoMsg info;
info.msg = dir; info.msg = dir;
auto frame = cliCore_->GetBuffer(info, FBT_CLI_ASK_DIRFILE, cliCore_->GetRemoteID()); 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);
} }

View File

@@ -1,5 +1,6 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <Util.h> #include <Util.h>
#include <iostream>
#include "Console.h" #include "Console.h"

View File

@@ -110,7 +110,7 @@ void Connecter::RefreshClient()
auto frame = QSharedPointer<FrameBuffer>::create(); auto frame = QSharedPointer<FrameBuffer>::create();
frame->data = infoPack(info); frame->data = infoPack(info);
frame->type = FBT_SER_MSG_ASKCLIENTS; 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) { if (!sendRet) {
qCritical() << QString(tr("send ask client list failed.")); qCritical() << QString(tr("send ask client list failed."));
return; return;

View File

@@ -47,7 +47,6 @@ private:
private: private:
Ui::Connecter* ui; Ui::Connecter* ui;
bool connceted_{false}; bool connceted_{false};
std::thread thContext_;
std::function<void(const QString& id)> remoteCall_; std::function<void(const QString& id)> remoteCall_;
ClientCore* clientCore_; ClientCore* clientCore_;

View File

@@ -4,10 +4,11 @@
#include <ClientCore.h> #include <ClientCore.h>
#include <FileTrans.h> #include <FileTrans.h>
#include <InfoDirFile.h> #include <InfoDirFile.h>
#include <QMenu>
#include <QMutex>
#include <QWidget> #include <QWidget>
#include <Util.h> #include <Util.h>
#include <QMutex> #include <memory>
#include <QMenu>
namespace Ui { namespace Ui {
class FileManager; class FileManager;

View File

@@ -3,6 +3,8 @@
#include <QDateTime> #include <QDateTime>
#include <QListWidgetItem> #include <QListWidgetItem>
#include <QStandardItem> #include <QStandardItem>
#include <chrono>
#include <ctime>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
@@ -17,9 +19,11 @@ LogPrint::LogPrint(QWidget* parent) : QWidget(parent), ui(new Ui::LogPrint)
void LogPrint::InitControl() void LogPrint::InitControl()
{ {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
isLightMode_ = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Light; isLightMode_ = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Light;
styleHints_ = QGuiApplication::styleHints(); styleHints_ = QGuiApplication::styleHints();
connect(styleHints_, &QStyleHints::colorSchemeChanged, this, &LogPrint::ColorChange); connect(styleHints_, &QStyleHints::colorSchemeChanged, this, &LogPrint::ColorChange);
#endif
ui->pedText->setReadOnly(true); 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 time_t_now = std::chrono::system_clock::to_time_t(now);
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(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; std::ostringstream timestamp;
timestamp << std::put_time(std::localtime(&time_t_now), "%H:%M:%S") << "." << std::setfill('0') << std::setw(3) timestamp << timeStr << "." << std::setfill('0') << std::setw(3) << milliseconds.count() << " ";
<< milliseconds.count() << " ";
return timestamp.str(); return timestamp.str();
} }
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
void LogPrint::ColorChange(Qt::ColorScheme scheme) void LogPrint::ColorChange(Qt::ColorScheme scheme)
{ {
if (scheme == Qt::ColorScheme::Dark) { if (scheme == Qt::ColorScheme::Dark) {
@@ -45,6 +55,7 @@ void LogPrint::ColorChange(Qt::ColorScheme scheme)
} }
RePrintLog(); RePrintLog();
} }
#endif
LogPrint::~LogPrint() LogPrint::~LogPrint()
{ {

View File

@@ -36,7 +36,10 @@ public:
public: public:
std::string now_str(); std::string now_str();
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
void ColorChange(Qt::ColorScheme scheme); void ColorChange(Qt::ColorScheme scheme);
#endif
private: private:
void InitControl(); void InitControl();
@@ -51,7 +54,11 @@ private:
QMap<PrintType, QBrush> lightMap_; QMap<PrintType, QBrush> lightMap_;
QMap<PrintType, QBrush> darkMap_; QMap<PrintType, QBrush> darkMap_;
QVector<LogEntry> logEntries_; QVector<LogEntry> logEntries_;
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
QStyleHints* styleHints_{}; QStyleHints* styleHints_{};
#endif
QStandardItemModel* model_; QStandardItemModel* model_;
}; };

View File

@@ -5,6 +5,7 @@
#include <QMimeData> #include <QMimeData>
#include <QPainter> #include <QPainter>
#include <Util.h> #include <Util.h>
#include <functional>
#include "GuiUtil/Public.h" #include "GuiUtil/Public.h"

View File

@@ -92,25 +92,20 @@ void frelayGUI::ControlLayout()
void frelayGUI::ControlMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg) void frelayGUI::ControlMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{ {
QMetaObject::invokeMethod( switch (type) {
qApp, case QtDebugMsg:
[type, msg]() { logPrint->Debug(msg);
switch (type) { break;
case QtDebugMsg: case QtInfoMsg:
logPrint->Debug(msg); logPrint->Info(msg);
break; break;
case QtInfoMsg: case QtWarningMsg:
logPrint->Info(msg); logPrint->Warn(msg);
break; break;
case QtWarningMsg: default:
logPrint->Warn(msg); logPrint->Error(msg);
break; break;
default: }
logPrint->Error(msg);
break;
}
},
Qt::QueuedConnection);
} }
void frelayGUI::HandleTask(const QVector<TransTask>& tasks) void frelayGUI::HandleTask(const QVector<TransTask>& tasks)

View File

@@ -20,9 +20,9 @@ int main(int argc, char* argv[])
#else #else
backward::SetDumpLogSavePath(configDir + QDir::separator() + "dumplog"); backward::SetDumpLogSavePath(configDir + QDir::separator() + "dumplog");
#endif #endif
CRASHELPER_MARK_ENTRY();
#endif #endif
CRASHELPER_MARK_ENTRY();
SingleApplication a(argc, argv); SingleApplication a(argc, argv);
#ifdef _WIN32 #ifdef _WIN32

View File

@@ -1,5 +1,6 @@
#include "Protocol.h" #include "Protocol.h"
#include <QDataStream>
#include <QIODevice> #include <QIODevice>
#include <cstdint> #include <cstdint>
@@ -14,12 +15,12 @@ QSharedPointer<FrameBuffer> Protocol::ParseBuffer(QByteArray& buffer)
int headerPos = buffer.indexOf(protocolHeader); int headerPos = buffer.indexOf(protocolHeader);
if (headerPos == -1) { if (headerPos == -1) {
return nullptr; return QSharedPointer<FrameBuffer>();
} }
const int minFrameSize = protocolHeader.size() + sizeof(uint16_t) + 32 + 32 + sizeof(uint32_t) + protocolTail.size(); const int minFrameSize = protocolHeader.size() + sizeof(uint16_t) + 32 + 32 + sizeof(uint32_t) + protocolTail.size();
if (buffer.size() - headerPos < minFrameSize) { if (buffer.size() - headerPos < minFrameSize) {
return nullptr; return QSharedPointer<FrameBuffer>();
} }
QDataStream stream(buffer.mid(headerPos)); QDataStream stream(buffer.mid(headerPos));
@@ -29,7 +30,7 @@ QSharedPointer<FrameBuffer> Protocol::ParseBuffer(QByteArray& buffer)
header.resize(protocolHeader.size()); header.resize(protocolHeader.size());
stream.readRawData(header.data(), protocolHeader.size()); stream.readRawData(header.data(), protocolHeader.size());
if (header != protocolHeader) { if (header != protocolHeader) {
return nullptr; return QSharedPointer<FrameBuffer>();
} }
FrameBufferType type; FrameBufferType type;
@@ -51,7 +52,7 @@ QSharedPointer<FrameBuffer> Protocol::ParseBuffer(QByteArray& buffer)
int totalFrameSize = minFrameSize - protocolTail.size() + dataLen; int totalFrameSize = minFrameSize - protocolTail.size() + dataLen;
if (buffer.size() - headerPos < totalFrameSize) { if (buffer.size() - headerPos < totalFrameSize) {
return nullptr; return QSharedPointer<FrameBuffer>();
} }
QByteArray data; QByteArray data;
if (dataLen > 0) { if (dataLen > 0) {
@@ -62,7 +63,7 @@ QSharedPointer<FrameBuffer> Protocol::ParseBuffer(QByteArray& buffer)
tail.resize(protocolTail.size()); tail.resize(protocolTail.size());
stream.readRawData(tail.data(), protocolTail.size()); stream.readRawData(tail.data(), protocolTail.size());
if (tail != protocolTail) { if (tail != protocolTail) {
return nullptr; return QSharedPointer<FrameBuffer>();
} }
auto frame = QSharedPointer<FrameBuffer>::create(); auto frame = QSharedPointer<FrameBuffer>::create();
frame->type = type; frame->type = type;

View File

@@ -2,9 +2,10 @@
#define PROTOCOL_H #define PROTOCOL_H
#include <QByteArray> #include <QByteArray>
#include <QMetaType>
#include <QSharedPointer> #include <QSharedPointer>
#include <QString> #include <QString>
#include <QMetaType> #include <functional>
constexpr quint32 CHUNK_BUF_SIZE = 1 * 1024 * 1024; constexpr quint32 CHUNK_BUF_SIZE = 1 * 1024 * 1024;
@@ -54,5 +55,4 @@ public:
static QByteArray PackBuffer(const QSharedPointer<FrameBuffer>& frame); static QByteArray PackBuffer(const QSharedPointer<FrameBuffer>& frame);
}; };
#endif // PROTOCOL_H #endif // PROTOCOL_H

View File

@@ -63,7 +63,8 @@ void Server::onNewConnection()
client->socket = clientSocket; client->socket = clientSocket;
client->socket->setProperty("clientId", clientId); client->socket->setProperty("clientId", clientId);
client->id = 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::readyRead, this, &Server::onReadyRead);
connect(clientSocket, &QTcpSocket::disconnected, this, &Server::onClientDisconnected); connect(clientSocket, &QTcpSocket::disconnected, this, &Server::onClientDisconnected);
@@ -198,7 +199,8 @@ bool Server::sendData(QTcpSocket* socket, QSharedPointer<FrameBuffer> frame)
void Server::monitorClients() void Server::monitorClients()
{ {
qint64 now = QDateTime::currentSecsSinceEpoch(); // qint64 now = QDateTime::currentSecsSinceEpoch();
qint64 now = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000;
QWriteLocker locker(&rwLock_); QWriteLocker locker(&rwLock_);
for (auto it = clients_.begin(); it != clients_.end();) { for (auto it = clients_.begin(); it != clients_.end();) {

View File

@@ -30,14 +30,15 @@ struct InfoClientVec {
void serialize(QDataStream& data) const void serialize(QDataStream& data) const
{ {
data << vec.size(); uint32_t size = static_cast<uint32_t>(vec.size());
data << size;
for (const auto& info : vec) { for (const auto& info : vec) {
data << info; data << info;
} }
} }
void deserialize(QDataStream& data) void deserialize(QDataStream& data)
{ {
qsizetype size; uint32_t size = 0;
data >> size; data >> size;
vec.resize(size); vec.resize(size);
for (quint32 i = 0; i < size; ++i) { for (quint32 i = 0; i < size; ++i) {

View File

@@ -19,12 +19,15 @@ struct DirFileInfo {
void serialize(QDataStream& data) const void serialize(QDataStream& data) const
{ {
data << name << size << type << fullPath << permission << lastModified; uint32_t t = static_cast<FileType>(type);
data << name << size << t << fullPath << permission << lastModified;
} }
void deserialize(QDataStream& data) 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<FileType>(t);
} }
}; };
@@ -37,7 +40,8 @@ struct DirFileInfoVec {
void serialize(QDataStream& data) const void serialize(QDataStream& data) const
{ {
data << vec.size(); uint32_t size = static_cast<uint32_t>(vec.size());
data << size;
for (const auto& info : vec) { for (const auto& info : vec) {
data << info; data << info;
} }
@@ -45,7 +49,7 @@ struct DirFileInfoVec {
} }
void deserialize(QDataStream& data) void deserialize(QDataStream& data)
{ {
qsizetype size; uint32_t size = 0;
data >> size; data >> size;
vec.resize(size); vec.resize(size);
for (quint32 i = 0; i < size; ++i) { for (quint32 i = 0; i < size; ++i) {

18
Test/BaseTest.cpp Normal file
View File

@@ -0,0 +1,18 @@
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
void DateTimeTest()
{
qDebug() << QDateTime::currentDateTime().toMSecsSinceEpoch();
}
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
qDebug() << "Running...";
DateTimeTest();
return app.exec();
}

View File

@@ -1,13 +1,24 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(frelayTest LANGUAGES CXX) 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 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) 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 set(MSOURCES
msgTest.h msgTest.cpp msgTest.h msgTest.cpp
protocolTest.cpp infoTest.h infoTest.cpp protocolTest.cpp infoTest.h infoTest.cpp
) )
add_executable(frelayTest ${MSOURCES}) add_executable(frelayTest ${MSOURCES})
target_link_libraries(frelayTest PRIVATE Protocol Util) target_link_libraries(frelayTest PRIVATE Protocol Util)
add_executable(frelayBaseTest BaseTest.cpp)
target_link_libraries(frelayBaseTest Qt${QT_VERSION_MAJOR}::Core)

View File

@@ -3,6 +3,7 @@
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QFileInfo>
#include <QMutex> #include <QMutex>
#include <QStandardPaths> #include <QStandardPaths>
#include <iostream> #include <iostream>
@@ -77,9 +78,6 @@ void Util::InitLogger(const QString& logPath, const QString& mark)
spdlog::register_logger(logger); spdlog::register_logger(logger);
} }
#include <QDir>
#include <QFileInfo>
// do not check exit // do not check exit
QString Util::Get2FilePath(const QString& file, const QString& directory) QString Util::Get2FilePath(const QString& file, const QString& directory)
{ {

View File

@@ -335,21 +335,19 @@
#if defined(BACKWARD_SYSTEM_WINDOWS) #if defined(BACKWARD_SYSTEM_WINDOWS)
#include <basetsd.h>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <basetsd.h>
typedef SSIZE_T ssize_t; typedef SSIZE_T ssize_t;
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
#endif #endif
#include <windows.h>
#include <winnt.h>
#include <psapi.h> #include <psapi.h>
#include <signal.h> #include <signal.h>
#include <windows.h>
#include <winnt.h>
#ifndef __clang__ #ifndef __clang__
#undef NOINLINE #undef NOINLINE
@@ -1293,8 +1291,7 @@ public:
for (;;) { for (;;) {
// NOTE: this only works if PDBs are already loaded! // NOTE: this only works if PDBs are already loaded!
SetLastError(0); SetLastError(0);
if (!StackWalk64(machine_type_, process, thd_, &s, ctx_, NULL, SymFunctionTableAccess64, SymGetModuleBase64, if (!StackWalk64(machine_type_, process, thd_, &s, ctx_, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
NULL))
break; break;
if (s.AddrReturn.Offset == 0) if (s.AddrReturn.Offset == 0)
@@ -1797,13 +1794,11 @@ private:
static void find_in_section_trampoline(bfd*, asection* section, void* data) static void find_in_section_trampoline(bfd*, asection* section, void* data)
{ {
find_sym_context* context = static_cast<find_sym_context*>(data); find_sym_context* context = static_cast<find_sym_context*>(data);
context->self->find_in_section(reinterpret_cast<bfd_vma>(context->addr), context->self->find_in_section(reinterpret_cast<bfd_vma>(context->addr), reinterpret_cast<bfd_vma>(context->base_addr),
reinterpret_cast<bfd_vma>(context->base_addr), context->fobj, section, context->fobj, section, context->result);
context->result);
} }
void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject* fobj, asection* section, void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject* fobj, asection* section, find_sym_result& result)
find_sym_result& result)
{ {
if (result.found) if (result.found)
return; return;
@@ -1844,8 +1839,8 @@ private:
} }
if (!result.found && fobj->dynamic_symtab) { if (!result.found && fobj->dynamic_symtab) {
result.found = bfd_find_nearest_line(fobj->handle.get(), section, fobj->dynamic_symtab.get(), result.found = bfd_find_nearest_line(fobj->handle.get(), section, fobj->dynamic_symtab.get(), addr - sec_addr,
addr - sec_addr, &result.filename, &result.funcname, &result.line); &result.filename, &result.funcname, &result.line);
} }
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
@@ -2490,62 +2485,61 @@ private:
// We go the preprocessor way to avoid having to create templated // We go the preprocessor way to avoid having to create templated
// classes or using gelf (which might throw a compiler error if 64 bit // classes or using gelf (which might throw a compiler error if 64 bit
// is not supported // is not supported
#define ELF_GET_DATA(ARCH) \ #define ELF_GET_DATA(ARCH) \
Elf_Scn* elf_section = 0; \ Elf_Scn* elf_section = 0; \
Elf_Data* elf_data = 0; \ Elf_Data* elf_data = 0; \
Elf##ARCH##_Shdr* section_header = 0; \ Elf##ARCH##_Shdr* section_header = 0; \
Elf_Scn* symbol_section = 0; \ Elf_Scn* symbol_section = 0; \
size_t symbol_count = 0; \ size_t symbol_count = 0; \
size_t symbol_strings = 0; \ size_t symbol_strings = 0; \
Elf##ARCH##_Sym* symbol = 0; \ Elf##ARCH##_Sym* symbol = 0; \
const char* section_name = 0; \ const char* section_name = 0; \
\ \
while ((elf_section = elf_nextscn(elf_handle.get(), elf_section)) != NULL) { \ while ((elf_section = elf_nextscn(elf_handle.get(), elf_section)) != NULL) { \
section_header = elf##ARCH##_getshdr(elf_section); \ section_header = elf##ARCH##_getshdr(elf_section); \
if (section_header == NULL) { \ if (section_header == NULL) { \
return r; \ return r; \
} \ } \
\ \
if ((section_name = elf_strptr(elf_handle.get(), shdrstrndx, section_header->sh_name)) == NULL) { \ if ((section_name = elf_strptr(elf_handle.get(), shdrstrndx, section_header->sh_name)) == NULL) { \
return r; \ return r; \
} \ } \
\ \
if (cstrings_eq(section_name, ".gnu_debuglink")) { \ if (cstrings_eq(section_name, ".gnu_debuglink")) { \
elf_data = elf_getdata(elf_section, NULL); \ elf_data = elf_getdata(elf_section, NULL); \
if (elf_data && elf_data->d_size > 0) { \ if (elf_data && elf_data->d_size > 0) { \
debuglink = std::string(reinterpret_cast<const char*>(elf_data->d_buf)); \ debuglink = std::string(reinterpret_cast<const char*>(elf_data->d_buf)); \
} \ } \
} \ } \
\ \
switch (section_header->sh_type) { \ switch (section_header->sh_type) { \
case SHT_SYMTAB: \ case SHT_SYMTAB: \
symbol_section = elf_section; \ symbol_section = elf_section; \
symbol_count = section_header->sh_size / section_header->sh_entsize; \ symbol_count = section_header->sh_size / section_header->sh_entsize; \
symbol_strings = section_header->sh_link; \ symbol_strings = section_header->sh_link; \
break; \ break; \
\ \
/* We use .dynsyms as a last resort, we prefer .symtab */ \ /* We use .dynsyms as a last resort, we prefer .symtab */ \
case SHT_DYNSYM: \ case SHT_DYNSYM: \
if (!symbol_section) { \ if (!symbol_section) { \
symbol_section = elf_section; \ symbol_section = elf_section; \
symbol_count = section_header->sh_size / section_header->sh_entsize; \ symbol_count = section_header->sh_size / section_header->sh_entsize; \
symbol_strings = section_header->sh_link; \ symbol_strings = section_header->sh_link; \
} \ } \
break; \ break; \
} \ } \
} \ } \
\ \
if (symbol_section && symbol_count && symbol_strings) { \ if (symbol_section && symbol_count && symbol_strings) { \
elf_data = elf_getdata(symbol_section, NULL); \ elf_data = elf_getdata(symbol_section, NULL); \
symbol = reinterpret_cast<Elf##ARCH##_Sym*>(elf_data->d_buf); \ symbol = reinterpret_cast<Elf##ARCH##_Sym*>(elf_data->d_buf); \
for (size_t i = 0; i < symbol_count; ++i) { \ for (size_t i = 0; i < symbol_count; ++i) { \
int type = ELF##ARCH##_ST_TYPE(symbol->st_info); \ int type = ELF##ARCH##_ST_TYPE(symbol->st_info); \
if (type == STT_FUNC && symbol->st_value > 0) { \ if (type == STT_FUNC && symbol->st_value > 0) { \
r.symbol_cache[symbol->st_value] = \ r.symbol_cache[symbol->st_value] = std::string(elf_strptr(elf_handle.get(), symbol_strings, symbol->st_name)); \
std::string(elf_strptr(elf_handle.get(), symbol_strings, symbol->st_name)); \ } \
} \ ++symbol; \
++symbol; \ } \
} \
} }
if (e_ident[EI_CLASS] == ELFCLASS32) { 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) { 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 // Get the source lines for this line context, to be deallocated
// later // later
if (dwarf_srclines_from_linecontext(de.line_context, &de.line_buffer, &de.line_count, &error) == if (dwarf_srclines_from_linecontext(de.line_context, &de.line_buffer, &de.line_count, &error) == DW_DLV_OK) {
DW_DLV_OK) {
// Add all the addresses to our map // Add all the addresses to our map
for (int i = 0; i < de.line_count; i++) { 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) { if (dwarf_get_ranges_a(dwarf, offset, die, &ranges, &ranges_count, &byte_count, &error) == DW_DLV_OK) {
has_ranges = ranges_count != 0; has_ranges = ranges_count != 0;
for (int i = 0; i < ranges_count; i++) { for (int i = 0; i < ranges_count; i++) {
if (ranges[i].dwr_addr1 != 0 && pc >= ranges[i].dwr_addr1 + low_pc && if (ranges[i].dwr_addr1 != 0 && pc >= ranges[i].dwr_addr1 + low_pc && pc < ranges[i].dwr_addr2 + low_pc) {
pc < ranges[i].dwr_addr2 + low_pc) {
result = true; result = true;
break; break;
} }
@@ -2908,8 +2900,7 @@ private:
std::string result; std::string result;
bool found = false; 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) == 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) {
DW_DLV_OK) {
if (strncmp(signature.signature, tu_signature.signature, 8) == 0) { if (strncmp(signature.signature, tu_signature.signature, 8) == 0) {
Dwarf_Die type_cu_die = 0; Dwarf_Die type_cu_die = 0;
@@ -3072,8 +3063,8 @@ private:
} }
// Resolve the function return type and parameters // Resolve the function return type and parameters
static void set_function_parameters(std::string& function_name, std::vector<std::string>& ns, static void set_function_parameters(std::string& function_name, std::vector<std::string>& ns, dwarf_fileobject& fobj,
dwarf_fileobject& fobj, Dwarf_Die die) Dwarf_Die die)
{ {
Dwarf_Debug dwarf = fobj.dwarf_handle.get(); Dwarf_Debug dwarf = fobj.dwarf_handle.get();
Dwarf_Error error = DW_DLE_NE; Dwarf_Error error = DW_DLE_NE;
@@ -3335,8 +3326,8 @@ private:
} }
template <typename CB> template <typename CB>
static bool deep_first_search_by_pc(dwarf_fileobject& fobj, Dwarf_Die parent_die, Dwarf_Addr pc, static bool deep_first_search_by_pc(dwarf_fileobject& fobj, Dwarf_Die parent_die, Dwarf_Addr pc, std::vector<std::string>& ns,
std::vector<std::string>& ns, CB cb) CB cb)
{ {
Dwarf_Die current_die = 0; Dwarf_Die current_die = 0;
Dwarf_Debug dwarf = fobj.dwarf_handle.get(); Dwarf_Debug dwarf = fobj.dwarf_handle.get();
@@ -3371,8 +3362,7 @@ private:
bool declaration = false; bool declaration = false;
Dwarf_Attribute attr_mem; Dwarf_Attribute attr_mem;
if (tag != DW_TAG_class_type && if (tag != DW_TAG_class_type && dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) == DW_DLV_OK) {
dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) == DW_DLV_OK) {
Dwarf_Bool flag = 0; Dwarf_Bool flag = 0;
if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) { if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) {
declaration = flag != 0; declaration = flag != 0;
@@ -3501,8 +3491,7 @@ private:
Dwarf_Half tag = 0; Dwarf_Half tag = 0;
returnDie = 0; returnDie = 0;
while (!found && 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) {
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) if (returnDie)
dwarf_dealloc(dwarf, returnDie, DW_DLA_DIE); dwarf_dealloc(dwarf, returnDie, DW_DLA_DIE);
@@ -3643,8 +3632,7 @@ private:
details::handle<char**> _symbols; details::handle<char**> _symbols;
}; };
template <> template <> class TraceResolverImpl<system_tag::darwin_tag> : public TraceResolverDarwinImpl<trace_resolver_tag::current>
class TraceResolverImpl<system_tag::darwin_tag> : public TraceResolverDarwinImpl<trace_resolver_tag::current>
{ {
}; };
@@ -3712,8 +3700,7 @@ public:
EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
module_handles.resize(cbNeeded / sizeof(HMODULE)); module_handles.resize(cbNeeded / sizeof(HMODULE));
EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded); EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), get_mod_info(process));
get_mod_info(process));
void* base = modules[0].base_address; void* base = modules[0].base_address;
IMAGE_NT_HEADERS* h = ImageNtHeader(base); IMAGE_NT_HEADERS* h = ImageNtHeader(base);
image_type = h->FileHeader.Machine; image_type = h->FileHeader.Machine;
@@ -3742,9 +3729,8 @@ public:
char* lpMsgBuf; char* lpMsgBuf;
DWORD dw = GetLastError(); DWORD dw = GetLastError();
if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
FORMAT_MESSAGE_IGNORE_INSERTS, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&lpMsgBuf, 0, NULL)) {
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&lpMsgBuf, 0, NULL)) {
std::fprintf(stderr, "%s\n", lpMsgBuf); std::fprintf(stderr, "%s\n", lpMsgBuf);
LocalFree(lpMsgBuf); LocalFree(lpMsgBuf);
} }
@@ -3959,8 +3945,8 @@ public:
return src_file.get_lines(start, context_size); 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, lines_t get_combined_snippet(const std::string& filename_a, unsigned line_a, const std::string& filename_b, unsigned line_b,
unsigned line_b, unsigned context_size) unsigned context_size)
{ {
SourceFile& src_file_a = get_src_file(filename_a); SourceFile& src_file_a = get_src_file(filename_a);
SourceFile& src_file_b = get_src_file(filename_b); SourceFile& src_file_b = get_src_file(filename_b);
@@ -4007,11 +3993,7 @@ private:
/*************** PRINTER ***************/ /*************** PRINTER ***************/
namespace ColorMode { namespace ColorMode {
enum type { enum type { automatic, never, always };
automatic,
never,
always
};
} // namespace ColorMode } // namespace ColorMode
class cfile_streambuf : public std::streambuf class cfile_streambuf : public std::streambuf
@@ -4055,11 +4037,7 @@ private:
#ifdef BACKWARD_SYSTEM_LINUX #ifdef BACKWARD_SYSTEM_LINUX
namespace Color { namespace Color {
enum type { enum type { yellow = 33, purple = 35, reset = 39 };
yellow = 33,
purple = 35,
reset = 39
};
} // namespace Color } // namespace Color
class Colorize class Colorize
@@ -4111,11 +4089,7 @@ private:
#else // ndef BACKWARD_SYSTEM_LINUX #else // ndef BACKWARD_SYSTEM_LINUX
namespace Color { namespace Color {
enum type { enum type { yellow = 0, purple = 0, reset = 0 };
yellow = 0,
purple = 0,
reset = 0
};
} // namespace Color } // namespace Color
class Colorize class Colorize
@@ -4148,11 +4122,7 @@ public:
int trace_context_size; int trace_context_size;
Printer() Printer()
: snippet(true), : snippet(true), color_mode(ColorMode::automatic), address(false), object(false), inliner_context_size(5),
color_mode(ColorMode::automatic),
address(false),
object(false),
inliner_context_size(5),
trace_context_size(7) trace_context_size(7)
{ {
} }
@@ -4211,8 +4181,7 @@ private:
} }
} }
template <typename IT> template <typename IT> void print_stacktrace(IT begin, IT end, std::ostream& os, size_t thread_id, Colorize& colorize)
void print_stacktrace(IT begin, IT end, std::ostream& os, size_t thread_id, Colorize& colorize)
{ {
print_header(os, thread_id); print_header(os, thread_id);
for (; begin != end; ++begin) { for (; begin != end; ++begin) {
@@ -4235,8 +4204,7 @@ private:
bool already_indented = true; bool already_indented = true;
if (!trace.source.filename.size() || object) { if (!trace.source.filename.size() || object) {
os << " Object \"" << trace.object_filename << "\", at " << trace.addr << ", in " << trace.object_function os << " Object \"" << trace.object_filename << "\", at " << trace.addr << ", in " << trace.object_function << "\n";
<< "\n";
already_indented = false; already_indented = false;
} }
@@ -4263,14 +4231,13 @@ private:
} }
} }
void print_snippet(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, void print_snippet(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, Colorize& colorize,
Colorize& colorize, Color::type color_code, int context_size) Color::type color_code, int context_size)
{ {
using namespace std; using namespace std;
typedef SnippetFactory::lines_t lines_t; typedef SnippetFactory::lines_t lines_t;
lines_t lines = lines_t lines = _snippets.get_snippet(source_loc.filename, source_loc.line, static_cast<unsigned>(context_size));
_snippets.get_snippet(source_loc.filename, source_loc.line, static_cast<unsigned>(context_size));
for (lines_t::const_iterator it = lines.begin(); it != lines.end(); ++it) { for (lines_t::const_iterator it = lines.begin(); it != lines.end(); ++it) {
if (it->first == source_loc.line) { 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 print_source_loc(std::ostream& os, const char* indent, const ResolvedTrace::SourceLoc& source_loc, void* addr = nullptr)
void* addr = nullptr)
{ {
os << indent << "Source \"" << source_loc.filename << "\", line " << source_loc.line << ", in " os << indent << "Source \"" << source_loc.filename << "\", line " << source_loc.line << ", in " << source_loc.function;
<< source_loc.function;
if (address && addr != nullptr) { if (address && addr != nullptr) {
os << " [" << addr << "]"; os << " [" << addr << "]";
@@ -4484,9 +4449,9 @@ private:
class SignalHandling class SignalHandling
{ {
private: private:
static inline std::function<std::string()> crash_path_getter_ = nullptr; static std::function<std::string()> crash_path_getter_;
static inline std::function<void(EXCEPTION_POINTERS* info)> crash_use_handler_ = nullptr; static std::function<void(EXCEPTION_POINTERS* info)> crash_use_handler_;
static inline std::function<void(int sig)> user_sig_handler_ = nullptr; static std::function<void(int sig)> user_sig_handler_;
public: public:
static void register_crash_path(std::function<std::string()>&& crash_path_getter) static void register_crash_path(std::function<std::string()>&& crash_path_getter)
@@ -4562,12 +4527,7 @@ private:
return &data; return &data;
} }
enum class crash_status { enum class crash_status { running, crashed, normal_exit, ending };
running,
crashed,
normal_exit,
ending
};
static crash_status& crashed() 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, static inline void __cdecl invalid_parameter_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t)
uintptr_t)
{ {
crash_handler(signal_skip_recs); crash_handler(signal_skip_recs);
abort(); abort();

View File

@@ -8,6 +8,12 @@
#include <QFileInfo> #include <QFileInfo>
#include <QStandardPaths> #include <QStandardPaths>
#include "backward.hpp"
std::function<std::string()> backward::SignalHandling::crash_path_getter_ = nullptr;
std::function<void(EXCEPTION_POINTERS* info)> backward::SignalHandling::crash_use_handler_ = nullptr;
std::function<void(int sig)> backward::SignalHandling::user_sig_handler_ = nullptr;
namespace backward { namespace backward {
class crashHelper class crashHelper
@@ -126,8 +132,7 @@ void UseExceptionHandler(EXCEPTION_POINTERS* exception)
QString fullPath = QDir(h.dumpSavePath_).absoluteFilePath(dumpName); QString fullPath = QDir(h.dumpSavePath_).absoluteFilePath(dumpName);
QString fullFailedPath = QDir(h.dumpSavePath_).absoluteFilePath(dumpFailedLog); QString fullFailedPath = QDir(h.dumpSavePath_).absoluteFilePath(dumpFailedLog);
HANDLE hFile = HANDLE hFile = CreateFile(fullPath.toStdString().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CreateFile(fullPath.toStdWString().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { if (hFile == INVALID_HANDLE_VALUE) {
QFile file(fullFailedPath); QFile file(fullFailedPath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {