Debugging with Manhole

Creating the Manhole Service

In order to create a manhole server, use a command like mktap manhole -u [username] -w [password]. If you've already got a TAP for a server, you can use the argument --append [tapname] to mktap to add a manhole service to that TAP.

Using the Manhole PB Client

The second service offered by twisted.manhole is a Perspective Broker -based server. This gives the client a remote reference to a twisted.manhole.service.Service object, which offers remotely-callable methods to evaluate Python code.

With this in place and running, you're ready to connect with the manhole client. This is a Gtk+-based GUI application named manhole that gets installed along with the rest of twisted. Execute the command manhole to start the client, and it will bring up a dialog that asks for hostname, port number, Service name, username, and password (and also Perspective but don't worry about that for now). Use the default host/port of localhost/8787 to indicate where the twisted.manhole service is listening, and use boss/sekrit for the username and password. Use the default Service name twisted.manhole, and leave the Perspective blank.

Click the Log In button to establish the connection, and you will be greeted with a short message in a window with an output area in the top, and an input area at the bottom. This is just like the python interpreter accessed through the telnet shell, but with a different GUI. You can type arbitrary python code into the input area and get the results in the output area. Note that multi-line sequences are all sent together, so if you define a function (or anything else that uses indentation to tell the interpreter that you aren't finished yet), you'll need to type one additional Return to tell the client to send off the code.

At this point, you can get access to the main Application object just like you did before with the telnet-based shell. You can use that to obtain the Service objects inside it, or references to the Factory objects that are listening on TCP or UDP ports, by doing:

from twisted.internet import app
a = app.theApplication
service = a.getServiceNamed("twisted.manhole")
(port, factory, backlog, interface) = a.tcpPorts[0]

After that, you can do anything you want with those objects.

Special Commands

At this time, not all commands are available in all manhole clients. /browse is currently only implemented in the GTK 1.x client, the Spelunking view is only available with GTK 1.x + GNOME.

There are a few special commands so far that make debugging Twisted objects really nice. Well, just one at the moment, really: /browse. You can /browse any type of object, and it will give you some nice information about that object in the Spelunking window that pops up when manhole establishes a connection to the manhole Service. Try the following in the manhole window and watch what happens in the Spelunking box (word wrapped for clarity):

/browse ["hello", "there"]
 <ObjectLink of ["hello", "there"] type list>:
  ['hello',
   'there',]


class A:
    def foo(self):
        self.x = 1

x = A()
/browse x
<ObjectLink of x type instance>:
  {members: {}
   class: 'A'
   methods: {}}

TODO: Add an example using twisted.python.rebuild.rebuild. This lets you tell your application (remotely) to reload its classes, allowing you to upgrade a running server without missing a beat.

Have fun!