On Wed, 2011-09-07 at 08:56 +0100, Vinay Sajip wrote:
[...snip...]
Actually I was trying "import ctypes; lib =
ctypes.cdll.LoadLibrary('python.so')" when I got the cfun error. Now I
realise I can't do this, because some of the symbols are in the
compiler itself.
Yes: AIUI, the structure is a bit like this:
toplevel "gcc" harness process
|
| (launches child process)
V
"cc1" compiler (contains "cfun")
|
| (dynamic loads)
V
"python.so" plugin (consumes "cfun" and "_Py_ZeroStruct")
|
| (dynamically linked against)
V
libpython2.7.so (contains _Py_ZeroStruct)
If I run "make" (after "make plugin" completed
without errors), I get a load error because of failure to find a
different symbol: _Py_ZeroStruct.
"make demo" can be a nice way to debug this, as it simply tries to
directly compile a single file, using the plugin.
You could try:
LD_DEBUG=all make demo 2> test.log
to generate (very) verbose diagnostics from the dynamic linker to
stderr, and thus to a log file. (set LD_DEBUG=help to get more info on
this).
However, this symbol is in
/usr/lib/python2.7/config/libpython2.7.so,
so it's hard to see what's going on. I checked that the 2.7 headers
are included and the 2.7 library is linked against in the "make
plugin" step - all looks OK.
My guess is that we're seeing an issue to do with how dlopen() is
invoked when the plugin is loaded.
I wonder if there's a difference between the dlopen() lines used to load
plugins in the versions of gcc that we're using.
See e.g.
http://gcc.gnu.org/ml/gcc/2011-09/msg00022.html
In the version of gcc I've been using (gcc-4.6.0-10.fc15.x86_64 on
Fedora), that code is in gcc/plugin.c:try_init_one_plugin and looks like
this:
/* We use RTLD_NOW to accelerate binding and detect any mismatch
between the API expected by the plugin and the GCC API; we use
RTLD_GLOBAL which is useful to plugins which themselves call
dlopen. */
dl_handle = dlopen (plugin->full_name, RTLD_NOW | RTLD_GLOBAL);
if (!dl_handle)
{
error ("cannot load plugin %s\n%s", plugin->full_name, dlerror ());
return false;
}
Or perhaps a difference in how libpython2.7.so is built between Ubuntu
and Fedora, maybe.
I've set LD_LIBRARY_PATH to /usr/lib/python2.7/config:
$HOME/projects/gcc-python-plugin, but that makes no difference to what
I'm seeing.
By the way, there's one more thing I had to change: c-common.h is not
on the default include path on Ubuntu, so I had to change #includes to
"c-family/c-common.h" in a couple of C files and the autogenerator
Python script.
This may be a 4.6.0 to 4.6.1 difference; see:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45348
http://gcc.gnu.org/viewcvs?view=revision&revision=176741
and also:
https://bugzilla.redhat.com/show_bug.cgi?id=728011