summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEran Mizrahi <erasmux@gmail.com>2017-12-08 18:24:06 +0200
committerEran Mizrahi <erasmux@gmail.com>2017-12-10 02:53:09 +0200
commit4adb13c9435baade511d3ac78fb142dc73bd2e1f (patch)
treeef08ae55a1d263c8e5c2a02e49d24b209ab6d4b4
parent54fd26fee15c320c363a4be355c80e4b7ce38164 (diff)
generate dumps using new diagnostics settings
-rw-r--r--src/main.cpp79
-rw-r--r--src/mainwindow.cpp2
-rw-r--r--src/organizercore.cpp23
-rw-r--r--src/organizercore.h7
-rw-r--r--src/settings.cpp2
-rw-r--r--src/usvfsconnector.cpp36
-rw-r--r--src/usvfsconnector.h4
7 files changed, 73 insertions, 80 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 526563a2..71fbc943 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -48,6 +48,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <eh.h>
#include <windows_error.h>
+#include <usvfs.h>
#include <QApplication>
#include <QPushButton>
@@ -127,71 +128,17 @@ bool isNxmLink(const QString &link)
static LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs)
{
- typedef BOOL (WINAPI *FuncMiniDumpWriteDump)(HANDLE process, DWORD pid, HANDLE file, MINIDUMP_TYPE dumpType,
- const PMINIDUMP_EXCEPTION_INFORMATION exceptionParam,
- const PMINIDUMP_USER_STREAM_INFORMATION userStreamParam,
- const PMINIDUMP_CALLBACK_INFORMATION callbackParam);
- LONG result = EXCEPTION_CONTINUE_SEARCH;
-
- HMODULE dbgDLL = ::LoadLibrary(L"dbghelp.dll");
-
- static const int errorLen = 200;
- char errorBuffer[errorLen + 1];
- memset(errorBuffer, '\0', errorLen + 1);
-
- if (dbgDLL) {
- FuncMiniDumpWriteDump funcDump = (FuncMiniDumpWriteDump)::GetProcAddress(dbgDLL, "MiniDumpWriteDump");
- if (funcDump) {
- QString dataPath = qApp->property("dataPath").toString();
- QString exeName = QFileInfo(qApp->applicationFilePath()).fileName();
- QString dumpName = dataPath + "/" + exeName + ".dmp";
-
- if (QMessageBox::question(nullptr, QObject::tr("Woops"),
- QObject::tr("ModOrganizer has crashed! "
- "Should a diagnostic file be created? "
- "If you send me this file (%1) to modorganizer@gmail.com, "
- "the bug is a lot more likely to be fixed. "
- "Please include a short description of what you were "
- "doing when the crash happened"
- ).arg(dumpName),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
-
- HANDLE dumpFile = ::CreateFile(dumpName.toStdWString().c_str(),
- GENERIC_WRITE, FILE_SHARE_WRITE, nullptr,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (dumpFile != INVALID_HANDLE_VALUE) {
- _MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
- exceptionInfo.ThreadId = ::GetCurrentThreadId();
- exceptionInfo.ExceptionPointers = exceptionPtrs;
- exceptionInfo.ClientPointers = false;
-
- BOOL success = funcDump(::GetCurrentProcess(), ::GetCurrentProcessId(), dumpFile,
- MiniDumpNormal, &exceptionInfo, nullptr, nullptr);
-
- ::FlushFileBuffers(dumpFile);
- ::CloseHandle(dumpFile);
- if (success) {
- return EXCEPTION_EXECUTE_HANDLER;
- }
- _snprintf(errorBuffer, errorLen, "failed to save minidump to %ls (error %lu)",
- dumpName.toStdWString().c_str(), ::GetLastError());
- } else {
- _snprintf(errorBuffer, errorLen, "failed to create %ls (error %lu)",
- dumpName.toStdWString().c_str(), ::GetLastError());
- }
- } else {
- return result;
- }
- } else {
- _snprintf(errorBuffer, errorLen, "dbghelp.dll outdated");
- }
- } else {
- _snprintf(errorBuffer, errorLen, "dbghelp.dll not found");
+ const std::wstring& dumpPath = OrganizerCore::crashDumpsPath();
+ int dumpRes =
+ CreateMiniDump(exceptionPtrs, OrganizerCore::getGlobalCrashDumpsType(), dumpPath.c_str());
+ if (!dumpRes) {
+ qCritical("ModOrganizer has crashed, crash dump created.");
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ else {
+ qCritical("ModOrganizer has crashed, CreateMiniDump failed (%d, error %lu).", dumpRes, GetLastError());
+ return EXCEPTION_CONTINUE_SEARCH;
}
-
- QMessageBox::critical(nullptr, QObject::tr("Woops"),
- QObject::tr("ModOrganizer has crashed! Unfortunately I was not able to write a diagnostic file: %1").arg(errorBuffer));
- return result;
}
static bool HaveWriteAccess(const std::wstring &path)
@@ -448,6 +395,10 @@ int runApplication(MOApplication &application, SingleInstance &instance,
QSettings settings(dataPath + "/"
+ QString::fromStdWString(AppConfig::iniFileName()),
QSettings::IniFormat);
+
+ // global crashDumpType sits in OrganizerCore to make a bit less ugly to update it when the settings are changed during runtime
+ OrganizerCore::setGlobalCrashDumpsType(settings.value("Settings/crash_dumps_type", static_cast<int>(CrashDumpsType::Mini)).toInt());
+
qDebug("initializing core");
OrganizerCore organizer(settings);
if (!organizer.bootstrap()) {
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 48dfdfbd..cab4c41f 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -3296,7 +3296,7 @@ void MainWindow::on_actionSettings_triggered()
updateDownloadListDelegate();
- m_OrganizerCore.setLogLevel(settings.logLevel());
+ m_OrganizerCore.updateVFSParams(settings.logLevel(), settings.crashDumpsType());
}
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index f8a368c9..adb895ec 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -47,6 +47,7 @@
#include <QtGlobal> // for qPrintable, etc
#include <Psapi.h>
+#include <Shlobj.h>
#include <tchar.h> // for _tcsicmp
#include <limits.h>
@@ -66,6 +67,9 @@
using namespace MOShared;
using namespace MOBase;
+//static
+CrashDumpsType OrganizerCore::m_globalCrashDumpsType = CrashDumpsType::None;
+
static bool isOnline()
{
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
@@ -643,8 +647,23 @@ void OrganizerCore::prepareVFS()
m_USVFS.updateMapping(fileMapping(m_CurrentProfile->name(), QString()));
}
-void OrganizerCore::setLogLevel(int logLevel) {
- m_USVFS.setLogLevel(logLevel);
+void OrganizerCore::updateVFSParams(int logLevel, int crashDumpsType) {
+ setGlobalCrashDumpsType(crashDumpsType);
+ m_USVFS.updateParams(logLevel, crashDumpsType);
+}
+
+//static
+void OrganizerCore::setGlobalCrashDumpsType(int crashDumpsType) {
+ m_globalCrashDumpsType = ::crashDumpsType(crashDumpsType);
+}
+
+//static
+std::wstring OrganizerCore::crashDumpsPath() {
+ wchar_t appDataLocal[MAX_PATH]{ 0 };
+ ::SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, appDataLocal);
+ std::wstring dumpPath{ appDataLocal };
+ dumpPath += L"\\modorganizer";
+ return dumpPath;
}
void OrganizerCore::setCurrentProfile(const QString &profileName)
diff --git a/src/organizercore.h b/src/organizercore.h
index 297b94f6..7bb7faa7 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -158,7 +158,11 @@ public:
void prepareVFS();
- void setLogLevel(int logLevel);
+ void updateVFSParams(int logLevel, int crashDumpsType);
+
+ static CrashDumpsType getGlobalCrashDumpsType() { return m_globalCrashDumpsType; }
+ static void setGlobalCrashDumpsType(int crashDumpsType);
+ static std::wstring crashDumpsPath();
public:
MOBase::IModRepositoryBridge *createNexusBridge() const;
@@ -319,6 +323,7 @@ private:
MOBase::DelayedFileWriter m_PluginListsWriter;
UsvfsConnector m_USVFS;
+ static CrashDumpsType m_globalCrashDumpsType;
};
#endif // ORGANIZERCORE_H
diff --git a/src/settings.cpp b/src/settings.cpp
index 7d90d861..05a62591 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -28,7 +28,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <iplugin.h>
#include <iplugingame.h>
#include <questionboxmemory.h>
-#include <usvfs.h>
+#include <usvfsparameters.h>
#include <QCheckBox>
#include <QCoreApplication>
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index 0420ddc2..b90784d9 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -19,6 +19,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "usvfsconnector.h"
#include "settings.h"
+#include "organizercore.h"
+#include "shared/util.h"
#include <memory>
#include <sstream>
#include <iomanip>
@@ -27,6 +29,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QProgressDialog>
#include <QDateTime>
#include <QCoreApplication>
+#include <qstandardpaths.h>
static const char SHMID[] = "mod_organizer_instance";
@@ -101,14 +104,33 @@ LogLevel logLevel(int level)
}
}
+CrashDumpsType crashDumpsType(int type)
+{
+ switch (type) {
+ case CrashDumpsType::Mini:
+ return CrashDumpsType::Mini;
+ case CrashDumpsType::Data:
+ return CrashDumpsType::Data;
+ case CrashDumpsType::Full:
+ return CrashDumpsType::Full;
+ default:
+ return CrashDumpsType::None;
+ }
+}
+
UsvfsConnector::UsvfsConnector()
{
USVFSParameters params;
LogLevel level = logLevel(Settings::instance().logLevel());
- USVFSInitParameters(&params, SHMID, false, level);
+ CrashDumpsType dumpType = crashDumpsType(Settings::instance().crashDumpsType());
+
+ std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true);
+ USVFSInitParameters(&params, SHMID, false, level, dumpType, dumpPath.c_str());
InitLogging(false);
+
+ qDebug("Initializing VFS <%s, %d, %d, %s>", params.instanceName, params.logLevel, params.crashDumpsType, params.crashDumpsPath);
+
CreateVFS(&params);
- SetLogLevel(level);
BlacklistExecutable(L"TSVNCache.exe");
@@ -165,12 +187,6 @@ void UsvfsConnector::updateMapping(const MappingType &mapping)
*/
}
-void UsvfsConnector::setLogLevel(int logLevel) {
- switch (logLevel) {
- case LogLevel::Debug: SetLogLevel(LogLevel::Debug); break;
- case LogLevel::Info: SetLogLevel(LogLevel::Info); break;
- case LogLevel::Warning: SetLogLevel(LogLevel::Warning); break;
- case LogLevel::Error: SetLogLevel(LogLevel::Error); break;
- default: SetLogLevel(LogLevel::Debug); break;
- }
+void UsvfsConnector::updateParams(int logLevel, int crashDumpsType) {
+ USVFSUpdateParams(::logLevel(logLevel), ::crashDumpsType(crashDumpsType));
}
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index 8f723a01..0935bac1 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QThread>
#include <QFile>
#include <QDebug>
+#include <usvfsparameters.h>
class LogWorker : public QThread {
@@ -67,7 +68,7 @@ public:
~UsvfsConnector();
void updateMapping(const MappingType &mapping);
- void setLogLevel(int logLevel);
+ void updateParams(int logLevel, int crashDumpsType);
private:
@@ -76,5 +77,6 @@ private:
};
+CrashDumpsType crashDumpsType(int type);
#endif // USVFSCONNECTOR_H