Commit 72446bce authored by Thomas Moulard's avatar Thomas Moulard
Browse files

Merge pull request #7 from francois-keith/master

Reduce the memory consumption in the interpreter.
parents 74a13936 7eb43ee3
......@@ -53,6 +53,7 @@ ADD_DEFINITIONS(-DBOOST_FILESYSTEM_VERSION=2)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(doc)
ADD_SUBDIRECTORY(unitTesting)
SETUP_PROJECT_FINALIZE()
......@@ -26,6 +26,12 @@
#include "convert-dg-to-py.hh"
#include "exception.hh"
// Ignore "dereferencing type-punned pointer will break strict-aliasing rules"
// warnings on gcc caused by Py_RETURN_TRUE and Py_RETURN_FALSE.
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
using dynamicgraph::Entity;
using dynamicgraph::SignalBase;
using dynamicgraph::command::Command;
......
......@@ -61,6 +61,8 @@ bool HandleErr(std::string & err,
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
if (ptraceback == NULL) {
ptraceback = Py_None;
// increase the Py_None count, to avoid a crash at the tuple destruction
Py_INCREF(ptraceback);
}
PyObject* args = PyTuple_New(3);
PyTuple_SET_ITEM(args, 0, ptype);
......@@ -73,12 +75,15 @@ bool HandleErr(std::string & err,
for (Py_ssize_t i=0; i<size; ++i)
stringRes += std::string
(PyString_AsString(PyList_GET_ITEM(pyerr, i)));
Py_DecRef(pyerr);
pyerr = PyString_FromString(stringRes.c_str());
err = PyString_AsString(pyerr);
dgDEBUG(15) << "err: " << err << std::endl;
Py_DecRef(pyerr);
// Here if there is a syntax error and
// Here if there is a syntax error and
// and the interpreter input is set to Py_eval_input,
// it is maybe a statement instead of an expression.
// Therefore we indicate to re-evaluate the command.
......@@ -91,7 +96,9 @@ bool HandleErr(std::string & err,
else
lres=true;
PyErr_Clear();
Py_CLEAR(args);
PyErr_Clear();
} else {
dgDEBUG(15) << "no object generated but no error occured." << std::endl;
}
......@@ -106,6 +113,7 @@ bool HandleErr(std::string & err,
{ dgDEBUG(15) << std::endl; }
else { dgDEBUG(15) << "No exception." << std::endl; }
dgDEBUGOUT(15);
Py_DecRef(stdout_obj);
return lres;
}
......@@ -195,19 +203,22 @@ void Interpreter::python( const std::string& command, std::string& res,
std::cout << "Output:" << out << std::endl;
if (err.size()!=0)
std::cout << "Error:" << err << std::endl;
result = PyObject_Repr(result);
PyObject* result2 = PyObject_Repr(result);
// If python cannot build a string representation of result
// then results is equal to NULL. This will trigger a SEGV
if (result!=NULL)
if (result2!=NULL)
{
dgDEBUG(15) << "For command :" << command << std::endl;
res = PyString_AsString(result);
res = PyString_AsString(result2);
dgDEBUG(15) << "Result is: " << res <<std::endl;
dgDEBUG(15) << "Out is: " << out <<std::endl;
dgDEBUG(15) << "Err is :" << err << std::endl;
}
else
else
{ dgDEBUG(15) << "Result is empty" << std::endl; }
Py_DecRef(stdout_obj);
Py_DecRef(result2);
Py_DecRef(result);
return;
}
......
......@@ -2,23 +2,34 @@
# Copyright
#
SET(EXECUTABLE_NAME test${PROJECT_NAME})
INCLUDE(CTest)
set(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
INCLUDE(../cmake/python.cmake)
FINDPYTHON()
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS} ${PYTHON_LIBRARY_DIRS})
ADD_DEFINITIONS(-DDEBUG=2)
# provide path to library libdynamic-graph.so
LINK_DIRECTORIES(${DYNAMIC_GRAPH_LIBRARY_DIRS})
ADD_EXECUTABLE(${EXECUTABLE_NAME}
main.cc
dynamic-graph-python-test.cc)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
LINK_DIRECTORIES(${${PROJECT_NAME}_BINARY_DIR}/src)
TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME}
dynamic-graph-python)
# Add dynamic-graph compilation flags and link to library libdynamic-graph.so
ADD_DEFINITIONS(${DYNAMIC_GRAPH_CFLAGS})
TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} ${DYNAMIC_GRAPH_LIBRARIES})
SET(EXECUTABLE_NAME interpreter-test)
ADD_EXECUTABLE(${EXECUTABLE_NAME} interpreter-test.cc)
TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} dynamic-graph-python)
TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} ${DYNAMIC_GRAPH_LIBRARIES} -lpthread -ldl -lutil)
ADD_TEST(${EXECUTABLE_NAME} ${EXECUTABLE_NAME})
// The purpose of this unit test is to evaluate the memory consumption
// when call the interpreter.
#include "dynamic-graph/python/interpreter.hh"
int main(int argc, char ** argv)
{
int numTest = 1;
if (argc > 1)
numTest = atoi(argv[1]);
dynamicgraph::python::Interpreter interp;
std::string command;
for (int i=0; i<numTest; ++i)
{
//correct input
command = "print \"Hello world\"";
interp.python(command);
//incorrect input
command = "print Hello";
interp.python(command);
std::string result;
std::string out;
std::string err;
//correct input
interp.python("print \"I am the interpreter\"", result, out, err);
//incorrect input
interp.python("print I am the interpreter", result, out, err);
}
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment