[mod_python] mod_python interpreter creation issue

Graham Dumpleton grahamd at dscpl.com.au
Tue Mar 15 23:19:25 EST 2005


John Belmonte wrote ..
> Several months ago an installation of my application which uses 
> mod_python/Quixote/ZODB/ZEO suddenly stopped working.  It appears to 
> have been caused by a mod_python upgrade.  I'm on Debian and now using
> 3.1.3, although I don't know what version I was using previously.
> 
> I traced the error to a "ImportError: No module named copy_reg" 
> resulting from a cPickle.Pickler() call.  This is caused by Python 
> thinking that it's in restricted execution mode.  The error is happening
> within ZEO's client thread code.
> 
> The following mod_python list message "Threads running in restricted 
> mode?" seems to detail similar problems, but no one responded to the issue.
> 
>    http://www.modpython.org/pipermail/mod_python/2005-January/017129.html
> 
> Tim Peters speculates that mod_python might be starting a new 
> interpreter from time to time using the Python C API.  The new 
> interpreter will have distinct copies of the sys module, the sys.modules
> dict, and the sys.path list, triggering Python's restricted execution mode.
> 
> Anyone have some insight to this problem?  Or at least, would someone 
> explain how and when mod_python creates new interpreters?

For an explaination of interpreters and what gets created when, read:

  http://www.modpython.org/live/mod_python-3.1.2b/doc-html/pyapi-interps.html

The closest I have ever got to problems with restricted mode is the
runtime exception "classes are read-only in restricted mode".

In my circumstance, which was probably pretty unique in terms of
what I was actually doing, I was trying to communicate between
subinterpreters within the one Apache process using a messaging
system (http://ose.sourceforge.net).

In order to do this the event system which runs the messaging system
is started up within its own thread from Python. The messaging system
then actually executes in its own right as C++ code, not Python code.

So that messages can come back into the Python world, callbacks are
registered in the C++ world for the Python functions to be called. At
some later point when the messaging system has something it will
execute the Python callback.

What happened though was that when the callback was executed I
got the Python run time error "classes are read-only in restricted mode".

The cause of this turned out to be because I had created the initial
thread for the messaging system in a dedicated interpreter created
for that purpose by using PythonImport directive with a special
interpreter name.

A programming problem in OSE however meant that it saved away
the thread state corresponding to that special interpreter and it
tried to use that thread state when trying to callback into other
interpreters. Because the thread state wasn't associated with these
other interpreters, it would only execute code in restricted mode.

Correspondingly, the messaging system worked great for where
you wanted to communicate within the one interpreter and to outside
processes, but not between multiple interpreters created by mod_python
in the same Apache process. I have yet to fix OSE to make it work
but might be motivated now to do something about it.

How is this tale relevant. Well, it may if any of those packages you
are using have a C/C++ based component which operates a distinct
thread which at some point needs to callback into Python code.

Now you may think, "but I don't create any extra interpreters", but
that may not matter. This is because there are some bugs in the
mod_python code which can cause multiple sub interpreters of the
same name to be errornously created if a web server is under load
immediately from the point it was started and you are using a
multithread MPM.

What the bug means is that an interpreter gets created with a specific
name but because of inadequate thread locking on the creation of
interpreters, a second interpreter of the same name can get created
at the same time. One of these will get thrown away, with possibly
leaking of resources and after that you wouldn't normally notice
anything.

Theorectically however, if the first of those interpreters initialised some
C/C++ based module which created an internal thread it may have
saved away the thread state for that interpreter. Now if the second
interpreter registered some callback with C/C++ code, when that
code executes the callback, the saved thread state could be wrong
for that interpreter and thus it may execute in restricted mode.

Now all this may be totally irrelevant, but thread state problems and
callbacks is the only way I have seen that restricted mode can be triggered,
so thus simple mentioning it in case it might be helpful.

As to what to do about it, first thing would be to patch the thread
problems in mod_python using patches at:

  http://www.dscpl.com.au/projects/vampire/PATCHES

If however you aren't using a multithread MPM, this may make no
difference at all.

The only other thing I can add is to ask whether you are using a
multithreaded MPM? Do any of the third party packages create
internal threads? Do any of the third party packages have a C/C++
component to them?

Hope this helps.

Graham


More information about the Mod_python mailing list