forked from qt-creator/qt-creator
CdbExt: Add python scripting
Introducing the script extension command that allows to run basic python code. Change-Id: I356ca5408474be0206b1c77cf2a0ecf6640ec651 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -33,6 +33,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include <Python.h>
|
||||
#endif
|
||||
|
||||
// wdbgexts.h declares 'extern WINDBG_EXTENSION_APIS ExtensionApis;'
|
||||
// and it's inline functions rely on its existence.
|
||||
WINDBG_EXTENSION_APIS ExtensionApis = {sizeof(WINDBG_EXTENSION_APIS), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
@@ -155,6 +159,10 @@ HRESULT ExtensionContext::initialize(PULONG Version, PULONG Flags)
|
||||
*Version = DEBUG_EXTENSION_VERSION(1, 0);
|
||||
*Flags = 0;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
Py_Initialize();
|
||||
#endif
|
||||
|
||||
IInterfacePointer<CIDebugClient> client;
|
||||
if (!client.create())
|
||||
return client.hr();
|
||||
@@ -503,6 +511,9 @@ HRESULT CALLBACK DebugExtensionInitialize(PULONG Version, PULONG Flags)
|
||||
|
||||
void CALLBACK DebugExtensionUninitialize(void)
|
||||
{
|
||||
#ifdef WITH_PYTHON
|
||||
Py_Finalize();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CALLBACK DebugExtensionNotify(ULONG Notify, ULONG64)
|
||||
|
||||
@@ -26,3 +26,4 @@ addwatch
|
||||
widgetat
|
||||
breakpoints
|
||||
KnownStructOutput
|
||||
script
|
||||
|
||||
@@ -96,6 +96,18 @@ HEADERS += extensioncontext.h \
|
||||
knowntype.h \
|
||||
symbolgroupnode.h
|
||||
|
||||
isEmpty(PYTHON_INSTALL_DIR):PYTHON_INSTALL_DIR=$$(PYTHON_INSTALL_DIR)
|
||||
exists($$PYTHON_INSTALL_DIR) {
|
||||
DEFINES += WITH_PYTHON=1
|
||||
|
||||
INCLUDEPATH += $$PYTHON_INSTALL_DIR/include
|
||||
DEPENDPATH += $$PYTHON_INSTALL_DIR/include
|
||||
|
||||
#TODO: parse version number for a generic approach
|
||||
CONFIG(release, debug|release): LIBS += -L$$PYTHON_INSTALL_DIR/libs -lpython35
|
||||
else:CONFIG(debug, debug|release): LIBS += -L$$PYTHON_INSTALL_DIR/libs -lpython35_d
|
||||
}
|
||||
|
||||
target.path = $$QTC_PREFIX/lib/$${DIRNAME} # TODO this should go to INSTALL_LIBRARY_PATH/$${DIRNAME}
|
||||
|
||||
INSTALLS += target
|
||||
|
||||
@@ -23,13 +23,17 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "extensioncontext.h"
|
||||
#include "outputcallback.h"
|
||||
#include "eventcallback.h"
|
||||
#include "extensioncontext.h"
|
||||
#include "gdbmihelpers.h"
|
||||
#include "outputcallback.h"
|
||||
#include "stringutils.h"
|
||||
#include "symbolgroup.h"
|
||||
#include "symbolgroupvalue.h"
|
||||
#include "stringutils.h"
|
||||
#include "gdbmihelpers.h"
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include <Python.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
@@ -106,7 +110,8 @@ enum Command {
|
||||
CmdWidgetAt,
|
||||
CmdBreakPoints,
|
||||
CmdTest,
|
||||
CmdSetParameter
|
||||
CmdSetParameter,
|
||||
CmdScript
|
||||
};
|
||||
|
||||
static const CommandDescription commandDescriptions[] = {
|
||||
@@ -172,7 +177,8 @@ static const CommandDescription commandDescriptions[] = {
|
||||
{"breakpoints","List breakpoints with modules","[-h] [-v]"},
|
||||
{"test","Testing command","-T type | -w watch-expression"},
|
||||
{"setparameter","Set parameter",
|
||||
"maxStringLength=value maxArraySize=value maxStackDepth=value stateNotification=1,0"}
|
||||
"maxStringLength=value maxArraySize=value maxStackDepth=value stateNotification=1,0"},
|
||||
{"script", "Run Python command", "[-t token]"}
|
||||
};
|
||||
|
||||
typedef std::vector<std::string> StringVector;
|
||||
@@ -564,6 +570,45 @@ static std::string commandLocals(ExtensionCommandContext &commandExtCtx,PCSTR ar
|
||||
return symGroup->dump(iname, dumpContext, parameters.dumpParameters, errorMessage);
|
||||
}
|
||||
|
||||
extern "C" HRESULT CALLBACK script(CIDebugClient *client, PCSTR argsIn)
|
||||
{
|
||||
ExtensionCommandContext exc(client);
|
||||
int token;
|
||||
#ifdef WITH_PYTHON
|
||||
std::stringstream command;
|
||||
for (std::string arg : commandTokens<StringList>(argsIn, &token))
|
||||
command << arg << ' ';
|
||||
|
||||
if (PyRun_SimpleString(command.str().c_str()) == 0) {
|
||||
ExtensionContext::instance().reportLong('R', token, "script", "");
|
||||
} else {
|
||||
ExtensionContext::instance().report('N', token, 0, "script",
|
||||
"Error while executing Python code.");
|
||||
}
|
||||
|
||||
_Py_IDENTIFIER(stdout);
|
||||
_Py_IDENTIFIER(flush);
|
||||
|
||||
PyObject *fout = _PySys_GetObjectId(&PyId_stdout);
|
||||
PyObject *tmp;
|
||||
|
||||
if (fout != NULL && fout != Py_None) {
|
||||
tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
|
||||
if (tmp == NULL)
|
||||
PyErr_WriteUnraisable(fout);
|
||||
else
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
#else
|
||||
commandTokens<StringList>(argsIn, &token);
|
||||
ExtensionContext::instance().report('N', token, 0, "script",
|
||||
"Python is not supported in this CDB extension.\n"
|
||||
"You need to define PYTHON_INSTALL_DIR in your creator build environment "
|
||||
"pointing to a Python 3.5 installation.");
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
extern "C" HRESULT CALLBACK locals(CIDebugClient *client, PCSTR args)
|
||||
{
|
||||
ExtensionCommandContext exc(client);
|
||||
|
||||
Reference in New Issue
Block a user