[Tutor] Strange IndexError

Willi Richert w.richert at gmx.net
Mon Jun 13 23:44:16 CEST 2005


Hi,

I used the same Pyro code, but this time with the release versions of player 
and stage. This time python crashed with a segfault:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1273599056 (LWP 27633)]
tupleiter_next (it=0xb6393cec) at Objects/tupleobject.c:797
797                     Py_INCREF(item);
(gdb) bt
#0  tupleiter_next (it=0xb6393cec) at Objects/tupleobject.c:797
#1  0x00ada39f in PyIter_Next (iter=0x9) at Objects/abstract.c:2225
#2  0x00b2d6f0 in eval_frame (f=0x815840c) at Python/ceval.c:2091
#3  0x00b3197b in eval_frame (f=0x814dcdc) at Python/ceval.c:3518
#4  0x00b3197b in eval_frame (f=0x815665c) at Python/ceval.c:3518
#5  0x00b3197b in eval_frame (f=0x81561e4) at Python/ceval.c:3518
#6  0x00b3209e in PyEval_EvalCodeEx (co=0xb7c0a4a0, globals=0x9, locals=0x0, 
args=0xb637e218, argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, 
closure=0x0)
    at Python/ceval.c:2663
#7  0x00aede2e in function_call (func=0xb7c03d84, arg=0xb637e20c, kw=0x0) at 
Objects/funcobject.c:504
#8  0x00ada607 in PyObject_Call (func=0xb0b4f1, arg=0x0, kw=0x0) at 
Objects/abstract.c:1755
#9  0x00ae1d98 in instancemethod_call (func=0xb7c03d84, arg=0xb637e20c, 
kw=0x0) at Objects/classobject.c:2433
#10 0x00ada607 in PyObject_Call (func=0xb0b4f1, arg=0x0, kw=0x0) at 
Objects/abstract.c:1755
#11 0x00b2fb7f in eval_frame (f=0x811bbc4) at Python/ceval.c:3644
#12 0x00b3197b in eval_frame (f=0x8079b34) at Python/ceval.c:3518
#13 0x00b3197b in eval_frame (f=0x80fda8c) at Python/ceval.c:3518
#14 0x00b3209e in PyEval_EvalCodeEx (co=0xb7cdf220, globals=0x9, locals=0x0, 
args=0xb7bffb98, argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, 
closure=0x0)
    at Python/ceval.c:2663
#15 0x00aede2e in function_call (func=0xb7ceca3c, arg=0xb7bffb8c, kw=0x0) at 
Objects/funcobject.c:504
#16 0x00ada607 in PyObject_Call (func=0xb0b4f1, arg=0x0, kw=0x0) at 
Objects/abstract.c:1755
#17 0x00ae1d98 in instancemethod_call (func=0xb7ceca3c, arg=0xb7bffb8c, 
kw=0x0) at Objects/classobject.c:2433
#18 0x00ada607 in PyObject_Call (func=0xb0b4f1, arg=0x0, kw=0x0) at 
Objects/abstract.c:1755
#19 0x00b2c1b0 in PyEval_CallObjectWithKeywords (func=0x0, arg=0xb7fa202c, 
kw=0x0) at Python/ceval.c:3346
#20 0x00b54072 in t_bootstrap (boot_raw=0x8119840) 
at ./Modules/threadmodule.c:180
#21 0x00baa341 in start_thread () from /lib/tls/libpthread.so.0
#22 0x00a29fee in clone () from /lib/tls/libc.so.6


Is this Python-related or some other application's problem?

