diff options
| -rw-r--r-- | src/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/commandline.cpp | 7 | ||||
| -rw-r--r-- | src/instancemanager.cpp | 9 | ||||
| -rw-r--r-- | src/moapplication.cpp | 33 | ||||
| -rw-r--r-- | src/organizercore.cpp | 5 | ||||
| -rw-r--r-- | src/profile.cpp | 1 | ||||
| -rw-r--r-- | src/shared/error_report.cpp | 64 | ||||
| -rw-r--r-- | src/shared/error_report.h | 44 | ||||
| -rw-r--r-- | src/shared/leaktrace.cpp | 68 | ||||
| -rw-r--r-- | src/shared/leaktrace.h | 24 | ||||
| -rw-r--r-- | src/shared/stackdata.cpp | 169 | ||||
| -rw-r--r-- | src/shared/stackdata.h | 50 |
12 files changed, 37 insertions, 440 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5d15740..e8c52721 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,12 +212,9 @@ add_filter(NAME src/utilities GROUPS shared/appconfig bbcode csvbuilder - shared/error_report - shared/leaktrace persistentcookiejar serverinfo spawn - shared/stackdata shared/util usvfsconnector shared/windows_error diff --git a/src/commandline.cpp b/src/commandline.cpp index 97d54b92..477bfba1 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -5,7 +5,6 @@ #include "multiprocess.h" #include "loglist.h" #include "shared/util.h" -#include "shared/error_report.h" #include "shared/appconfig.h" #include <log.h> #include <report.h> @@ -807,7 +806,7 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core) if (itor == exes.end()) { // not found - MOShared::criticalOnTop( + reportError( QObject::tr("Executable '%1' not found in instance '%2'.") .arg(program) .arg(InstanceManager::singleton().currentInstance()->name())); @@ -833,7 +832,7 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core) const auto r = p.run(); if (r == ProcessRunner::Error) { - MOShared::criticalOnTop( + reportError( QObject::tr("Failed to run '%1'. The logs might have more information.").arg(program)); return 1; @@ -842,7 +841,7 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core) return 0; } catch (const std::exception &e) { - MOShared::criticalOnTop( + reportError( QObject::tr("Failed to run '%1'. The logs might have more information. %2") .arg(program).arg(e.what())); diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp index a9905b75..8add4af8 100644 --- a/src/instancemanager.cpp +++ b/src/instancemanager.cpp @@ -28,7 +28,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "createinstancedialogpages.h" #include "shared/appconfig.h" #include "shared/util.h" -#include "shared/error_report.h" #include <report.h> #include <iplugingame.h> #include <utility.h> @@ -896,7 +895,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // unreadable ini, there's not much that can be done, select another // instance - MOShared::criticalOnTop( + reportError( QObject::tr("Cannot open instance '%1', failed to read INI file %2.") .arg(instance.name()).arg(instance.iniPath())); @@ -911,7 +910,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // // ask the user for the game managed by this instance - MOShared::criticalOnTop( + reportError( QObject::tr( "Cannot open instance '%1', the managed game was not found in the INI " "file %2. Select the game managed by this instance.") @@ -925,7 +924,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // there is no plugin that can handle the game name/directory from the // ini, so this instance is unusable - MOShared::criticalOnTop( + reportError( QObject::tr( "Cannot open instance '%1', the game plugin '%2' doesn't exist. It " "may have been deleted by an antivirus. Select another instance.") @@ -939,7 +938,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // the game directory doesn't exist or the plugin doesn't recognize it; // ask the user for the game managed by this instance - MOShared::criticalOnTop( + reportError( QObject::tr( "Cannot open instance '%1', the game directory '%2' doesn't exist or " "the game plugin '%3' doesn't recognize it. Select the game managed " diff --git a/src/moapplication.cpp b/src/moapplication.cpp index da45e26c..91cac2b1 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -32,7 +32,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "sanitychecks.h"
#include "mainwindow.h"
#include "messagedialog.h"
-#include "shared/error_report.h"
#include "shared/util.h"
#include <iplugingame.h>
#include <report.h>
@@ -204,7 +203,7 @@ int MOApplication::setup(MOMultiProcess& multiProcess) setProperty("dataPath", dataPath);
if (!setLogDirectory(dataPath)) {
- reportError("Failed to create log folder");
+ reportError(tr("Failed to create log folder."));
InstanceManager::singleton().clearCurrentInstance();
return 1;
}
@@ -271,7 +270,7 @@ int MOApplication::setup(MOMultiProcess& multiProcess) m_core.reset(new OrganizerCore(*m_settings));
if (!m_core->bootstrap()) {
- reportError("failed to set up data paths");
+ reportError(tr("Failed to set up data paths."));
InstanceManager::singleton().clearCurrentInstance();
return 1;
}
@@ -412,6 +411,30 @@ void MOApplication::externalMessage(const QString& message) return;
}
+ if (auto i=cl.instance()) {
+ const auto ci = InstanceManager::singleton().currentInstance();
+
+ if (*i != ci->name()) {
+ reportError(tr(
+ "This shortcut or command line is for instance '%1', but the current "
+ "instance is '%2'.")
+ .arg(*i).arg(ci->name()));
+
+ return;
+ }
+ }
+
+ if (auto p=cl.profile()) {
+ if (*p != m_core->profileName()) {
+ reportError(tr(
+ "This shortcut or command line is for profile '%1', but the current "
+ "profile is '%2'.")
+ .arg(*p).arg(m_core->profileName()));
+
+ return;
+ }
+ }
+
cl.runPostOrganizer(*m_core);
}
}
@@ -436,11 +459,11 @@ std::unique_ptr<Instance> MOApplication::getCurrentInstance() m.clearOverrides();
if (m.hasAnyInstances()) {
- MOShared::criticalOnTop(QObject::tr(
+ reportError(QObject::tr(
"Instance at '%1' not found. Select another instance.")
.arg(currentInstance->directory()));
} else {
- MOShared::criticalOnTop(QObject::tr(
+ reportError(QObject::tr(
"Instance at '%1' not found. You must create a new instance")
.arg(currentInstance->directory()));
}
diff --git a/src/organizercore.cpp b/src/organizercore.cpp index c7c1f828..d3e817a5 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -37,7 +37,6 @@ #include "shared/filesorigin.h" #include "shared/fileentry.h" #include "shared/util.h" -#include "shared/error_report.h" #include <QApplication> #include <QCoreApplication> @@ -562,7 +561,7 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) log::error("picked profile '{}' instead", QDir(profileDir).dirName()); - MOShared::criticalOnTop( + reportError( tr("The selected profile '%1' does not exist. The profile '%2' will be used instead") .arg(profileName).arg(QDir(profileDir).dirName())); } @@ -812,7 +811,7 @@ ModInfo::Ptr OrganizerCore::installDownload(int index, int priority) } } } catch (const std::exception &e) { - reportError(e.what()); + reportError(QString(e.what())); } return nullptr; diff --git a/src/profile.cpp b/src/profile.cpp index 3cc1a2a3..695cd3ae 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -22,7 +22,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "modinfo.h" #include "settings.h" #include <utility.h> -#include "shared/error_report.h" #include "shared/appconfig.h" #include <iplugingame.h> #include <report.h> diff --git a/src/shared/error_report.cpp b/src/shared/error_report.cpp deleted file mode 100644 index 09fdcb49..00000000 --- a/src/shared/error_report.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "error_report.h"
-#include <sstream>
-#include <stdio.h>
-
-namespace MOShared {
-
-void reportError(LPCSTR format, ...)
-{
- char buffer[1025];
- memset(buffer, 0, sizeof(char) * 1025);
-
- va_list argList;
- va_start(argList, format);
-
- vsnprintf(buffer, 1024, format, argList);
- va_end(argList);
-
- MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR);
-}
-
-void reportError(LPCWSTR format, ...)
-{
- WCHAR buffer[1025];
- memset(buffer, 0, sizeof(WCHAR) * 1025);
-
- va_list argList;
- va_start(argList, format);
-
- _vsnwprintf_s(buffer, 1024, format, argList);
- va_end(argList);
-
- MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR);
-}
-
-void criticalOnTop(const QString& message)
-{
- QMessageBox mb(QMessageBox::Critical, QObject::tr("Mod Organizer"), message);
-
- mb.show();
- mb.activateWindow();
- mb.raise();
- mb.exec();
-}
-
-} // namespace MOShared
diff --git a/src/shared/error_report.h b/src/shared/error_report.h deleted file mode 100644 index 9343d3da..00000000 --- a/src/shared/error_report.h +++ /dev/null @@ -1,44 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef MODORGANIZER_SHARED_ERROR_REPORT_INCLUDED
-#define MODORGANIZER_SHARED_ERROR_REPORT_INCLUDED
-
-#include <tchar.h>
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <string>
-
-namespace MOShared
-{
-
-void reportError(LPCSTR format, ...);
-void reportError(LPCWSTR format, ...);
-
-// shows a critical message box that's raised to the top of the zorder, useful
-// for messages without a main window, which sometimes makes them pop up behind
-// all other windows
-//
-// the dialog is not topmost, it's just raised once when shown
-//
-void criticalOnTop(const QString& message);
-
-} // namespace MOShared
-
-#endif // MODORGANIZER_SHARED_ERROR_REPORT_INCLUDED
diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp deleted file mode 100644 index 466162a4..00000000 --- a/src/shared/leaktrace.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//disable warning messages 4302 , 4311 and 4312
-#pragma warning( disable : 4302 )
-#pragma warning( disable : 4311 )
-#pragma warning( disable : 4312 )
-
-#include "leaktrace.h"
-#include "stackdata.h"
-#include <Windows.h>
-#include <DbgHelp.h>
-#include <set>
-#include <map>
-#include <vector>
-#include <sstream>
-#include <algorithm>
-
-
-using namespace MOShared;
-
-
-static struct __TraceData {
- void regTrace(void *pointer, const char *functionName, int line) {
- m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
- }
- void deregTrace(void *pointer) {
- auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
- if (iter != m_Traces.end()) {
- m_Traces.erase(iter);
- }
- }
-
- ~__TraceData() {
- std::map<StackData, std::vector<unsigned long> > result;
- for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
- result[iter->second].push_back(iter->first);
- }
- for (auto iter = result.begin(); iter != result.end(); ++iter) {
- printf("-----------------------------------\n"
- "%d objects not freed, allocated at:\n%s",
- static_cast<int>(iter->second.size()), iter->first.toString().c_str());
- printf("Addresses: ");
- for (int i = 0;
- i < (std::min<int>)(5, static_cast<int>(iter->second.size())); ++i) {
- printf("%p, ", reinterpret_cast<void *>(iter->second[i]));
- }
- printf("\n");
- }
- }
-
- std::map<unsigned long, StackData> m_Traces;
-
-} __trace;
-
-
-void LeakTrace::TraceAlloc(void *ptr, const char *functionName, int line)
-{
- __trace.regTrace(ptr, functionName, line);
-}
-
-void LeakTrace::TraceDealloc(void *ptr)
-{
- __trace.deregTrace(ptr);
-}
-
-//re-enable warning messages 4302 , 4311 and 4312
-#pragma warning( default : 4302 )
-#pragma warning( default : 4311 )
-#pragma warning( default : 4312 )
-
diff --git a/src/shared/leaktrace.h b/src/shared/leaktrace.h deleted file mode 100644 index 4985925e..00000000 --- a/src/shared/leaktrace.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef LEAKTRACE_H
-#define LEAKTRACE_H
-
-
-namespace LeakTrace {
-
-void TraceAlloc(void *ptr, const char *functionName, int line);
-void TraceDealloc(void *ptr);
-
-};
-
-#ifdef TRACE_LEAKS
-
-#define LEAK_TRACE LeakTrace::TraceAlloc(this, __FUNCTION__, __LINE__)
-#define LEAK_UNTRACE LeakTrace::TraceDealloc(this)
-
-#else // TRACE_LEAKS
-
-#define LEAK_TRACE
-#define LEAK_UNTRACE
-
-#endif // TRACE_LEAKS
-
-#endif // LEAKTRACE_H
diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp deleted file mode 100644 index b336593a..00000000 --- a/src/shared/stackdata.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "stackdata.h"
-
-#include "util.h"
-#include <DbgHelp.h>
-#include <sstream>
-#include <TlHelp32.h>
-#include <set>
-#include "error_report.h"
-#include <boost/predef.h>
-
-
-using namespace MOShared;
-
-#if defined _MSC_VER
-
-static void initDbgIfNecess()
-{
- HANDLE process = ::GetCurrentProcess();
- static std::set<DWORD> initialized;
- if (initialized.find(::GetCurrentProcessId()) == initialized.end()) {
- static bool firstCall = true;
- if (firstCall) {
- ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
- firstCall = false;
- }
- if (!::SymInitialize(process, NULL, TRUE)) {
- printf("failed to initialize symbols: %lu", ::GetLastError());
- }
- initialized.insert(::GetCurrentProcessId());
- }
-}
-
-
-
-StackData::StackData()
- : m_Count(0)
- , m_Function()
- , m_Line(-1)
-{
- initTrace();
-}
-
-StackData::StackData(const char *function, int line)
- : m_Count(0)
- , m_Function(function)
- , m_Line(line)
-{
-
-}
-
-std::string StackData::toString() const {
- initDbgIfNecess();
-
- char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
- PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
- symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
- symbol->MaxNameLen = MAX_SYM_NAME;
-
- std::ostringstream stackStream;
-
- if (m_Function.length() > 0) {
- stackStream << "[" << m_Function << ":" << m_Line << "]\n";
- }
-
- for(unsigned int i = 0; i < m_Count; ++i) {
- DWORD64 displacement = 0;
- if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) {
- stackStream << m_Count - i - 1 << ": [" << m_Stack[i] << "]\n";
- } else {
- stackStream << m_Count - i - 1 << ": " << symbol->Name << "\n";
- }
- }
- return stackStream.str();
-}
-
-void StackData::load_modules(HANDLE process, DWORD processID) {
- HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
- if (snap == INVALID_HANDLE_VALUE)
- return;
-
- MODULEENTRY32 entry;
- entry.dwSize = sizeof(entry);
-
- if (Module32First(snap, &entry)) {
- do {
- std::string fileName = ToString(entry.szExePath, false);
- std::string moduleName = ToString(entry.szModule, false);
- SymLoadModule64(process, NULL, fileName.c_str(), moduleName.c_str(), (DWORD64) entry.modBaseAddr, entry.modBaseSize);
- } while (Module32Next(snap, &entry));
- }
- CloseHandle(snap);
-}
-
-#pragma warning( disable : 4748 )
-
-void StackData::initTrace() {
-#ifdef _X86_
- load_modules(::GetCurrentProcess(), ::GetCurrentProcessId());
- CONTEXT context;
- std::memset(&context, 0, sizeof(CONTEXT));
- context.ContextFlags = CONTEXT_CONTROL;
- //Why only for 64 bit?
-#if BOOST_ARCH_X86_64 || defined(__clang__)
- ::RtlCaptureContext(&context);
-#else
- __asm
- {
- Label:
- mov [context.Ebp], ebp;
- mov [context.Esp], esp;
- mov eax, [Label];
- mov [context.Eip], eax;
- }
-#endif
-
- STACKFRAME64 stackFrame;
- ::ZeroMemory(&stackFrame, sizeof(STACKFRAME64));
- stackFrame.AddrPC.Offset = context.Eip;
- stackFrame.AddrPC.Mode = AddrModeFlat;
- stackFrame.AddrFrame.Offset = context.Ebp;
- stackFrame.AddrFrame.Mode = AddrModeFlat;
- stackFrame.AddrStack.Offset = context.Esp;
- stackFrame.AddrStack.Mode = AddrModeFlat;
- m_Count = 0;
- while (m_Count < FRAMES_TO_CAPTURE) {
- if (!StackWalk64(IMAGE_FILE_MACHINE_I386, ::GetCurrentProcess(),
- ::GetCurrentThread(), &stackFrame, &context, NULL,
- &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) {
- break;
- }
-
- if (stackFrame.AddrPC.Offset == 0) {
- continue;
- break;
- }
-
- m_Stack[m_Count++] = reinterpret_cast<void *>(stackFrame.AddrPC.Offset);
- }
-#endif
-}
-
-
-bool MOShared::operator==(const StackData &LHS, const StackData &RHS) {
- if (LHS.m_Count != RHS.m_Count) {
- return false;
- } else {
- for (int i = 0; i < LHS.m_Count; ++i) {
- if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
- return false;
- }
- }
- }
- return true;
-}
-
-
-bool MOShared::operator<(const StackData &LHS, const StackData &RHS) {
- if (LHS.m_Count != RHS.m_Count) {
- return LHS.m_Count < RHS.m_Count;
- } else {
- for (int i = 0; i < LHS.m_Count; ++i) {
- if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
- return LHS.m_Stack[i] < RHS.m_Stack[i];
- }
- }
- }
- return false;
-}
-#endif
diff --git a/src/shared/stackdata.h b/src/shared/stackdata.h deleted file mode 100644 index 7151699c..00000000 --- a/src/shared/stackdata.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef STACKDATA_H
-#define STACKDATA_H
-
-
-#include <string>
-#include <Windows.h>
-
-
-namespace MOShared {
-
-
-class StackData {
- friend bool operator==(const StackData &LHS, const StackData &RHS);
- friend bool operator<(const StackData &LHS, const StackData &RHS);
-public:
-
- StackData();
- StackData(const char *function, int line);
-
- std::string toString() const;
-
-private:
-
- void load_modules(HANDLE process, DWORD processID);
-
- void initTrace();
-
-private:
-
- static const int FRAMES_TO_SKIP = 1;
- static const int FRAMES_TO_CAPTURE = 20;
-
-private:
-
- LPVOID m_Stack[FRAMES_TO_CAPTURE];
- USHORT m_Count;
- std::string m_Function;
- int m_Line;
-
-};
-
-
-bool operator==(const StackData &LHS, const StackData &RHS);
-
-bool operator<(const StackData &LHS, const StackData &RHS);
-
-} // namespace MOShared
-
-
-#endif // STACKDATA_H
|
