Pyro Troubleshooting
Everything that is not a bug in Pyro itself.
please: if you have a problem, try the latest (perhaps even CVS) version of Pyro and see if the problem still occurs.
Contents
-
Pyro Troubleshooting
- Pyro and Python 3.x
- Problems with user defined exception classes
- Pyro and SSL issues
- connection problems involving localhost/127.0.0.1
- Problems when using Numeric
- deadlock (freeze) on RedHat 9
- problems using COM (or related stuff like ADO DB API) from Pyro objects (on Windows)
- Memory allocation errors on Windows
- 'bad file descriptor' errors on Windows
- connection errors on Windows
- Windows NT Naming Service (nssvc) doesn't respond to broadcasts
- AttributeError: ''some object'' instance has no attribute 'objectGUID'
- ConnectionClosed errors when using socket.setdefaulttimeout
Pyro and Python 3.x
Pyro doesn't work on Python 3.x. Use Python 2.x instead (recommended: 2.6).
Problems with user defined exception classes
In Python 2.5 and later, there is an issue with user-defined exceptions. Say you have a custom exception class written as follows:
1 class MyEx(Exception):
2 def __init__(self, mymessage):
3 self.mymessage=mymessage
4 def __str__(self):
5 return "[MyEx '%s']" % self.mymessage
If you are passing these exceptions over the wire in Pyro method calls, you will find that your program crashes with an error like this: TypeError: ('__init__() takes exactly 2 arguments (1 given)', <class '__main__.MyEx'>, ())
This is not Pyro's fault: it is caused by a change in the Exception classes which was introduced in Python 2.5. This change seems to cause that Exception objects don't follow the usual pickle protocol. The unpickling of the exception object fails, because the __init__ method is called without any arguments (it shouldn't even be called at all by the way!) Unfortunately you won't be able to fix this problem by writing a __getinitargs__ or __getnewargs__ method to force the correct parameters, because these methods won't be called.
The easiest way to work around this problem now seems to change your __init__ method so that it uses *args instead of a single argument (this is what the built in Exceptions seem to do), or change it a little so that it also works with zero arguments:
1 def __init__(self, mymessage=None):
2 self.mymessage=mymessage
If you don't need any special behavior of your own exception objects, it is probably best to just subclass them from Exception and not define any custom methods or properties. That avoids the problem as well. As far as I know all builtin exceptions already accept a string argument to be used as the exception message, so there is no need to subclass the exception and add custom behavior as shown above, if you just want to remember a message string.
Pyro and SSL issues
Pyro uses M2Crypto for SSL. There is a known bug that makes the use of socket timeouts (socket.setdefaulttimeout) impossible when using SSL.
connection problems involving localhost/127.0.0.1
The Troubleshooting chapter in the Pyro manual already contains a paragraph on this issue, but it appears that it is rather nasty. What are the symptoms: your pyro client cannot connect to a server and it seems that somehow the 127.0.0.1 address is involved. Probable cause: incorrect DNS config, or the server's host name resolves to 127.0.0.1, for instance because the hosts file contains an invalid entry. only "localhost" is allowed resolve to 127.0.0.1 ! Usually, Pyro will warn you about this issue though.
This problem occurs on Linux systems, but I don't think it can really be considered an incorrect configuration. It is a deliberate step to deal with issues involving multi-homed hosts. For practical purposes, Pyro already provides an option that gives a satisfactory workaround: PYRO_DNS_URI. Setting this configuration option to "true" on both the client and server allows for usable name resolution. You will still see the warning, but things will work.
Problems when using Numeric
The problem is originated in Pickle and is related to "from Numeric import *". The work around is to include "del array_constructor" after "from Numeric import *" in a module that you want to import. Or just don't use from Numeric import blah and instead only use import Numeric.
deadlock (freeze) on RedHat 9
On certain Redhat 9 boxes, Pyro servers seem to hang. You can duplicate this by simply starting the nameserver and then bang on it in a couple of windows running 'nsc listall' in a tight while loop. What happens is truly odd. Eventually, one of the clients will hang waiting for an authentication token, immediately after establishing a connection.
The problem is Redhat 9 and the new NPTL thread library. The solution was to update glibc and the kernel to the latest version. Check out at bugzilla.redhat.com bugs #86416 and #97637.
So it's not Pyro's fault, and also not Python's fault.
If all else fails you may have good results with telling Redhat to revert to the old threading behavior. To do this set the following environment variable:
export LD_ASSUME_KERNEL=2.2.5
problems using COM (or related stuff like ADO DB API) from Pyro objects (on Windows)
Note, that Pyro uses threads and pythoncom (win32com) needs to be initialized seperately for each thread (google for solutions). Also, in adodbapi.py there are some try...catch statements that mask the real exception so you might want to comment them out.
If you see something like: com_error: 'CoInitialize has not been called.' you're having this problem
Add pythoncom.CoInitialize() and pythoncom.CoUninitialize() calls in your Pyro objects and things should work.
Memory allocation errors on Windows
Windows seems to have a bug in the TCP/IP stack that makes Python crash with a MemoryError if large data chunks are transferred over the network. Because this is the second OS that has problems with large data chunks (see above), and because it's not possible to fix Windows, I decided to end this once and for all, and since Pyro 3.4 it transfers data in chunks of about 60 kb. This should work on all OSes, right? *sigh*
'bad file descriptor' errors on Windows
If you see "error: bad file descriptor" crashes on Windows, chances are that you are running your Pyro stuff as a windows service. Windows services have to meaningful way to interact with stdin/stdout, so you should not be using standard input/output or the print statement. The failure doesn't occur immediately, but after some buffer size is exceeded (this is the confusing part). Pyro's BasicNTService.py contains code to work around the problem.
connection errors on Windows
If you have troubles in your Pyro client code, when it tries to connect to a Pyro server, that look like these: "socket.error: (10048, 'Address already in use')" or "Pyro.errors.ProtocolError: connection failed", read the following.
There seems to be a problem (bug? feature?) in the Windows TCP stack that makes your program crash if it creates a lot of socket connections to the same location. Or maybe even just socket connections. I have no idea what is causing this, but it can be easily reproduced by the following code:
1 import socket
2 for i in range(50000):
3 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4 s.connect(('localhost',9000))
5 s.send("bla")
6 s.close()
7 if i %100==0:
8 print i
Run this small server code first, this is where that code is talking to:
1 import socket as s
2 import sys
3 serv=s.socket(s.AF_INET, s.SOCK_STREAM)
4 serv.bind(('',9000))
5 serv.listen(5)
6 while True:
7 (c,l) = serv.accept()
8 while True:
9 data=c.recv(9000)
10 if data:
11 print data,
12 else:
13 break
14 sys.stdout.flush()
15 c.close()
I reproduced the problem using Python 2.4 and 2.5 on windows XP. No problem occurred on Mac OS X. You may have to wait up to 2000 or 3000 iterations (socket creations) before the program crashes, but I've also seen it crash after only a couple of hundred socket creations. I have no work around.
Windows NT Naming Service (nssvc) doesn't respond to broadcasts
When using the nssvc windows NT service, you may find that the Windows Firewall is blocking broadcast communication. Disable Windows Firewall or configure it to leave the nssvc alone somehow. That will allow Pyro's broadcast NS locator to find your Name Server again.
AttributeError: ''some object'' instance has no attribute 'objectGUID'
if you get the above error, it's most likely because you forgot
Pyro.core.SynchronizedObjBase.__init__(self)
in the __init__ method of the class derived from Pyro.core.SynchronizedObjBase
ConnectionClosed errors when using socket.setdefaulttimeout
There are some problems when using the socket.setdefaulttimeout feature of Python. It doesn't work well because it is a global setting and it changes socket behavior in the whole interpreter. Use it with caution. It's safer to use Pyro's own timeout features.
The biggest problem is with SSL connections: M2Crypto SSL sockets will cause connection closed errors because they're no longer returning any data on receive calls. I have no idea how to fix this. (My idea is that M2Crypto puts the socket in nonblocking mode but fails to process the timeout setting, thus the socket immediately returns without any data at all)
More info on this bug here: https://bugzilla.osafoundation.org/show_bug.cgi?id=2341
