Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2002:
[Freeciv-Dev] Re: (PR#2534) civclient crash on FreeBSD 5.0
Home

[Freeciv-Dev] Re: (PR#2534) civclient crash on FreeBSD 5.0

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: mwlucas@xxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#2534) civclient crash on FreeBSD 5.0
From: "Raimar Falke via RT" <rt@xxxxxxxxxxxxxx>
Date: Thu, 12 Dec 2002 12:47:06 -0800
Reply-to: rt@xxxxxxxxxxxxxx

On Thu, Dec 12, 2002 at 05:17:53AM -0800, mwlucas@xxxxxxxxxxxxxxxxxxxx via RT 
wrote:
> On Thu, Dec 12, 2002 at 05:12:32AM -0800, Raimar Falke via RT wrote:
> > On Thu, Dec 12, 2002 at 04:49:12AM -0800, mwlucas@xxxxxxxxxxxxxxxxxxxx via 
> > RT wrote:
> > > Start the server with "civserver."
> > > 
> > > Start up "civclient" and connect.  Pick any nation.
> > > 
> > > Build your first city, and let it start building the first unit
> > > (warriors, phalanx, whatever.)
> > > 
> > > Play until that unit is complete.  Once that unit is built, fortify or
> > > sentry it within the city.
> > > 
> > > The next turn, activate that unit.  The client pauses for a long
> > > moment, then dumps core.
> > 
> > I can't reproduce this here.
> 
> I had rather assumed that this would have been caught pretty early by
> anyone who had actually played the game.  It may be because it's
> running on FreeBSD instead of Linux, perhaps?  (I don't know how large
> your FreeBSD userbase is.)

The reason can be a buggy compiler (we had such an issue, don't use a
CVS compiler), the OS, GTK or freeciv.

> > > #0  0x08091cb6 in popup_mes_close (dialog_shell=0x8444a00) at 
> > > dialogs.c:1428
> > > 1428        if (GTK_IS_WIDGET(parent)) {
> > 
> > Please post the output of
> >  info locals
> >  print parent
> >  print *parent
> 
> #0  0x08091cb6 in popup_mes_close (dialog_shell=0x8444a00) at dialogs.c:1428
> 1428      if (GTK_IS_WIDGET(parent)) {
> (gdb) info locals
> parent = (struct _GtkWidget *) 0x8429000
> close_callback = (void (*)(void *)) 0x8094b60 <dummy_close_callback>
> close_callback_data = (void *) 0x0
> buttons = (struct button_descr *) 0x8444980
> (gdb) print parent
> $1 = (struct _GtkWidget *) 0x8429000
> (gdb) print *parent
> $2 = {object = {klass = 0xd0d0d0d0, flags = 3503345872, 
>     ref_count = 3503345872, object_data = 0xd0d0d0d0}, private_flags = 53456, 
>   state = 208 '', saved_state = 208 '', 
>   name = 0xd0d0d0d0 <Address 0xd0d0d0d0 out of bounds>, style = 0xd0d0d0d0, 
>   requisition = {width = -12080, height = -12080}, allocation = {x = -12080, 
>     y = -12080, width = 53456, height = 53456}, window = 0xd0d0d0d0, 
>   parent = 0xd0d0d0d0}

#define GTK_IS_WIDGET(widget)                 (GTK_CHECK_TYPE ((widget), 
GTK_TYPE_WIDGET))
#define GTK_CHECK_TYPE(type_object, otype)       ( \
  ((GtkTypeObject*) (type_object)) != NULL && \
  GTK_CHECK_CLASS_TYPE (((GtkTypeObject*) (type_object))->klass, (otype)) \
)
#define GTK_CHECK_CLASS_TYPE(type_class, otype)  ( \
  ((GtkTypeClass*) (type_class)) != NULL && \
  gtk_type_is_a (((GtkTypeClass*) (type_class))->type, (otype)) \
)

So GTK_CHECK_CLASS_TYPE is called with parent->klass (0xd0d0d0d0) and
tried to derefence it later. This is bad since 0xd0d0d0d0 doesn't look
like a valid pointer. So we have a memory corruption problem
here. Also the other fields of parent got overwritten by 0xd0
(0xd0d0==53456).

I don't see code in freeciv which memset's a memory block to 0xd0.

Please try the attached diff.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "Life is too short for reboots."

Index: client/gui-gtk/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/dialogs.c,v
retrieving revision 1.115
diff -u -u -r1.115 dialogs.c
--- client/gui-gtk/dialogs.c    2002/12/01 22:49:24     1.115
+++ client/gui-gtk/dialogs.c    2002/12/12 20:46:08
@@ -51,6 +51,8 @@
 
 #include "dialogs.h"
 
+#define CHECK(x, msg) printf("%s: %s\n",msg,(((GtkTypeObject 
*)x)->klass==(void*)0xd0d0d0d0)?"BAD":"OK")
+
 /******************************************************************/
 static gint popup_mes_del_callback(GtkWidget *widget, GdkEvent *event,
                                   gpointer data);
@@ -1448,6 +1450,8 @@
   struct button_descr *buttons =
       gtk_object_get_data(GTK_OBJECT(dialog_shell), "buttons");
 
+  CHECK(parent, "popup_mes_close");
+
   if (GTK_IS_WIDGET(parent)) {
     /* 
      * It is possible that the user callback for a button may have
@@ -1473,7 +1477,6 @@
   void (*close_callback) (gpointer) =
       (void (*)(gpointer)) gtk_object_get_data(GTK_OBJECT(dialog_shell),
                                               "close_callback");
-
   if (close_callback) {
     popup_mes_close(dialog_shell);
     return FALSE;
@@ -1492,9 +1495,13 @@
        GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "button"));
   struct button_descr *buttons =
       gtk_object_get_data(GTK_OBJECT(dialog_shell), "buttons");
+  GtkWidget *parent =
+      gtk_object_get_data(GTK_OBJECT(dialog_shell), "parent");
 
+  CHECK(parent, "popup_mes_handle_callback #1");
   if (buttons[button].callback) {
     (*buttons[button].callback)(buttons[button].data);
+    CHECK(parent, "popup_mes_handle_callback #2");
   }
 
   popup_mes_close(dialog_shell);
@@ -1538,6 +1545,7 @@
   GtkAccelGroup *accel = gtk_accel_group_new();
   int i;
 
+  CHECK(parent, "base_popup_message_dialog");
   gtk_widget_set_sensitive(parent, FALSE);
   
   dshell=gtk_window_new(GTK_WINDOW_TOPLEVEL);

[Prev in Thread] Current Thread [Next in Thread]