wr
Am Donnerstag, 2. Juni 2005 21:00 schrieb Danny Yoo:
> On Thu, 2 Jun 2005, Willi Richert wrote:
> > my app is a Pyrobot (http://emergent.brynmawr.edu/~dblank/pyro/)
> > simulation which connects to PlayerStage (playerstage.sf.net)  to
> > simulate three Pioneer robots. These are controlled using NeedBrain.py.
> > In parallel to the three NeedBrains there is one MonitorBrain running
> > for some management tasks, so I have
> >  four parallel running classes.
>
> Hi Willi,
>
> I think you may want to bring this up on comp.lang.python: I have a strong
> feeling I'm in over my head.  *grin* The experts on comp.lang.python
> should be able to better pinpoint the exact problem.
>
>
> The code that prints that peculiar error message is at the very core of
> Python's object implementation in doing object equality checking:
>
> /*** Objects/object.c, about line 441 in Python 2.4 source ***/
> /* Helper to warn about deprecated tp_compare return values.  Return:
>    -2 for an exception;
>    -1 if v <  w;
>     0 if v == w;
>     1 if v  > w.
>    (This function cannot return 2.)
> */
> static int
> adjust_tp_compare(int c)
> {
> 	if (PyErr_Occurred()) {
> 		if (c != -1 && c != -2) {
> 			PyObject *t, *v, *tb;
> 			PyErr_Fetch(&t, &v, &tb);
> 			if (PyErr_Warn(PyExc_RuntimeWarning,
> 				       "tp_compare didn't return -1 or -2 "
> 				       "for exception") < 0) {
> 				Py_XDECREF(t);
> 				Py_XDECREF(v);
> 				Py_XDECREF(tb);
> 			}
> 			else
> 				PyErr_Restore(t, v, tb);
> /******/
>
>
> We can reason that PyErr_Occurred() somehow returned true, and that the
> error information is being captured in C code throught the 't', 'v' and
> 'tb' variables.  Those three variables are ultimately responsible for
> what's printing out:
>
>     IndexError: tuple assignment index out of range
>
> and the output that talks about 'tp_compare' shows up because of the
> PyErr_Warn call.  That explains why we see both error messages.
>
>
>
> I'm staring at the code a little more; there's a bit of code around line
> 229 that bothers me a bit:
>
> ######
>         try:
>             self._markerObject = self.get("robot/fiducial/id")(self.marker)
>         finally:
>             if not self._markerObject:
>                 self._markerDist = 1000.0
>             else:
>                 self._markerDist = self._markerObject.range
> ######
>
> My hypothesis now is that the equality check against the type of
> self._markerDist is raising an error, which would require self._markerDist
> to be something unusual.  I know, I'm reaching, but let me see how far
> this goes.  *grin*
>
> I don't see anything else that assigns to self._markerDist in any other
> part of the code.  In the code above, I see in the 'else' block that
> self._markerDist is being assigned to 'self._markerObject.range'.  What
> type is 'self._markerObject', and what type is 'self._markerObject.range?
> Do you mind adding some code to print those out?
>
>
>
>
> I can't assume that 'range' is a number, since 'range' is being used in
> all sorts of contexts, especially in the pyro source code.  For example,
> pyro.PyroHierarchy has the following comment:
>
> ######
> class PyroHierarchy (object):
>     """
>     A wrapper class for the pyro devices hierarchy.
>     An instance of this class represents a node of the hierarchy,
>     with an attribute for every subnode.
>     Getting an attribute is equivalent to using robot.get .
>     Setting an attribute is equivalent to using robot.set .
>     Numeric nodes can be accessed as list elements.
>
>     Examples of use:
>       h.robot.range.all               # returns another PyroHierarchy
> object
>       h.robot.range.name              # return a string
>       h.robot.range.all.value         # return a list of numbers
>       h.robot.range[1].value          # returns a number
>       h.robot.range[1:4]              # returns a list of PyroHierarchy
> objects
>       h.devices.gripper.command = "open" # issues command "open" to
> gripper0
>     """
> ######
>
>
> so I strongly suspect that this 'range' object is something much richer
> than a float.
>
>
>
> Something like:
>
>      print self._markerDist, type(self._markerDist)
>
> might help us see what's going on better.
>
>
> Best of wishes to you!
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor


More information about the Tutor mailing list