[Zope] Debugging tip: Actual HTTP Request with PDB & emacs, also applicable to other IDEs

Andrew Athan aathan-zope-list%REMOVEME@memeplex.com
Wed, 11 Apr 2001 02:36:00 -0400


Perhaps I am missing some basic technique, but I don't believe this is
documented anywhere, including the numerous debugging how-to's I've read.

First, this simple technique for debugging Zope & Zope products within emacs
amounts to:

1) Make some simple changes to emacs configs
2) Make some simple changes to Zope so that it handles requests single
threaded
3) Specify where in the Zope (or your) code the debugger should start
4) Run pdb-mode in emacs, telling it to start Zope

I don't think Test.py cuts it for me because I want to be able to see the
response in a browser, and I like to interact with the dugger in an IDE (for
me, emacs).  The big problem was that the default PubCore behavior involves
a separate thread which handles the request, and this wreaks havoc on pdb &
on emacs' comint mode.  The details have to do with the fact that pdb does
not track thread creation & switching, etc.

So, now the details:

1) Make some simple changes to emacs configs
1.A) I assume you're running the latest emacs with decently current python &
gud modes.
1.B) Put this into your .emacs if you're running on win32: (setq
gud-pdb-marker-regexp
  "^>
\\([-a-zA-Z0-9_/.:\\]*\\|<string>\\)(\\([0-9]+\\))\\([a-zA-Z0-9_]*\\|\\?\\)(
)\\(->[^\n]*\\)?\n")

2) Make some simple changes to Zope so that it handles requests single
threaded
   This amounts to replacing the contents of __init__.py in PubCore with the
lines following the ============= at the bottom of this message

3) Specify where in the Zope (or your) code the debugger should start
Put
import pdb
at the very top of one of the Zope product files, even at the top of z2.py
and
pdb.set_trace()
at the spot you want to start debugging from.  I bet with some name space
trickery you can make this happen inside a DTML document.  Haven't tried
yet.

4) Run pdb-mode in emacs, telling it to start Zope
   M-x pdb
enter the following as the command, assuming a win32 platform and my setup:
   D:\Zope\bin\python.exe -i D:\Zope\z2.py -D -t 1

When your set_trace() call gets hit, you will be dropped into the debugger,
and emacs will load the right file and move around with you as you use
debugging commands.  Enter "continue" and Zope will go along its merry way
and return the results of your page to the browser, and wait for the next
request.

I hope this saves someone the 2 hours of reading Zope, medusa, and other
sources that I spent.

If this is totally misguided and there is a simpler technique, I'm all
ears!!

A.


===================

import ZRendezvous
from ZPublisher import publish_module

_handle=None
_n=1

def _simple_handle(name,request,response):
    print name,request,response
    try:
        publish_module(
            name,
            request=request,
            response=response)
    finally:
        response._finish()

def handle(*args, **kw):
    global _handle
    global _n

    if _handle is None:
        if _n==1:
            _handle = _simple_handle
        else:
            _handle=ZRendezvous.ZRendevous(_n).handle

    return apply(_handle, args, kw)

def setNumberOfThreads(n):
    global _n
    _n=n
    global setNumberOfThreads
    del setNumberOfThreads