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:
David Schulz
2016-09-19 14:01:29 +02:00
parent a2a766d770
commit 14c65ed6db
4 changed files with 75 additions and 6 deletions

View File

@@ -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)

View File

@@ -26,3 +26,4 @@ addwatch
widgetat
breakpoints
KnownStructOutput
script

View File

@@ -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

View File

@@ -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);