I had some time to debug. An explanation and a patch included.
Explanation:
in cpu.c in cpu_update() there is a loop with a condition:
i < (c->Wwg - BORDER_SIZE)
The SEGFAULT appears when a problem with GTK widget allocation occurs.
As the GTK documentation[1] states:
"gtk_widget_set_size_request () [...]
However in some strange cases a widget may be allocated less than its
requested size, and in many cases a widget may be allocated more space
than it requested."
I've got the "strange case" here, every time lxpanel starts just after
openbox.
'configure_event' is signalled a couple of times and sometimes the first
one occurs after allocation of 1x1px space, while the requested size is
40x20px.
When cpu_update() is allowed to execute with size 1x1 it goes into an
infinite loop because (c->Wwg - BORDER_SIZE) gets negative (1 - 2), but
is then compared to unsigned int. It has enough time to write
unallocated memory.
I thought that it would be simplest to just check if we have the
requested space before drawing.
[1]
http://library.gnome.org/devel/gtk/unstable/GtkWidget.html#gtk-widget-set-size-request
--
Marcin Szewczyk http://wodny.org
mailto:[email protected] <- remove b / usuĊ b
xmpp:[email protected] xmpp:[email protected]
--- lxpanel-patched/src/plugins/cpu/cpu.c 2009-09-15 12:54:35.000000000
+0200
+++ lxpanel-0.4.1+svn20090524/src/plugins/cpu/cpu.c 2008-11-14
15:49:11.000000000 +0100
@@ -36,8 +36,6 @@
#define KILOBYTE 1024
#define MAX_WGSIZE 100
-#define WWIDTH 40
-#define WHEIGHT 20
#define BORDER_SIZE 2
#include "dbg.h"
@@ -75,10 +73,6 @@
float total;
ENTER;
-
- if(c->Wwg < WWIDTH)
- RET(TRUE);
-
if(!c->pixmap)
RET(TRUE);
@@ -116,11 +110,6 @@
RET(TRUE);
}
-/* bugs.debian.org #535568:
- * sometimes configure_event is signalled before the widget's space
- * allocation has succeeded resulting in allocation.width and height
- * being less than requested (for example 1x1)
- */
static gint
configure_event(GtkWidget *widget, GdkEventConfigure *event, cpu_t *c)
{
@@ -186,7 +175,7 @@
GTK_WIDGET_SET_FLAGS( p->pwid, GTK_NO_WINDOW );
c->da = gtk_drawing_area_new();
- gtk_widget_set_size_request(c->da, WWIDTH, WHEIGHT);
+ gtk_widget_set_size_request(c->da, 40, 20);
gtk_widget_add_events( c->da, GDK_BUTTON_PRESS_MASK );
gtk_widget_show(c->da);