Python Callback from SWIG PyObject_Call Segfault - c++

I have a wx.py.Shell.shell widget which lets the user execute python code that interacts with my program. I want to be able to pass a function that the user defines in this space to my C++ code (Through the wxswig generated wrapper around my custom widget)and execute it.
In my C++ code I'm using a std::function <> class to invoke bound functions (C++ or Python)
So I created a simple class to wrap the PyObject with the function call operator. However I get a segfault when I try to call the PyObject *.
class PyMenuCallback
{
PyObject *Func;
public:
PyMenuCallback(const PyMenuCallback &op2);
PyMenuCallback(PyObject *func);
~PyMenuCallback ();
void operator() (int id);
};
/////////////////////////////////////////////////////////
PyMenuCallback::PyMenuCallback(PyObject *func)
: Func(func)
{
Py_XINCREF (Func);
if(!PyCallable_Check(Func))
cout << "Not a Callable Callback." << endl; //Throw an exception or something
}
PyMenuCallback::PyMenuCallback(const PyMenuCallback &op2)
: Func (op2.Func)
{
Py_XINCREF (Func);
if(!PyCallable_Check(Func))
cout << "Not a Callable Callback." << endl;
}
PyMenuCallback::~PyMenuCallback()
{
Py_XDECREF (Func);
}
void PyMenuCallback::operator() (int id)
{
cout << "Calling Callback" << endl;
if (Func == 0 || Func == Py_None || !PyCallable_Check(Func))
return;
cout << "Building Args" << endl;
PyObject *arglist = Py_BuildValue ("(i)",id);
cout << "Func: " << Func->ob_type->tp_name << " " << Func->ob_refcnt << endl;
PyObject *result = PyObject_Call(Func,arglist,0); //<<<<<---SEGFAULTS HERE
cout << "Executed" << endl;
Py_DECREF(arglist);
Py_XDECREF(result);
}
In my attempts to find what was going on, I put a bunch of print statements.
One of which prints the type name and reference count the line before the segfault. This results in "function 3" so I have to assume the function has not been destroyed yet.
I'm passing the following to swig:
void AddOption (std::string name, PyObject *pycallback);
In which I construct a PyMenuCallback
I'm at a loss for what's causing the segfault, any ideas?

Since the C++ calling the python callback is within a wxWidget, and the swig wrapper is generated by the special wxPython swig (wxswig?) There is some thread protection required around the function call...
The fixed operator should look like this
void PyMenuCallback::operator() (int id)
{
cout << "Calling Callback" << endl;
if (Func == 0 || Func == Py_None || !PyCallable_Check(Func))
return;
cout << "Building Args" << endl;
PyObject *arglist = Py_BuildValue ("(i)",id);
cout << "Built: " << arglist << endl;
cout << "Func: " << Func->ob_type->tp_name << " " << Func->ob_refcnt << endl;
wxPyBlock_t blocked = wxPyBeginBlockThreads(); //Anti-WxSwig
PyObject *result = PyObject_Call(Func,arglist,0);
wxPyEndBlockThreads(blocked);
cout << "Executed" << endl;
Py_XDECREF(arglist);
Py_XDECREF(result);
}
Make sure to include
#include "wx/wxPython/wxPython.h"
#include "wx/wxPython/wxPython_int.h"

Related

Check function template validity in C++14 when using -Waddress

When compiling this code with -Waddress:
#include <iostream>
#include <memory>
#include <string.h>
template <typename T, void (*func)(T*) = nullptr>
struct Caller {
Caller(T* ptr = nullptr)
{
std::cout
<< "Creating caller " << ptr
<< ", is function " << std::is_function<decltype(func)>()
<< ", is null " << std::is_null_pointer<decltype(func)>()
<< ", function is " << func
<< std::endl;
if (func)
{
std::cout << "Running for " << ptr << " func " << func << std::endl;
func(ptr);
}
}
};
void free_char(char *c) { free(c); }
int main() {
Caller<char, free_char>(strdup("Test"));
Caller<const char>("Test2");
return 0;
}
it will fail with:
/tmp/foo.cpp: In instantiation of ‘Caller<T, func>::Caller(T*) [with T = char; void (* func)(T*) = free_char]’:
/tmp/foo.cpp:36:40: required from here
/tmp/foo.cpp:13:33: warning: the address of ‘void free_char(char*)’ will never be NULL [-Waddress]
A workaround is using something like if (auto f = func) f(ptr); but i'd like to have something that is statically checked at compile time.
This solution mentions the usage of template specialization, but a part that here we're handling a struct, this is a case where i'd like to use static template checks.
How about simply providing a no-op function by default instead of a null pointer? This gets rid of the if altogether and makes the code cleaner in general.
template<typename T>
void no_op(T*) {}
template <typename T, void (*func)(T*) = no_op<T>>
struct Caller {
static_assert(func != nullptr, "don't pass nullptr");
Caller(T* ptr = nullptr)
{
std::cout
<< "Creating caller " << ptr
<< ", is function " << std::is_function<decltype(func)>()
<< ", is null " << std::is_null_pointer<decltype(func)>()
<< ", function is " << func
<< std::endl;
std::cout << "Running for " << ptr << " func " << func << std::endl;
func(ptr);
}
};

