<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1276" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>I would like to thank everyone for politely 
ignoring this post and not stating the obvious...</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Dave Harris is clueless!</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>I completely misapprended the problem. Instead of a 
code problem, the abort occurs during maintenance of the garbage collection 
chain. In particular, cm_dealloc() makes the call:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp;&nbsp; _PyObject_GC_UNTRACK((PyObject 
*)cm);</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>and the process collapses when the assignment to 
the previous element link is attempted. The address of the previous element 
appears to be 0xfffffffd (-3). Now I have to find out why.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>I'll post again when I have an answer.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Thanks for your patience,</FONT></DIV>
<DIV><FONT face=Arial size=2>Dave Harris</FONT></DIV>
<BLOCKQUOTE 
style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
  <DIV style="FONT: 10pt arial">----- Original Message ----- </DIV>
  <DIV 
  style="BACKGROUND: #e4e4e4; FONT: 10pt arial; font-color: black"><B>From:</B> 
  <A title=dpharris76@msn.com href="mailto:dpharris76@msn.com">David Harris</A> 
  </DIV>
  <DIV style="FONT: 10pt arial"><B>To:</B> <A title=osuchw@ecn.ab.ca 
  href="mailto:osuchw@ecn.ab.ca">W.Osuch</A> ; <A title=zope3-dev@zope.org 
  href="mailto:zope3-dev@zope.org">zope3-dev@zope.org</A> </DIV>
  <DIV style="FONT: 10pt arial"><B>Sent:</B> Friday, January 16, 2004 12:44 
  AM</DIV>
  <DIV style="FONT: 10pt arial"><B>Subject:</B> Re: [Zope3-dev] 
  Zope3+W2k+mingw=Python crash</DIV>
  <DIV><BR></DIV>
  <DIV><FONT face=Arial size=2>----- Original Message ----- </FONT></DIV>
  <DIV>
  <DIV><FONT face=Arial size=2>From: "W.Osuch" &lt;</FONT><A 
  href="mailto:osuchw@ecn.ab.ca"><FONT face=Arial 
  size=2>osuchw@ecn.ab.ca</FONT></A><FONT face=Arial size=2>&gt;</FONT></DIV>
  <DIV><FONT face=Arial size=2>To: &lt;</FONT><A 
  href="mailto:zope3-dev@zope.org"><FONT face=Arial 
  size=2>zope3-dev@zope.org</FONT></A><FONT face=Arial size=2>&gt;</FONT></DIV>
  <DIV><FONT face=Arial size=2>Sent: Wednesday, January 14, 2004 1:05 
  AM</FONT></DIV>
  <DIV><FONT face=Arial size=2>Subject: [Zope3-dev] Zope3+W2k+mingw=Python 
  crash</FONT></DIV></DIV>
  <DIV><FONT face=Arial><BR><FONT size=2></FONT></FONT></DIV>
  <DIV><FONT face=Arial size=2>&gt; Since there seems to be an increased 
  interest on the list in Zope3 on<BR>&gt; Windows tests result I am<BR>&gt; 
  posting an error that I have seen showing up for quite a 
  while.<BR></FONT></DIV>
  <DIV><FONT face=Arial size=2>&gt; test_descr_abuse 
  (zope.context.tests.test_wrapper.WrapperTestCase) ...<BR></FONT></DIV>
  <DIV><FONT face=Arial size=2>I've analyzed this failure down into the C code 
  and understand why it fails. But it leaves three questions to be 
  answered...</FONT></DIV>
  <DIV><FONT face=Arial size=2>1) Why is the failure only manifested on Windows 
  (XP in my case) and mingw32?</FONT></DIV>
  <DIV><FONT face=Arial size=2>2) Is the unit test wrong (as I describe 
  below)?</FONT></DIV>
  <DIV><FONT face=Arial size=2>3) Is the wrapper.c code incorrect?</FONT></DIV>
  <DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face=Arial size=2>The abort does occur in the test_descr_abuse unit 
  test at the ContextMethod() call. The current code looks like 
  this:</FONT></DIV>
  <DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2>&nbsp;&nbsp;&nbsp; def 
  test_descr_abuse(self):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def 
  abuse():<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  def foo(): 
  pass<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ContextMethod(ContextMethod(foo)).__get__(1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;self.assertRaises(TypeError, 
  abuse)<BR></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>Breaking it down a bit 
  further, I found that it's the second ContextMethod() call which triggers the 
  failure.</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT>&nbsp;</DIV></FONT>
  <DIV><FONT face=Courier size=2>&nbsp;&nbsp;&nbsp; def 
  test_descr_abuse(self):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def 
  abuse():<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  def foo(): pass<BR>&nbsp; 
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adebug = 
  ContextMethod(foo)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  bdebug = 
  ContextMethod(adebug)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  bdebug.__get__(1)</FONT></DIV>
  <DIV><FONT face=Courier 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;self.assertRaises(TypeError, 
  abuse)<BR><BR><FONT face=Arial>ContextMethod resides in wrapper.c. cm_init() 
  sets the stage for the failure which is subsequently realized in cm_dealloc(). 
  And here's where the questionable things come in.</FONT></FONT></DIV>
  <DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2>static int<BR>cm_init(PyObject *self, PyObject 
  *args, PyObject *kwds)<BR>{<BR>&nbsp;&nbsp;&nbsp; ContextMethod *cm = 
  (ContextMethod *)self;<BR>&nbsp;&nbsp;&nbsp; PyObject *callable;</FONT></DIV>
  <DIV><FONT face=Courier></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2>&nbsp;&nbsp;&nbsp; if (!PyArg_UnpackTuple(args, 
  "ContextMethod", 1, 1, 
  &amp;callable))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
  -1;<BR>&nbsp;&nbsp;&nbsp; if (!PyCallable_Check(callable)) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PyErr_Format(PyExc_TypeError, 
  "'%s' object is not 
  callable",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  callable-&gt;ob_type-&gt;tp_name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return -1;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; 
  Py_INCREF(callable);<BR>&nbsp;&nbsp;&nbsp; cm-&gt;cm_callable = 
  callable;<BR>&nbsp;&nbsp;&nbsp; return 0;<BR>}<BR></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>The&nbsp;ContextMethod(adebug) 
  call results in PyCallable_Check() returning 0, which leads to PyErr_Format() 
  and a return value of -1. The initialization of the resulting ContextMethod 
  object (bdebug) is incomplete and cm_dealloc() aborts when trying to handle 
  the debris.</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>Why does PyCallable_Check() 
  fail? Because the tp_call field is not set for ContextMethod object adebug. I 
  traced into PyCallable_Check() (which is in Python23's object.c file) and 
  found that the following line of code was exercised and returned 
  0.</FONT></FONT></DIV>
  <DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2>&nbsp;&nbsp;&nbsp; return 
  x-&gt;ob_type-&gt;tp_call != NULL;</FONT></DIV>
  <DIV><FONT face=Courier size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>So, back to the three 
  questions:</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>1) I don't see anything 
  Windows-specific here. The empty tp_call field should be happening on all 
  systems. However, it could be that cm_dealloc() survives the encounter with 
  bdebug on *NIX systems, where Windows is less forgiving. Purely conjecture, I 
  don't know for sure.</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>2 and 3) The abuse() method 
  does not (cannot??) check for a failure in ContextMethod(). I'm still new 
  enough to Python that I can't begin to suggest how the event should be 
  resolved. The real issue is how cm_dealloc() is invoked - does it happen when 
  cm_init() fails or when abuse() exits?</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>The situation really boils 
  down to this: I can't tell if the empty tp_call field is intentional or not. 
  That ContextMethod is a method seems to imply that it is callable and tp_call 
  should be set. At the same time, the wrapper unit tests have been running fine 
  for somebody which implies that ContextMethod is operating within normal 
  parameters.</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>I could really use some 
  insight at this point.</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial></FONT></FONT>&nbsp;</DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>Thanks,</FONT></FONT></DIV>
  <DIV><FONT face=Courier size=2><FONT face=Arial>Dave 
Harris</DIV></FONT></FONT>
  <P>
  <HR>

  <P></P>_______________________________________________<BR>Zope3-dev mailing 
  list<BR>Zope3-dev@zope.org<BR>http://mail.zope.org/mailman/listinfo/zope3-dev<BR></BLOCKQUOTE></BODY></HTML>