Tuesday, February 8, 2011

[Discuss-gnuradio] Re-Occurrence of bug #199 in code based on gr_bin_statistics_f

--- ./gr_feval.i 2011-02-04 09:24:06.153283011 -0500
+++ /home/tja/Research/energy/detector/GR_ORIGINAL/gnuradio-3.3.0/gnuradio-core/src/lib/general/gr_feval.i 2010-06-01 20:57:52.000000000 -0400
@@ -70,11 +70,11 @@
// class that ensures we acquire and release the Python GIL

class ensure_py_gil_state {
PyGILState_STATE d_gstate;
public:
- ensure_py_gil_state() { PyEval_InitThreads(); d_gstate = PyGILState_Ensure(); }
+ ensure_py_gil_state() { d_gstate = PyGILState_Ensure(); }
~ensure_py_gil_state() { PyGILState_Release(d_gstate); }
};

%}

Hello all,

It looks as though I have uncovered GNU Radio bug #199 in one of my programs. I used gr_bin_statistics_f as a template and designed a new block which uses the same method to callback to Python code and retune the USRP.

http://gnuradio.org/redmine/issues/show/199

Now, I could get into more details of my specific program, however it seems like this bug could be hard to replicate on different hardware. I am not sure to the extent of the issue, but I know where the problem is.

---

The problem occurs in the callback code in gr_feval.i. As described in the bug report, Py_GILState_Ensure() is called before calleval(), and then Py_GILState_Release() is called after returning from Python land. It is at this point that I get a segmentation fault.

For a gdb stacktrace similar to that on the bug report, please refer to my blog post:

http://tomonprogramming.blogspot.com/2011/02/gnu-radio-bug-199.html

After googling around for a while I read about similar issues which were solved by adding a call to PyEval_InitThreads() right before Py_GILState_Ensure() is called (hinted at in the bug report). This did the trick for me! Calling PyEval_InitThreads() acquires and initializes the GIL, and calling it multiple times is a NOOP. More details can be found in Python documentation. I am not sure if this is the correct solution, but it worked for me. Others have suggested to me that the module using the multi-threaded Python extension should 'import threading' early to ensure that PyEval_InitThreads is called.

Finally, here is the system I tested on:
Fedora 14 64-bit
Linux tjadesktop 2.6.35.10-72.fc14.x86_64 #1 SMP Mon Dec 20 21:14:22 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
Intel i5 760
USRP 1 w/ WBX d'board

I have attached a small patch file which includes my fix. I could submit a formal fix if that would help, but I would really just like to get some feedback on the issue. What do you guys think?

Thanks!
-Tom


No comments:

Post a Comment