Exe crashes after coming out of the method in c++

I have a method FormatOutPut() that internally calls a "callBack" method MyFunct() in C++. There is a crash, when the control comes out the FormatOutPut(). The callback method MyFunct() just prints the output on the screen. When I debugged the code using windbg I got the following traces,
(1250.1270): Stack buffer overflow - code c0000409 (!!! second chance !!!)
What I am guessing is that,the return address on the stack for the FormatOutPut(), is corrupted by the callback method. So when control is shifted back to the calling method it crashes.
When I comment out the callback method everything works fine. Any inputs on this will be great help.
Callback method prototype is as below,
typedef void(__stdcall *MyCallBack)(char*,char*,char*,char*,char*,char*,char*,char*,char*,char*,int, int );
Body:-
void MyCallbackRoutine(char* GetFeature,char* GetVersion,char* GetStartDate, char* GetExpireDate, char* GetUsers,char* GetKey,char* GetVendorString, char* GetHostID,char* GetErrorMsg,char* GetLicense,int GetCheckOutStatus, int nCount)
{
if ( nCount == 0 )
{
_strtime_s( timeCallbackstart, 10 );
time(&startCallbackstart);
bOnlyOnce = true;
}
cout << endl;
cout << "-------------------------------------------------------" << endl;
cout << "GetCheckOutStatus: " << GetCheckOutStatus << endl;
cout << "GetErrorMsg: " << GetErrorMsg << endl;
cout << endl;
cout << "GetFeature: " << GetFeature << endl;
cout << "GetVersion: " << GetVersion << endl;
cout << "GetStartDate: " << GetStartDate << endl;
cout << "GetExpireDate: " << GetExpireDate << endl;
cout << "GetUsers: " << GetUsers << endl;
cout << "GetKey: " << GetKey << endl;
cout << "GetVendorString: " << GetVendorString << endl;
cout << "GetHostID: " << GetHostID << endl;
cout << "GetLicense: " << GetLicense << endl;
cout << endl;
cout << "Licenscounter: " << nCount << endl;
cout << "------------------------------------------------------" << endl;
cout << endl;
}
Thanks and Regards,
AKJ
The issue that I see is that your calling convention of __stdcall for the typedef of the function prototype and the callback function itself does not match. If the calling convention does not match up, stack issues can arise when returning from the called function.
More on calling conventions here.
The typedef for the function is as follows:
typedef void(__stdcall *MyCallBack)(char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,int, int );
but the function that is assigned as the callback has this:
void MyCallbackRoutine(char* GetFeature,char* GetVersion,char* GetStartDate,
char* GetExpireDate, char* GetUsers,char* GetKey,
char* GetVendorString, char* GetHostID,
char* GetErrorMsg,char* GetLicense,
int GetCheckOutStatus, int nCount)
The number and type of parameters match up, the return type void matches, but the key element that doesn't match is that __stdcall is missing. By default, The calling convention is __cdecl if not specified. The correction should be:
void __stdcall MyCallbackRoutine(char* GetFeature,char* GetVersion,char* GetStartDate,
char* GetExpireDate, char* GetUsers,char* GetKey,
char* GetVendorString, char* GetHostID,
char* GetErrorMsg,char* GetLicense,
int GetCheckOutStatus, int nCount)
Note that the compiler should have picked up the issue when assigning a function who's definition doesn't match the prototype as this small example demonstrates (If this compiler error occurs, do not try to fix it by applying a C-style cast to shut the compiler up -- that is not a fix).

How to put C++ source code snippet into a string?

I have some C++ code snippet in the program. I need to output them when running, such as:
int foo()
{
return 0;
}
void main()
{
string s = "
int foo()
{
return 0;
}
";
cout << "Code: " << s << endl;
cout << "Return value: " << foo() << endl;
}
I just don't want to copy foo() code into s manually. How to automatically put foo()'s code into s? For example using macro?
While this will make your source ugly, you can define the function body in a macro and then stringify it to print.
#define FOO\
int foo()\
{\
return 0;\
}
FOO
#define BASIC_STRINGIFY(x) #x
#define STRINGIFY(x) BASIC_STRINGIFY(x)
void main()
{
string s = STRINGIFY(FOO);
cout << "Code: " << s << endl;
cout << "Return value: " << foo() << endl;
}

testing "Try and Catch"

