diff options
| author | Tannin <devnull@localhost> | 2014-12-20 14:45:08 +0100 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2014-12-20 14:45:08 +0100 |
| commit | 7bfb48d6abb248d9739281ae46f8e9f52fcd16e3 (patch) | |
| tree | d9e954d5a0bbad8559e2ddefd6ec018d4e59c1f2 | |
| parent | 88817c7f3b259550741c5e203fb28f7f705ce30c (diff) | |
cleanup
| -rw-r--r-- | src/modlist.cpp | 12 | ||||
| -rw-r--r-- | src/modlist.h | 2 | ||||
| -rw-r--r-- | src/modlistsortproxy.cpp | 4 | ||||
| -rw-r--r-- | src/shared/leaktrace.cpp | 78 | ||||
| -rw-r--r-- | src/shared/shared.pro | 10 | ||||
| -rw-r--r-- | src/shared/stackdata.cpp | 163 | ||||
| -rw-r--r-- | src/shared/stackdata.h | 50 |
7 files changed, 225 insertions, 94 deletions
diff --git a/src/modlist.cpp b/src/modlist.cpp index d294bdd1..43862008 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -464,17 +464,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) } -ModList::EColumn ModList::getEnabledColumn(int index) const -{ - for (int i = 0; i <= COL_LASTCOLUMN; ++i) { - if (index == 0) { - return static_cast<EColumn>(i); - } else { - --index; - } - } - return ModList::COL_NAME; -} + QVariant ModList::headerData(int section, Qt::Orientation orientation, diff --git a/src/modlist.h b/src/modlist.h index 6cf5af31..3c33fd05 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -245,8 +245,6 @@ private: QString contentsToToolTip(const std::vector<ModInfo::EContent> &contents) const;
- ModList::EColumn getEnabledColumn(int index) const;
-
QVariant categoryData(int categoryID, int column, int role) const;
QVariant modData(int modID, int modelColumn, int role) const;
diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 0f6ce33a..4e066eb8 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <QWidgetAction>
#include <QApplication>
#include <QDebug>
+#include <QTreeView>
ModListSortProxy::ModListSortProxy(Profile* profile, QObject *parent)
@@ -324,7 +325,8 @@ bool ModListSortProxy::dropMimeData(const QMimeData *data, Qt::DropAction action int row, int column, const QModelIndex &parent)
{
if (sortColumn() != ModList::COL_PRIORITY) {
- MessageDialog::showMessage(tr("Drag&Drop is only supported when sorting by priority"), qApp->activeWindow());
+ QWidget *wid = qApp->activeWindow()->findChild<QTreeView*>("modList");
+ MessageDialog::showMessage(tr("Drag&Drop is only supported when sorting by priority"), wid);
return false;
}
if ((row == -1) && (column == -1)) {
diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp index 729eb42e..0d99b82e 100644 --- a/src/shared/leaktrace.cpp +++ b/src/shared/leaktrace.cpp @@ -1,4 +1,5 @@ #include "leaktrace.h"
+#include "stackdata.h"
#include <Windows.h>
#include <DbgHelp.h>
#include <set>
@@ -8,82 +9,7 @@ #include <algorithm>
-static const int FRAMES_TO_SKIP = 3; // StackData::StackData(), __TraceData::regTrace(), TraceAlloc()
-static const int FRAMES_TO_CAPTURE = 10;
-
-
-void initDbgIfNecessary()
-{
- 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: %d", ::GetLastError());
- }
- initialized.insert(::GetCurrentProcessId());
- }
-}
-
-
-class StackData {
- friend bool operator==(const StackData &LHS, const StackData &RHS);
- friend bool operator<(const StackData &LHS, const StackData &RHS);
-public:
-
- StackData()
- : m_Count(0), m_Hash(0UL), m_FunctionName("Dummy"), m_CodeLine(0)
- {}
- StackData(const char *functionName, int line) {
- m_Count = ::CaptureStackBackTrace(FRAMES_TO_SKIP, FRAMES_TO_CAPTURE, m_Stack, &m_Hash);
- m_FunctionName = functionName;
- m_CodeLine = line;
- if (m_Count == 0) {
- // TODO in this case the hash doesn't seem to be set. This is of course not a good solution
- m_Hash = reinterpret_cast<unsigned long>(m_FunctionName) + m_CodeLine;
- }
- }
- std::string toString() const {
- initDbgIfNecessary();
-
- 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;
-
- stackStream << m_FunctionName << " [" << m_CodeLine << "]\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();
- }
-private:
- LPVOID m_Stack[FRAMES_TO_CAPTURE];
- USHORT m_Count;
- ULONG m_Hash;
- const char *m_FunctionName;
- int m_CodeLine;
-};
-
-bool operator==(const StackData &LHS, const StackData &RHS) {
- return LHS.m_Hash == RHS.m_Hash;
-}
-
-bool operator<(const StackData &LHS, const StackData &RHS) {
- return LHS.m_Hash < RHS.m_Hash;
-}
+using namespace MOShared;
static struct __TraceData {
diff --git a/src/shared/shared.pro b/src/shared/shared.pro index 69f6f2e6..1e26b7c0 100644 --- a/src/shared/shared.pro +++ b/src/shared/shared.pro @@ -28,7 +28,8 @@ SOURCES += \ util.cpp \
skyriminfo.cpp \
appconfig.cpp \
- leaktrace.cpp
+ leaktrace.cpp \
+ stackdata.cpp
HEADERS += \
inject.h \
@@ -43,12 +44,13 @@ HEADERS += \ skyriminfo.h \
appconfig.h \
appconfig.inc \
- leaktrace.h
+ leaktrace.h \
+ stackdata.h
# only for custom leak detection
-DEFINES += TRACE_LEAKS
-LIBS += -lDbgHelp
+#DEFINES += TRACE_LEAKS
+#LIBS += -lDbgHelp
CONFIG(debug, debug|release) {
diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp new file mode 100644 index 00000000..7f6f6e52 --- /dev/null +++ b/src/shared/stackdata.cpp @@ -0,0 +1,163 @@ +#include "stackdata.h"
+
+#include <DbgHelp.h>
+#include <sstream>
+#include <TlHelp32.h>
+#include <util.h>
+#include <set>
+
+
+using namespace MOShared;
+
+
+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: %d", ::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);
+}
+
+#include "error_report.h"
+#include <boost/predef.h>
+
+void StackData::initTrace() {
+ load_modules(::GetCurrentProcess(), ::GetCurrentProcessId());
+ CONTEXT context;
+ std::memset(&context, 0, sizeof(CONTEXT));
+ context.ContextFlags = CONTEXT_CONTROL;
+#if BOOST_ARCH_X86_64
+ ::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);
+ }
+}
+
+
+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;
+}
diff --git a/src/shared/stackdata.h b/src/shared/stackdata.h new file mode 100644 index 00000000..7151699c --- /dev/null +++ b/src/shared/stackdata.h @@ -0,0 +1,50 @@ +#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
|
