I'm a little confused - you said you get a "segmentation error", and you
mentioned running a debugger, but you are showing a python error. So do you
get a real segmentation fault? Like bad memory access that drops out of
python and all that? If so, you haven't captured that error in the right
kind of debugger for seg faults (gdb) yet.

Assuming you are getting a seg fault, then that sucks.  If it were me in
that case, I'd probably see if I can set up some system to force the error
to happen. Like say make the game run through the conditions that you see
the error in now, and make it run over night - or maybe set up some kind of
automation to record and playback some play, and again, run it all night.

The reason getting a stable reproducing case is so important, is then you
can binary search this. Like disable all blitting, or turn off the music,
etc.

As far as the python stack trace goes, if you are getting a seg fault, then
the weirdness of the python stack makes it seem likely that memory
corruption happened between the event.pos and event.button lines, as you
pointed out. Is this python stack reproducible? Have you seen it multiple
times? If so, then it seems like it could be code that executes
synchronously between those 2 lines, in which case tossing a ton of asserts
or "temp = event.button" lines in the mouse_button_up would help you narrow
down the lines that trigger things next time this in-python exception
triggers? If on the other hand you haven't seen it before/can't reporoduce
it, it may just be a red herring, and the corruption could be happening
asynchronously in some other thread - maybe it could be the music?

So what OS and versions of stuff you using when you get the error? Have you
been able to try the code on other platforms? Any other libraries besides
pygame used with this program? Any idea when exactly it started occurring in
relation to your code? Any code of yours that seems like something that
could be causing the problem (like your own c compiled extensions)? I don't
suppose you are blitting a surface to itself anywhere and using Linux?


On Wed, Sep 16, 2009 at 11:36 AM, Bo Jangeborg <[email protected]> wrote:

