Re: [Sawfish] periodic segfault

[ Thread Index | Date Index | More lists.tuxfamily.org/sawfish Archives ]


On 2012-02-23 Teika Kazura wrote:
> Hi. This looks very annoying. How can it happen?
> Let's see the function. It's simple.
> 
> ------------------------------------------------------------------------
> void
> refresh_frame_part (struct frame_part *fp)
> {
>     if (!frame_draw_mutex)
>     {
> 	Lisp_Window *w = fp->win;
> 	if (w == 0)			/* XXX why is this needed?
> */ return;
> 
> 	if (fp->drawn.width != fp->width || fp->drawn.height !=
> fp->height) fp->drawn.bg = rep_NULL;
> 
> 	if (!WINDOW_IS_GONE_P (w) && fp->id != 0) /* It happened
> here */ set_frame_part_bg (fp);
> 	if (!WINDOW_IS_GONE_P (w) && fp->id != 0)
> 	    set_frame_part_fg (fp);
> 
> 	fp->drawn.width = fp->width;
> 	fp->drawn.height = fp->height;
> 	fp->pending_refresh = 0;
>     }
>     else
> 	fp->pending_refresh = 1;
> }
> ------------------------------------------------------------------------
> 
> In X, each frame components (top, bottom, buttons, etc) are drawed in
> a separate window, and there exists a window which contains all of the
> client (= application) window and the frame components. (Such kind of
> window managers are called "reparenting WMs".) refresh_frame_part() is
> a function to redraw a frame part (= a frame component).
> 
> fp->win is the window associated with the concerned frame part,
> represented as a librep lisp object. ** And the check follows if it's
> not NULL. **
> 
> It seems WINDOW_IS_GONE_P segfaults, but it's defined in sawfish.h as:
>   #define WINDOW_IS_GONE_P(w) (w->id == 0)
> 
> But w is not NULL! I'm lost here.

Is this stuff multi-threaded or re-entrant?  Can X null out fp or
fp->win between checks and later stuff (race condition)?  Maybe that's
why the lame exact same double-test is done calling WINDOW_IS_GONE_P
twice instead of doing 1 test and putting 2 statements in {}?

Also, I'm not a good C programmer, but by chance does
if (!WINDOW_IS_GONE_P (w) && fp->id != 0)
expand to:
#1  if (!w->id == 0 && fp->id != 0)
or:
#2  if (!(w->id == 0) && fp->id != 0)
??

If #1, then isn't that the problem, buggy test giving exact opposite
result?


I am pretty sure this time I know what I was doing.  It crashed right
as I was trying to move the window by dragging title bar.  Perhaps also
I had just launched the window (firefox I think).  I work very fast and
the window may not have been done drawing when I clicked to drag it.
The system might have been moderately loaded at the time and there
could have been some lag between start of draw and finish.  Could
catching these routines at the wrong point (race condition) cause some
problem?

I had thought it was due to excessive window creation, but I wrote a
program to launch/exit an xterm window thousands of times in minutes
and that didn't seem to cause any speed up of the segfault.  Perhaps
it's more related to me using a loaded system with my fast mousing.

Thanks for the help!

-- 
--
Sawfish ML


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/