In this program, I am using template class, I have a header file and this is my main file. I am having trouble displaying the (".....") IndexOutOfBounds and displaying it on the screen.
#include "XArray.h"
#include <iomanip>
#include <string>
using namespace std;
template<class T>
void afriend ( XArray<T> );
int main()
{
XArray<double> myAD(18);
myAD.randGen(15, 100);
cout << myAD.getType() << endl;
cout << setprecision(1) << fixed << "\n\n Unsorted: " << myAD;
myAD.sort();
cout << "\n Now Sorted: " << myAD;
cout << "\n\n";
**try
{
cout << "A[-5] = " << setw(6) << myAD[-5] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}
try
{
cout << "A[8] = " << setw(6) << myAD[8] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}**
cout << "\n\n" << setprecision(2) << fixed;
cout << "Size = " << setw(6) << myAD.getSize() << endl;
cout << "Mean = " << setw(6) << myAD.mean() << endl;
cout << "Median = " << setw(6) << myAD.median() << endl;
cout << "STD = " << setw(6) << myAD.std() << endl;
cout << "Min # = " << setw(6) << myAD.min() << endl;
cout << "Max # = " << setw(6) << myAD.max() << endl;
return 0;
}
There is the Array.h file posted as a dropbox link
Array.h
The code for operator[] in Array.h is:
template <class T>
T XArray<T>::operator[] (int idx)
{
if( (idx = 0) && (idx < size) )
{
return Array[idx];
}
else
{
throw IndexOutOfBound();
return numeric_limits<T>::epsilon();
}
}
Although the question is somewhat obscure, give a try to these suggestions.
Firstly, it can happen that XArray<>::IndexOutOfBounds have no proper copy ctor. You can try catching by const reference to workaround that:
try
{
...
}
catch(const XArray<double>::IndexOutOfBound& e)
{
e.print();
}
Index operator in standard library containers does not check for bounds, there is a special getter that does the check called at(). If the XArray class is designed with standard library in mind, it could behave similarly.
However to get more adequate response you need to be more specific describing the trouble you are having.
I'm still wondering what exact question is.
However, I'm understanding the question is that how I can use 'catch' by using 'IndexOutOfBound'.
#include <exception>
#include <iostream>
using namespace std;
template <typename T>
class Array
{
private:
int m_nLength;
T *m_ptData;
public:
...
...
T& operator[](int nIndex)
{
//assert(nIndex >= 0 && nIndex < m_nLength);
if(nIndex < 0 || nIndex > m_nLength)
{
throw myex;
}
else
{
return m_ptData[nIndex];
}
}
//class definition for 'IndexOutOfBound'
class IndexOutOfBound: public exception
{
public:
virtual const char* print() const throw()
{
return "Exception occured 'Index Out Of Bound'";
}
}myex;
};
int main()
{
Array<double> arr(3);
try
{
arr[0] = 1;
//exception will occur here.
arr[4] = 2;
}
catch(Array<double>::IndexOutOfBound &e)
{
cout << e.print() << '\n';
}
return 0;
}
Here is no 'XArray.h', so I've written a sample array class for example.
The problem is in the operator[] function. The code idx = 0 sets idx to 0. So all of your calls to operator[] will return the first element, and therefore there is no out-of-bounds error unless the array is empty.
You probably meant to write if ( idx >= 0 && idx < size ).
BTW the throw aborts the function, it makes no sense to return after throw.

c++11 capture-by-value lambda producing wrong value

I'm trying to store a lambda in an object system involving several layers of indirection. I'm using g++ 4.7.1.
Depending on how exactly I construct the (equivalent) objects, the lambda may or may not have the correct value.
Code:
#include <iostream>
#include <functional> // used for std::function
using namespace std; // TODO nope
typedef function<int()> intf;
struct SaveLambda {
const intf func;
SaveLambda(const intf& _func) : func(_func) {}
};
struct StoreSaved {
const SaveLambda* child;
StoreSaved(const SaveLambda& _child) : child(&_child) {
cout << "Before returning parent: " << child->func() << endl;
}
};
int main() {
const int ten = 10;
auto S = SaveLambda([ten](){return ten;});
cout << "No indirection: " << S.func() << endl << endl;
auto saved = StoreSaved(S);
cout << "Indirection, saved: " << saved.child->func() << endl << endl;
auto temps = StoreSaved ( SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;}) );
cout << "***** what. *****" << endl;
cout << "Indirection, unsaved: " << temps.child->func() << endl;
cout << "***** what. *****" << endl << endl;
cout << "ten still lives: " << ten << endl;
}
Compile as g++ -std=c++11 -Wall -o itest itest.cpp and run: notice the one line of output with a different value.
What am I doing wrong? I assumed that capture-by-value would, well, capture by value. (Observe most disconcertingly that the print in StoreSaved (line 15) produces the correct value, unlike line 34, despite these both referring to the same object. The only difference is adding another layer of indirection.)
This is wrong:
auto temps = StoreSaved(
/* This temporary value dies at the last semicolon! */
SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;})
);
StoreSaved then has a pointer to a nonexistent object. Using it is UB.
As already pointed out by others, the problem is that in temps you end with a pointer to a nonexistent SaveLambda struct, as it is a temporary.
You can keep a copy using a SaveLambda struct in StoreSaved, instead of a pointer:
struct StoreSaved {
const SaveLambda child;
StoreSaved(const SaveLambda& _child) : child(_child) {
cout << "Before returning parent: " << child.func() << endl;
}
};
You also have to change all the child->func() to child.func(), as you are not dealing with a pointer anymore.