From c5177148223a820c9ee2c28ad988ed48cc71ddd5 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 23 Feb 2017 07:25:03 +0100 Subject: [PATCH] Debugger: Expose current symbol group to other python classes Change-Id: I8648d0269bdc2a4085ecf550171bb33d66f2fb30 Reviewed-by: Christian Stenger --- src/libs/qtcreatorcdbext/pycdbextmodule.cpp | 117 ++++++++++---------- src/libs/qtcreatorcdbext/pycdbextmodule.h | 21 ++++ 2 files changed, 77 insertions(+), 61 deletions(-) diff --git a/src/libs/qtcreatorcdbext/pycdbextmodule.cpp b/src/libs/qtcreatorcdbext/pycdbextmodule.cpp index 62e09cffb47..051aad58a3e 100644 --- a/src/libs/qtcreatorcdbext/pycdbextmodule.cpp +++ b/src/libs/qtcreatorcdbext/pycdbextmodule.cpp @@ -39,65 +39,60 @@ #include -class CurrentSymbolGroup -{ -public: - CurrentSymbolGroup() = default; - ~CurrentSymbolGroup() - { - releaseSymbolGroup(); - } - IDebugSymbolGroup2 *get() - { - ULONG threadId = ExtensionCommandContext::instance()->threadId(); - CIDebugControl *control = ExtensionCommandContext::instance()->control(); - DEBUG_STACK_FRAME frame; - if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL))) - return nullptr; - if (m_symbolGroup && m_threadId == threadId && m_frameNumber == frame.FrameNumber) - return m_symbolGroup; - return create(threadId, frame.FrameNumber); - } - - IDebugSymbolGroup2 *create() - { - ULONG threadId = ExtensionCommandContext::instance()->threadId(); - CIDebugControl *control = ExtensionCommandContext::instance()->control(); - DEBUG_STACK_FRAME frame; - if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL))) - return nullptr; - return create(threadId, frame.FrameNumber); - } - -private: - IDebugSymbolGroup2 *create(ULONG threadId, ULONG64 frameNumber) - { - CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols(); - releaseSymbolGroup(); - if (FAILED(symbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_ALL, NULL, &m_symbolGroup))) { - releaseSymbolGroup(); - return nullptr; - } - m_frameNumber = frameNumber; - m_threadId = threadId; - return m_symbolGroup; - } - void releaseSymbolGroup () - { - if (!m_symbolGroup) - return; - m_symbolGroup->Release(); - m_symbolGroup = nullptr; - } - -private: - IDebugSymbolGroup2 *m_symbolGroup = nullptr; - ULONG m_threadId = 0; - ULONG64 m_frameNumber = 0; -}; - static CurrentSymbolGroup currentSymbolGroup; +CurrentSymbolGroup::~CurrentSymbolGroup() +{ + releaseSymbolGroup(); +} + +IDebugSymbolGroup2 *CurrentSymbolGroup::get() +{ + ULONG threadId = ExtensionCommandContext::instance()->threadId(); + CIDebugControl *control = ExtensionCommandContext::instance()->control(); + DEBUG_STACK_FRAME frame; + if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL))) + return nullptr; + if (currentSymbolGroup.m_symbolGroup + && currentSymbolGroup.m_threadId == threadId + && currentSymbolGroup.m_frameNumber == frame.FrameNumber) { + return currentSymbolGroup.m_symbolGroup; + } + return create(threadId, frame.FrameNumber); +} + +IDebugSymbolGroup2 *CurrentSymbolGroup::create() +{ + ULONG threadId = ExtensionCommandContext::instance()->threadId(); + CIDebugControl *control = ExtensionCommandContext::instance()->control(); + DEBUG_STACK_FRAME frame; + if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL))) + return nullptr; + return create(threadId, frame.FrameNumber); +} + +IDebugSymbolGroup2 *CurrentSymbolGroup::create(ULONG threadId, ULONG64 frameNumber) +{ + CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols(); + currentSymbolGroup.releaseSymbolGroup(); + if (FAILED(symbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_ALL, NULL, + ¤tSymbolGroup.m_symbolGroup))) { + currentSymbolGroup.releaseSymbolGroup(); + return nullptr; + } + currentSymbolGroup.m_frameNumber = frameNumber; + currentSymbolGroup.m_threadId = threadId; + return currentSymbolGroup.m_symbolGroup; +} + +void CurrentSymbolGroup::releaseSymbolGroup() +{ + if (!m_symbolGroup) + return; + m_symbolGroup->Release(); + m_symbolGroup = nullptr; +} + // cdbext python module static PyObject *cdbext_parseAndEvaluate(PyObject *, PyObject *args) // -> Value { @@ -201,11 +196,11 @@ static PyObject *cdbext_listOfLocals(PyObject *, PyObject *args) // -> [ Value ] IDebugSymbolGroup2 *symbolGroup = nullptr; auto locals = PyList_New(0); if (partialVariable.empty()) { - symbolGroup = currentSymbolGroup.create(); + symbolGroup = CurrentSymbolGroup::create(); if (symbolGroup == nullptr) return locals; } else { - symbolGroup = currentSymbolGroup.get(); + symbolGroup = CurrentSymbolGroup::get(); if (symbolGroup == nullptr) return locals; @@ -303,7 +298,7 @@ static PyObject *cdbext_createValue(PyObject *, PyObject *args) << " type name: " << type->impl->name(); } - IDebugSymbolGroup2 *symbolGroup = currentSymbolGroup.get(); + IDebugSymbolGroup2 *symbolGroup = CurrentSymbolGroup::get(); if (symbolGroup == nullptr) Py_RETURN_NONE; @@ -367,7 +362,7 @@ static PyObject *cdbext_call(PyObject *, PyObject *args) if (debugPyCdbextModule) DebugPrint() << "Call ret value expression: " << name; - IDebugSymbolGroup2 *symbolGroup = currentSymbolGroup.get(); + IDebugSymbolGroup2 *symbolGroup = CurrentSymbolGroup::get(); if (FAILED(symbolGroup->AddSymbol(name.c_str(), &index))) Py_RETURN_NONE; return createPythonObject(PyValue(index, symbolGroup)); diff --git a/src/libs/qtcreatorcdbext/pycdbextmodule.h b/src/libs/qtcreatorcdbext/pycdbextmodule.h index 98c1b13333c..f1bc7d4c630 100644 --- a/src/libs/qtcreatorcdbext/pycdbextmodule.h +++ b/src/libs/qtcreatorcdbext/pycdbextmodule.h @@ -28,12 +28,33 @@ #include #include +#include "dbgeng.h" + void initCdbextPythonModule(); int pointerSize(); constexpr bool debugPyCdbextModule = false; using Bytes = std::vector; +class CurrentSymbolGroup +{ +public: + CurrentSymbolGroup() = default; + ~CurrentSymbolGroup(); + + static IDebugSymbolGroup2 *get(); + static IDebugSymbolGroup2 *create(); + +private: + static IDebugSymbolGroup2 *create(ULONG threadId, ULONG64 frameNumber); + void releaseSymbolGroup (); + +private: + IDebugSymbolGroup2 *m_symbolGroup = nullptr; + ULONG m_threadId = 0; + ULONG64 m_frameNumber = 0; +}; + #define PY_IMPL_GUARD if (!self->impl || !self->impl->isValid()) Py_RETURN_NONE #define PY_FUNC_DECL(func,pyObj) PyObject *func(pyObj *self) #define PY_FUNC_DECL_WITH_ARGS(func,pyObj) PyObject *func(pyObj *self, PyObject *args)