Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2001:
[Freeciv-Dev] Re: Client core (PR#1107)
Home

[Freeciv-Dev] Re: Client core (PR#1107)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: Client core (PR#1107)
From: jdorje@xxxxxxxxxxxxxxxxxxxxx
Date: Sat, 8 Dec 2001 19:20:40 -0800 (PST)

Paul Zastoupil wrote:

I was trying to hit 't' on s city.

civclient: map.c:1217: map_get_city: Assertion `is_normal_map_pos(((x)),((y)))' 
failed.

#0  0x403278d1 in __kill () from /lib/libc.so.6
#1  0x4032764d in raise (sig=6) at ../sysdeps/posix/raise.c:27
#2  0x40328cb8 in abort () at ../sysdeps/generic/abort.c:88
#3 0x40320d71 in __assert_fail (assertion=0x80c3900 "is_normal_map_pos(((x)),((y)))", file=0x80c4564 "map.c", line=1217, function=0x80c475b "map_get_city") at assert.c:74
#4  0x080a8521 in map_get_city (x=-1, y=30) at map.c:1217
#5  0x0808c7a5 in find_city_near_tile (x=0, y=32) at mapctrl.c:361
#6  0x0808cab0 in key_city_workers (widget=0x81a24a0, ev=0x8198688) at 
mapctrl.c:461
#7  0x08085a92 in keyboard_handler (widget=0x81a24a0, event=0x8198688) at 
gui_main.c:303
#8 0x400db841 in gtk_marshal_BOOL__POINTER (object=0x81a24a0, func=0x808545c <keyboard_handler>, func_data=0x0, args=0xbffff610) at gtkmarshal.c:28 #9 0x4010b0be in gtk_handlers_run (handlers=0x81fd078, signal=0xbffff5b0, object=0x81a24a0, params=0xbffff610, after=0) at gtksignal.c:1917 #10 0x4010a51f in gtk_signal_real_emit (object=0x81a24a0, signal_id=26, params=0xbffff610) at gtksignal.c:1477
#11 0x40108594 in gtk_signal_emit (object=0x81a24a0, signal_id=26) at 
gtksignal.c:552
#12 0x4013f874 in gtk_widget_event (widget=0x81a24a0, event=0x8198688)
    at gtkwidget.c:2864
#13 0x400db73c in gtk_propagate_event (widget=0x81f99b8, event=0x8198688)
    at gtkmain.c:1360
#14 0x400da975 in gtk_main_do_event (event=0x8198688) at gtkmain.c:818
#15 0x4018e10f in gdk_event_dispatch (source_data=0x0, current_time=0xbffff9e0, user_data=0x0) at gdkevents.c:2139
#16 0x401bd055 in g_main_dispatch (dispatch_time=0xbffff9e0) at gmain.c:656
#17 0x401bd659 in g_main_iterate (block=1, dispatch=1) at gmain.c:877
#18 0x401bd7e8 in g_main_run (loop=0x8213b00) at gmain.c:935
#19 0x400da27b in gtk_main () at gtkmain.c:524
#20 0x0808728e in ui_main (argc=3, argv=0xbffffb24) at gui_main.c:836
#21 0x0805f178 in main (argc=3, argv=0xbffffb24) at civclient.c:189
#22 0x40315306 in __libc_start_main (main=0x805ed20 <main>, argc=3, ubp_av=0xbffffb24, init=0x805c680 <_init>, fini=0x80b9580 <_fini>, rtld_fini=0x4000d2cc <_dl_fini>, stack_end=0xbffffb1c) at ../sysdeps/generic/libc-start.c:129

When you click on a tile like that, the game tries to associate a city with it, so it calls find_city_near_tile. Unfortunately, find_city_near_tile is not CHECK_MAP_POS-safe, so it'll fail the assertion any time a wrap-around is needed to find the city (i.e. any time you're working near x==0 or x==map.xsize-1).

This is easy enough to fix. But, it's more complicated because each of gui-gtk, gui-xaw, and gui-mui uses its own local (static) version of the function; this code is not common. However, nothing in the code is gui-specific, and in fact all three versions of the code are completely identical. (I'm not sure what gui-win32 does for this...maybe it's not implemented yet.)

I therefore propose that this code be unified into find_city_near_tile() in mapctrl_common.[ch] in client/. A patch for this will follow.

Attached is a preleminary patch for this that should fix the segfault if you're playing under GTK. Please test if possible.

jason
? old
? topology
Index: client/gui-gtk/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.c,v
retrieving revision 1.50
diff -u -r1.50 mapctrl.c
--- client/gui-gtk/mapctrl.c    2001/12/08 15:15:51     1.50
+++ client/gui-gtk/mapctrl.c    2001/12/09 03:18:10
@@ -358,7 +358,10 @@
 
   pcity2 = NULL;
   city_map_iterate(i, j)  {
-    pcity = map_get_city(x+i-2, y+j-2);
+    int map_x, map_y;
+    if (!base_city_map_to_map(&map_x, &map_y, x, y, i, j))
+      continue;
+    pcity = map_get_city(map_x, map_y);
     if(pcity && pcity->owner==game.player_idx && 
        get_worker_city(pcity,4-i,4-j)==C_TILE_EMPTY)  {  /* rule b */
       if(pcity==last_pcity) return pcity;  /* rule c */

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