[ZODB-Dev] Coredump: ZODB, nested scopes, and pdb

Greg Ward gward@mems-exchange.org
Thu, 25 Oct 2001 13:28:30 -0400


Hi all --

I have a curious little coredump happening here.  I have managed to
reduce it to a ~20 line script with (maybe) two external dependencies,
notably our database and a command-line parsing library I wrote called
Optik.  I suspect both of these are red herrings (especially since the
code that calls Optik has no effect apart from eating sys.argv -- but
having the code there seems to make the difference between dumping core
or not; it's probably some delicate memory thing).  I thought I'd report
this before trying to further eliminate the remaining dependencies.

I'll attach the full script, because getting the coredump depends on
having the main code in main(), and having two useless lines of code.
(I don't think it will be useful to anyone except the other MEMS
Exchange developers right now, since nobody else has our database and
Optik.)

Anyways, here's the meat of the code:

    storage = FileStorage("/www/var/mxdb.fs")
    db = DB(storage)
    conn = db.open()
    root = conn.root()

    std_DC = root["standard_units"].dims
    std_DC_oid = std_DC._p_oid
    print "standard DimensionCollection: %r %r" % (std_DC_oid, std_DC)

If I run this with a regular interpreter, no problem -- the database is
opened, the "standard_units" object is fetched, etc.  All is fine.

If I run it through pdb, Python dumps core as soon as I try to step over
(or into) the second last line, ie. the line that fetches _p_oid.  If I
replace that line with other actions that de-ghostify an object, like
"dir(std_DC)" or "std_DC.foo", the same thing happens.

If I start up ZEO serving /www/var/mxdb.fs and open a ClientStorage
instead, the same thing happens.

Here's the first bit of the C traceback from gdb:

 #0  PyCell_Set (op=0x0, obj=0x8151320) at Objects/cellobject.c:32
 #1  0x808edc0 in dict_to_map (map=0x8141b3c, nmap=1, dict=0x8108e44, 
     values=0x81a3138, deref=1, clear=1) at Objects/frameobject.c:287
 #2  0x808f064 in PyFrame_LocalsToFast (f=0x81a2ff0, clear=1)
     at Objects/frameobject.c:371
 #3  0x80598d5 in call_trace (p_trace=0x81a3010, p_newtrace=0x81a3010, 
     f=0x81a2ff0, msg=0x80accc2 "line", arg=0x80ccc4c) at Python/ceval.c:2595
 #4  0x80587e6 in eval_code2 (co=0x8140fe0, globals=0x80dfdbc, locals=0x0, 
     args=0x8128cfc, argcount=0, kws=0x8128cfc, kwcount=0, defs=0x0, 
     defcount=0, closure=0x0) at Python/ceval.c:1926
 #5  0x805a24d in fast_function (func=0x8168ebc, pp_stack=0xbffff204, n=0, 
     na=0, nk=0) at Python/ceval.c:3015
 #6  0x80588e1 in eval_code2 (co=0x8141060, globals=0x80dfdbc, 
     locals=0x80dfdbc, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, 
     defcount=0, closure=0x0) at Python/ceval.c:1966
 #7  0x8055cb8 in PyEval_EvalCode (co=0x8141060, globals=0x80dfdbc, 
     locals=0x80dfdbc) at Python/ceval.c:341
 #8  0x806e773 in run_node (n=0x814dee0, filename=0x814de14 "pdb_coredump.py", 
     globals=0x80dfdbc, locals=0x80dfdbc, flags=0x0) at Python/pythonrun.c:1045

It's fairly obvious from the Python 2.1 source that it dumps core
because the 'op' argument to PyCell_Set() is NULL.  (The first thing
PyCell_Set() does is call a macro, PyCell_Check, that does
"(op)->ob_type".)

This is with Python 2.1; ZODB and ZEO (I think) from Andrew's SF
repository, so fairly recent (I think).  Haven't tried Python 2.1.1
because our 2.1.1 installation isn't complete.  Hmmmph.

        Greg
-- 
Greg Ward - software developer                gward@mems-exchange.org
MEMS Exchange                            http://www.mems-exchange.org