> I have seen a troubling error for some time now.
> Occasionally I get a segmentation error with no indication of what
> went wrong. The error is not repeatable in a reliable way and I get
> no error trace. Repeating the error can take hours.
>
> After seeing this I have tried to pin down, with the debugger running,
> what's going wrong but the nearest I can get is that the event object
> gets turned into a long at different times.
>
> Running with a debugger I got this trace. I have included the calling
> line were you can see that the event seem to be correct, but at some
> point the event object seem to become corrupted.
> Included is also the code between the call and the eventual point
> of error. I am at loss at what may be going wrong.
>
> Bo)
>
> Traceback (most recent call last):
>  File "C:\Program
> Files\eclipse\plugins\org.python.pydev.debug_1.4.7.2843\pysrc\pydevd.py",
> line 881, in <module>
>   debugger.run(setup['file'], None, None)
>  File "C:\Program
> Files\eclipse\plugins\org.python.pydev.debug_1.4.7.2843\pysrc\pydevd.py",
> line 710, in run
>   execfile(file, globals, locals) #execute the script
>  File "C:\Projekt\eclipse\Pyos\Program\Solitaire\solitaire.py", line 761,
> in <module>
>   main()
>  File "C:\Projekt\eclipse\Pyos\Program\Solitaire\solitaire.py", line 80, in
> main
>   if screen.main_loop(app):
>  File "C:\Projekt\eclipse\Pyos\System\widgets\gui.py", line 328, in
> main_loop
>   = self.mouse_button_up(event, mob_pos, mousemove)
>  File "C:\Projekt\eclipse\Pyos\System\widgets\gui.py", line 573, in
> mouse_button_up
>   if event.button == 1:
> AttributeError: 'long' object has no attribute 'button'
>
>
> elif event.type is MOUSEBUTTONUP:
>    mob_pos, mousemove, mouse_pos, hit_pos \
>                = self.mouse_button_up(event, mob_pos, mousemove)
>
>
>
>   def mouse_button_up(self, event, mob_pos, mousemove):
>       ''' handle mouse button up events'''
>       mousebtn_event = False
>       mouse_pos = event.pos
>       widget, hit_pos = self.mouse_hit_widget(mouse_pos[0],
>                                           mouse_pos[1])
>       if widget is None or not widget.enabled:
>           self.moving_object = None
>           self.repeating_object = None
>           self.last_over_drop_widget = None
>       else:
>           event_data = {'hit_pos':hit_pos, 'over_widget':widget}
>           event_data['gui'] = self
>           if widget and widget.exists('event_click_release_data'):
>               event_data.update(widget.event_click_release_data)
>           #InsideButton  (Left)
>           if event.button == 1:
>
>
>
>   def mouse_hit_widget(self, hit_pos_x, hit_pos_y, draged_widget=None,
>                       dropreciever=False, mouse_down=False,
> mouse_over=False):
>       ''' Return the first valid widget under the mouse pointer'''
>       widget_hit, hit_pos = _mouse_hit_widget(self, hit_pos_x, hit_pos_y,
>                                                draged_widget, dropreciever)
>       if not widget_hit is None:
>           modal_lock = widget_hit.app.get_modal()
>           if modal_lock:
>               if modal_lock.close_on_focuschange\
>               and not (modal_lock in widget_hit.get_actionpath())\
>               and mouse_down:
>                   #Close the modal widget if something else
>                   # is being clicked. Popups, such as menues f.ex,
>                   #  would have this behaviour.
>                   event_data = {'mouse_over':widget_hit,
>                                 'close_on_focuschange':True}
>                   modal_lock.event_close(event_data)
>               elif not (widget_hit is modal_lock) \
>               and not (mouse_over and modal_lock.close_on_focuschange):
>                   if not (modal_lock in widget_hit.get_actionpath()):
>                       widget_hit = None
>       return widget_hit, hit_pos
>
>
> def _mouse_hit_widget(wid, hit_pos_x, hit_pos_y, draged_widget=None,
>                     dropreciever=False):
>   ''' Loop until a valid widget is under the mouse pointer'''
>   hit_pos_x -= wid.rect.left
>   hit_pos_y -= wid.rect.top
>   widget_hit = None
>   hit_pos = False
>   for widget in wid.widgets[::-1]:
>       if widget.rect.top <= hit_pos_y \
>       and widget.rect.bottom > hit_pos_y \
>       and widget.rect.left <= hit_pos_x \
>       and widget.rect.right > hit_pos_x\
>       and widget.visible \
>       and widget.visible_to_hit \
>       and widget != draged_widget:
>           if widget.widgets:
>               widget_hit, hit_pos = _mouse_hit_widget(widget, hit_pos_x,
>                                                   hit_pos_y, draged_widget,
>                                                   dropreciever)
>               if widget_hit:
>                   break
>           if dropreciever:
>               if not hasattr(widget, 'dropreciever')\
>               or widget.dropreciever != True:
>                   continue
>           if widget.image and not type(widget.image) == type(True):
>               _image_offset = (hit_pos_x - widget.rect.left,
>                                 hit_pos_y - widget.rect.top)
>               if widget.flags & PIXELALPHA:
>                   if widget.image.get_at(_image_offset)[3] != 0:
>                       if not widget.image.get_colorkey() is None:
>                           if widget.image.get_at(_image_offset) !=\
>                           widget.image.get_colorkey():
>                               widget_hit = widget
>                       else:
>                           widget_hit = widget
>                       if widget_hit and hasattr(widget, 'on_hit_image'):
>                           widget_hit = widget.on_hit_image(_image_offset)
>               elif not widget.image.get_colorkey() is None:
>                   if widget.image.get_at(_image_offset) !=\
>                   widget.image.get_colorkey():
>                       widget_hit = widget
>               else:
>                   widget_hit = widget
>           else:
>               if hasattr(widget, 'paper'):
>                   widget_hit = widget
>           if widget_hit:
>               hit_pos = (hit_pos_x - widget_hit.rect.left,
>                           hit_pos_y - widget_hit.rect.top)
>               break
>   if not widget_hit and isinstance(wid, Gui):
>       widget_hit = wid
>       hit_pos = (hit_pos_x, hit_pos_y)
>   return widget_hit, hit_pos
>
>
>

Reply via email to