Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2004:
[Freeciv-Dev] Re: (PR#8521) sha.c crashes
Home

[Freeciv-Dev] Re: (PR#8521) sha.c crashes

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#8521) sha.c crashes
From: "Raimar Falke" <i-freeciv-lists@xxxxxxxxxxxxx>
Date: Fri, 16 Apr 2004 11:11:31 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8521 >

On Thu, Apr 15, 2004 at 02:56:54PM -0700, Jason Short wrote:
> 
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=8521 >
> 
> When I play for any amount of time there's a segfault in sha.c. 
> Something like this:
> 
> #0  sha_unit_new (id=152) at sha.c:69
> 69      struct unit *pold_unit = 
> create_unit_virtual(get_player(punit->owner),(gdb) bt
> #0  sha_unit_new (id=152) at sha.c:69
> #1  0x08120c57 in execute_call (call=0x82d93d0) at agents.c:213
> #2  0x08120cee in call_handle_methods () at agents.c:251
> #3  0x08120d77 in thaw () at agents.c:287
> 
> Please fix.

Of course the unit doesn't have to exists anymore when sha_unit_new is
called.

I also added unit_clone and unit_destroy.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
  Tank: So what do you need? Besides a miracle.
  Neo: Guns. Lots of guns.
    -- From The Matrix

Index: client/agents/sha.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/agents/sha.c,v
retrieving revision 1.1
diff -u -u -r1.1 sha.c
--- client/agents/sha.c 14 Apr 2004 17:18:36 -0000      1.1
+++ client/agents/sha.c 16 Apr 2004 18:08:01 -0000
@@ -17,6 +17,7 @@
 
 #include "log.h"
 #include "map.h"
+#include "mem.h"
 #include "support.h"
 
 #include "agents.h"
@@ -49,43 +50,40 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static void sha_unit_change(int id)
+static void sha_unit_new(int id)
 {
   struct unit *punit = find_unit_by_id(id);
-  struct unit *pold_unit = unit_list_find(&previous_units, id);
-
-  freelog(LOG_DEBUG, "sha got unit: %d", id);
 
-  assert(pold_unit);
-  *pold_unit = *punit;
+  if (punit) {
+    unit_list_insert(&previous_units, unit_clone(punit));
+  }
 }
 
 /**************************************************************************
 ...
 **************************************************************************/
-static void sha_unit_new(int id)
+static void sha_unit_remove(int id)
 {
-  struct unit *punit = find_unit_by_id(id);
-  struct unit *pold_unit = create_unit_virtual(get_player(punit->owner),
-                                              NULL, 0, 0);
+  struct unit *punit = unit_list_find(&previous_units, id);;
 
-  freelog(LOG_DEBUG, "sha got unit: %d", id);
+  assert(punit != NULL);
 
-  *pold_unit = *punit;
-  unit_list_insert(&previous_units, pold_unit);
+  unit_list_unlink(&previous_units, punit);
+
+  unit_destroy(punit);
 }
 
 /**************************************************************************
 ...
 **************************************************************************/
-static void sha_unit_remove(int id)
+static void sha_unit_change(int id)
 {
-  struct unit *pold_unit = unit_list_find(&previous_units, id);;
-
-  freelog(LOG_DEBUG, "sha got unit: %d", id);
+  struct unit *punit = find_unit_by_id(id);
 
-  assert(pold_unit);
-  unit_list_unlink(&previous_units, pold_unit);
+  if (punit) {
+    sha_unit_remove(id);
+    sha_unit_new(id);
+  }
 }
 
 /**************************************************************************
@@ -95,7 +93,8 @@
 {
   struct agent self;
 
-  previous_tiles = fc_malloc(MAX_MAP_INDEX * sizeof(*previous_tiles));
+  previous_tiles =
+      fc_realloc(previous_tiles, MAX_MAP_INDEX * sizeof(*previous_tiles));
   memset(previous_tiles, 0, MAX_MAP_INDEX * sizeof(*previous_tiles));
 
   unit_list_init(&previous_units);
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.203
diff -u -u -r1.203 unit.c
--- common/unit.c       14 Apr 2004 11:19:45 -0000      1.203
+++ common/unit.c       16 Apr 2004 18:08:03 -0000
@@ -1822,3 +1822,28 @@
 
   return result;
 }
+
+/**************************************************************************
+  Returns a deep clone of the given unit.
+**************************************************************************/
+struct unit *unit_clone(struct unit *punit)
+{
+  struct unit *result = fc_malloc(sizeof(*result));
+
+  *result = *punit;
+
+  if (result->has_orders) {
+    size_t size = result->orders.length * sizeof(*(result->orders.list));
+    result->orders.list = fc_malloc(size);
+    memcpy(result->orders.list, punit->orders.list, size);
+  }
+  return result;
+}
+
+/**************************************************************************
+  Frees any resoures allocated by unit_clone.
+**************************************************************************/
+void unit_destroy(struct unit *punit)
+{
+  destroy_unit_virtual(punit);
+}
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.114
diff -u -u -r1.114 unit.h
--- common/unit.h       14 Apr 2004 11:19:45 -0000      1.114
+++ common/unit.h       16 Apr 2004 18:08:03 -0000
@@ -325,6 +325,8 @@
                                  Unit_Type_id type, int veteran_level);
 void destroy_unit_virtual(struct unit *punit);
 void free_unit_orders(struct unit *punit);
+struct unit *unit_clone(struct unit *punit);
+void unit_destroy(struct unit *punit);
 
 int get_transporter_occupancy(struct unit *ptrans);
 struct unit *find_transporter_for_unit(struct unit *pcargo, int x, int y);

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