Follow-up Comment #3, bug #21384 (project freeciv):
> And from backtrace:
>> timer_callback()
...although I think I have seen a backtrace that doesn't involve that (I don't
have it to hand now, but see below).
Reducing the focus circle update time in get_focus_unit_toggle_timeout() from
0.1 to 0.02 seemed to make this more reproducible, to the point where I got a
plausibly-related symptom under valgrind:
==18983== Invalid read of size 8
==18983== at 0x5B3669: player_number (player.c:730)
==18983== by 0x4B56E8: fill_grid_sprite_array.isra.17 (tilespec.c:4371)
==18983== by 0x4B7175: fill_sprite_array (tilespec.c:4792)
==18983== by 0x48B9A5: put_one_element (mapview_common.c:957)
==18983== by 0x48F37B: update_map_canvas (mapview_common.c:1347)
==18983== by 0x49041A: unqueue_mapview_updates (mapview_common.c:2599)
==18983== by 0x4762C7: blink_active_unit (control.c:723)
==18983== by 0x46F53A: real_timer_callback (client_main.c:1002)
==18983== by 0x445858: timer_callback (gui_main.c:264)
==18983== by 0x5BA98DA: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.4)
==18983== by 0x5BA8D12: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.4)
==18983== by 0x5BA905F: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.4)
==18983== Address 0x143408d0 is 0 bytes inside a block of size 2,984 free'd
==18983== at 0x4C2A82E: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18983== by 0x5B4457: player_destroy (player.c:700)
==18983== by 0x4978E8: handle_player_remove (packhand.c:1893)
==18983== by 0x49D245: client_handle_packet (packhand_gen.c:124)
==18983== by 0x46E45D: client_packet_input (client_main.c:654)
==18983== by 0x474C84: input_from_server (clinet.c:421)
==18983== by 0x44583F: get_net_input (gui_main.c:1882)
==18983== by 0x5BA8D12: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.4)
==18983== by 0x5BA905F: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.4)
==18983== by 0x5BA9459: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.4)
==18983== by 0x65CE2F6: gtk_main (in
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
==18983== by 0x4487C8: ui_main (gui_main.c:1673)
==18983==
1: in fill_grid_sprite_array() [tilespec.c::4373]: assertion
't->sprites.player[plrid].grid_borders [pedge->type][1] != NULL' failed.
2: Backtrace:
2: 0: client/freeciv-gtk2() [0x5c9f3b]
2: 1: client/freeciv-gtk2(vdo_log+0x9b) [0x5ceceb]
2: 2: client/freeciv-gtk2(do_log+0x7d) [0x5cedbd]
2: 3: client/freeciv-gtk2(fc_assert_fail+0x9f) [0x5cefef]
2: 4: client/freeciv-gtk2() [0x4b5ca5]
2: 5: client/freeciv-gtk2(fill_sprite_array+0x3f6) [0x4b7176]
2: 6: client/freeciv-gtk2(put_one_element+0x56) [0x48b9a6]
2: 7: client/freeciv-gtk2(update_map_canvas+0x4fc) [0x48f37c]
2: 8: client/freeciv-gtk2(unqueue_mapview_updates+0x3db) [0x49041b]
2: 9: client/freeciv-gtk2(blink_active_unit+0xb8) [0x4762c8]
2: 10: client/freeciv-gtk2(real_timer_callback+0x5b) [0x46f53b]
2: 11: client/freeciv-gtk2() [0x445859]
2: 12: /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x488db) [0x5ba98db]
2: 13:
/lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x133)
[0x5ba8d13]
2: 14: /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x48060) [0x5ba9060]
2: 15: /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_loop_run+0x6a)
[0x5ba945a]
2: 16: /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(gtk_main+0xa7)
[0x65ce2f7]
2: 17: client/freeciv-gtk2(ui_main+0x549) [0x4487c9]
2: 18: client/freeciv-gtk2(client_main+0x306) [0x46ea66]
2: 19: /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x745f76d]
2: 20: client/freeciv-gtk2() [0x445551]
...
...followed by more similar messages. Which I think confirms that it's due to
player destruction.
I'm guessing that the problem is that knowledge of a removed player can
continue indefinitely in other players' private maps. player_map_free() on the
server (oddly) removes knowledge of the removed player's cities from other
players (although I'm not sure it pushes this information to clients), but I
don't see anything to clear down tile owners (possibly this was missed when
foggedborders was added in patch #1258).
And indeed, a more targeted test where I "/remove" a player does cause the
client of another player to crash sooner or later. Here's a crash not
involving a timer:
#0 0x00000000004b56a4 in fill_grid_sprite_array (t=0x15bb2a0,
sprs=0x7fff43fd86c0, ptile=<optimised out>, pedge=0x7fff43fd8f10,
citymode=0x0, pcorner=<optimised out>, punit=<optimised out>, pcity=<optimised
out>) at tilespec.c:4367
plrid = <optimised out>
owner0 = <optimised out>
owner1 = 0x0
known = {true, true}
unit = {false, false}
worked = {false, false}
pfocus_units = 0x440d640
city = {false, false}
saved_sprs = 0x7fff43fd86c0
#1 0x00000000004b7176 in fill_sprite_array (t=<optimised out>,
sprs=0x7fff43fd86c0, layer=LAYER_GRID1, ptile=0x0, pedge=0x7fff43fd8f10,
pcorner=0x0, punit=0x0, pcity=0x0, citymode=0x0, putype=0x0) at
tilespec.c:4792
tileno = <optimised out>
tspecial_near = {{vec = "\000"}, {vec = "\000"}, {vec = "\000"}, {vec
= "\005\b"}, {vec = "\000"}, {vec = "\000"}, {vec = "\000"}, {vec = "\000"}}
tspecial = {vec = "\000"}
tterrain_near = {0x9d23c8, 0x9d1d28, 0x9d1d28, 0x9d23c8, 0x9d1d28,
0x9d1d28, 0x9d1d28, 0x9d1d28}
pterrain = 0x0
save_sprs = 0x7fff43fd86c0
owner = 0x0
do_draw_unit = false
solid_bg = false
__FUNCTION__ = "fill_sprite_array"
#2 0x000000000048b9a6 in put_one_element (pcanvas=0x1821180, layer=<optimised
out>, ptile=0x0, pedge=<optimised out>, pcorner=<optimised out>,
punit=<optimised out>, pcity=0x0, canvas_x=3, canvas_y=-31, citymode=0x0,
putype=0x0) at mapview_common.c:957
tile_sprs = {{foggable = false, sprite = 0x465fed0, offset_x = 0,
offset_y = 0}, {foggable = false, sprite = 0x64a3dc0, offset_x = 0, offset_y =
0}, {foggable = false, sprite = 0x1752310, offset_x = 0, offset_y = 0},
{foggable = false, sprite = 0x1752390, offset_x = 0, offset_y = 0}, {foggable
= false, sprite = 0x17522d0, offset_x = 0, offset_y = 0}, {foggable = false,
sprite = 0x1752350, offset_x = 0, offset_y = 0}, {foggable = false, sprite =
0x1752310, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x1752390,
offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x0, offset_x = 0,
offset_y = 0}, {foggable = false, sprite = 0x0, offset_x = 0, offset_y = 0},
{foggable = false, sprite = 0x0, offset_x = 0, offset_y = 0}, {foggable =
false, sprite = 0x0, offset_x = -391152093, offset_y = 32674}, {foggable =
false, sprite = 0x7fa200000001, offset_x = 101, offset_y = 0}, {foggable =
160, sprite = 0x16e7ea0, offset_x = 1140689424, offset_y = 32767}, {foggable =
40, sprite = 0x7fa2e8b435e1, offset_x = 24018592, offset_y = 0}, {foggable =
242, sprite = 0x0, offset_x = -417751776, offset_y = 32674}, {foggable = 4,
sprite = 0x27900000090, offset_x = 1, offset_y = 32674}, {foggable = false,
sprite = 0x80, offset_x = 142177184, offset_y = 0}, {foggable = 144, sprite =
0x7fa2e719b6fe, offset_x = 1140689344, offset_y = 32767}, {foggable = false,
sprite = 0x848a800, offset_x = 141446096, offset_y = 0}, {foggable = 224,
sprite = 0x3dc, offset_x = 997, offset_y = 0}, {foggable = 247, sprite =
0x1c33300, offset_x = 128, offset_y = 0}, {foggable = 240, sprite =
0x7fa2e7bc2988, offset_x = 141446112, offset_y = 0}, {foggable = 149, sprite =
0x848a820, offset_x = 29569816, offset_y = 0}, {foggable = false, sprite =
0x848a820, offset_x = 141446112, offset_y = 0}, {foggable = 220, sprite =
0x848a820, offset_x = 141446112, offset_y = 0}, {foggable = 220, sprite =
0x7fa2e7bc3305, offset_x = 997, offset_y = 0}, {foggable = 5, sprite =
0x86e4bd0, offset_x = 997, offset_y = 32674}, {foggable = true, sprite =
0x1c33300, offset_x = 36659488, offset_y = 3}, {foggable = 176, sprite =
0x1c2e750, offset_x = 1, offset_y = 0}, {foggable = 40, sprite =
0x7fa2e8b43979, offset_x = 29550440, offset_y = 0}, {foggable = 236, sprite =
0x1c2e750, offset_x = 29550416, offset_y = 0}, {foggable = 128, sprite =
0x16fdd80, offset_x = 24106112, offset_y = 0}, {foggable = false, sprite =
0x7fa2e808fe10, offset_x = 1, offset_y = 0}, {foggable = false, sprite =
0x7fff43fd8b30, offset_x = 24208896, offset_y = 0}, {foggable = 240, sprite =
0x1, offset_x = -414182894, offset_y = 32674}, {foggable = 80, sprite =
0x3000000018, offset_x = 1140689664, offset_y = 32767}, {foggable = 64, sprite
= 0x15e5950, offset_x = 1, offset_y = 0}, {foggable = 40, sprite = 0x1716600,
offset_x = 0, offset_y = 0}, {foggable = 223, sprite = 0x30, offset_x =
-391151953, offset_y = 32674}, {foggable = 187, sprite = 0x0, offset_x =
1140689712, offset_y = 32767}, {foggable = 50, sprite = 0x7fa2e81a5f32,
offset_x = 633, offset_y = 0}, {foggable = false, sprite = 0x7fa2e8b435e1,
offset_x = 4579568, offset_y = 0}, {foggable = 86, sprite = 0x10, offset_x =
1, offset_y = 0}, {foggable = true, sprite = 0x17b1d00, offset_x = 1140689712,
offset_y = 32767}, {foggable = 87, sprite = 0x17b1d00, offset_x = 24029744,
offset_y = 0}, {foggable = 224, sprite = 0x0, offset_x = 24219440, offset_y =
0}, {foggable = false, sprite = 0x0, offset_x = -476509268, offset_y = 32674},
{foggable = false, sprite = 0x0, offset_x = 71235648, offset_y = 0}, {foggable
= 64, sprite = 0x16eaa30, offset_x = 64, offset_y = 0}, {foggable = 142,
sprite = 0x7fa2e398e73b, offset_x = 0, offset_y = 0}, {foggable = false,
sprite = 0x16eaa30, offset_x = 24276032, offset_y = 0}, {foggable = 48, sprite
= 0x7fa2e5c02b9a, offset_x = 0, offset_y = 0}, {foggable = 198, sprite =
0x235c000, offset_x = -402018618, offset_y = 32674}, {foggable = 240, sprite =
0x7fff43fd8c10, offset_x = 1, offset_y = 0}, {foggable = 16, sprite = 0x1,
offset_x = 4566460, offset_y = 0}, {foggable = 32, sprite = 0x1718c10,
offset_x = 24390176, offset_y = 0}, {foggable = 48, sprite = 0x473a060,
offset_x = 72, offset_y = 0}, {foggable = 48, sprite = 0x1718f30, offset_x =
72, offset_y = 0}, {foggable = 167, sprite = 0x301742a20, offset_x = 65012438,
offset_y = 0}, {foggable = 215, sprite = 0x3e01e8e, offset_x = 288, offset_y =
48}, {foggable = 4, sprite = 0x439a690, offset_x = 4, offset_y = 0}, {foggable
= 96, sprite = 0x439a680, offset_x = 24029744, offset_y = 0}, {foggable = 64,
sprite = 0x16eaa30, offset_x = -440389493, offset_y = 32674}, {foggable = 48,
sprite = 0x1726c40, offset_x = 65020545, offset_y = 0}, {foggable = 15, sprite
= 0x1742ac0, offset_x = 74750432, offset_y = 0}, {foggable = 64, sprite =
0x1742ac0, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x1,
offset_x = -407165755, offset_y = 32674}, {foggable = 40, sprite = 0x228,
offset_x = 1, offset_y = 0}, {foggable = 209, sprite = 0x1718c10, offset_x =
71221264, offset_y = 1440}, {foggable = 192, sprite = 0x7fa2e7bbfe5f, offset_x
= 1440, offset_y = 0}, {foggable = 16, sprite = 0x173a8f0, offset_x =
24390336, offset_y = 0}, {foggable = false, sprite = 0x0, offset_x = 1,
offset_y = 0}, {foggable = 197, sprite = 0x228, offset_x = 48, offset_y = 0},
{foggable = false, sprite = 0x7fa2e7bb6bd1, offset_x = 24218640, offset_y =
0}, {foggable = 32, sprite = 0x1742a20, offset_x = 4676123, offset_y = 0},
{foggable = false, sprite = 0x83ecc90, offset_x = 0, offset_y = 0}, {foggable
= 155, sprite = 0x15bb2a0, offset_x = 138260528, offset_y = 0}, {foggable =
false, sprite = 0x1821180, offset_x = 1371, offset_y = 0}, {foggable = 70,
sprite = 0x467f5c0, offset_x = 62, offset_y = 0}}
count = <optimised out>
#3 0x000000000048f37c in update_map_canvas (canvas_x=0, canvas_y=0,
width=1440, height=552) at mapview_common.c:1347
cx = 3
cy = -31
gui_x = <optimised out>
gui_y = <optimised out>
ptile = 0x0
pedge = <optimised out>
pcorner = <optimised out>
ptile_r1 = 2
ptile_y0 = 122
ptile_index = <optimised out>
ptile_yi = <optimised out>
ptile_r2 = 4
ptile_w = 96
ptile_x0 = -55
ptile_y1 = <optimised out>
ptile_count = 3328
ptile_xi = <optimised out>
ptile_di = <optimised out>
ptile_h = 48
ptile_x1 = <optimised out>
ptilepedge = {type = EDGE_NS, tile = {0x83dabd0, 0x83dbc60}}
ptilepcorner = {tile = {0x83d9f50, 0x83db080, 0x83dc110, 0x83db030}}
ptile_si = <optimised out>
_x__0 = -1275
_y__0 = <optimised out>
_x__w = <optimised out>
_y__h = <optimised out>
layer = <optimised out>
gui_x0 = -1275
gui_y0 = 1483
full = false
tmp = <optimised out>
__FUNCTION__ = "update_map_canvas"
#4 0x000000000049041b in unqueue_mapview_updates (write_to_screen=true) at
mapview_common.c:2599
min_x = -165
max_x = 1563
min_y = -91
max_y = 461
W = <optimised out>
H = <optimised out>
UW = <optimised out>
UH = <optimised out>
city_width = <optimised out>
city_height = <optimised out>
area = {{dx = 0, dy = 0, w = 96, h = 48}, {dx = -48, dy = -24, w =
192, h = 96}, {dx = 0, dy = -24, w = 96, h = 72}, {dx = -48, dy = 48, w = 192,
h = 48}, {dx = -384, dy = -192, w = 864, h = 432}, {dx = 48, dy = 48, w = 0, h
= 0}}
my_tile_updates = {0x0, 0x455b660, 0x0, 0x0, 0x0, 0x0}
i = <optimised out>
__FUNCTION__ = "unqueue_mapview_updates"
#5 0x00000000004457fa in idle_callback_wrapper (data=<optimised out>) at
gui_main.c:2038
cb = 0x46cc250
#6 0x00007fa2e8b07d13 in g_main_context_dispatch () from
/lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#7 0x00007fa2e8b08060 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#8 0x00007fa2e8b0845a in g_main_loop_run () from
/lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#9 0x00007fa2e7f762f7 in gtk_main () from
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
No symbol table info available.
#10 0x00000000004487c9 in ui_main (argc=1, argv=0x7fff43fd95a8) at
gui_main.c:1673
home = <optimised out>
sig = <optimised out>
__FUNCTION__ = "ui_main"
#11 0x000000000046ea66 in client_main (argc=1, argv=0x7fff43fd95a8) at
client_main.c:590
i = 3
loglevel = LOG_NORMAL
ui_options = <optimised out>
ui_separator = <optimised out>
option = <optimised out>
user_tileset = <optimised out>
fatal_assertions = -1
aii = <optimised out>
__FUNCTION__ = "client_main"
#12 0x00007fa2e713976d in __libc_start_main (main=0x445520 <main>, argc=3,
ubp_av=0x7fff43fd95a8, init=<optimised out>, fini=<optimised out>,
rtld_fini=<optimised out>, stack_end=0x7fff43fd9598) at libc-start.c:226
result = <optimised out>
unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, -4179252356033740929,
4478248, 140734334080416, 0, 0, 4179014882160869247, 4126878600629911423},
mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x607710, 0x7fff43fd95a8}, data
= {prev = 0x0, cleanup = 0x0, canceltype = 6321936}}}
not_first_call = <optimised out>
#13 0x0000000000445551 in _start ()
No symbol table info available.
Undefined command: "qut". Try "help".
If I'm right about the cause, probably the thing to do is to ensure that all
owners and cities are cleared from other players' maps when a player is
removed, and that these updates are pushed to clients in a timely fashion so
that they happen before the client does handle_player_remove().
(Note that this only affects outright player removal -- at game end, via
/remove, or in the editor -- and not players dying during gameplay due to e.g.
losing a GameLoss unit, who will hang around as dead players. In that case we
would ideally like information about dead players to remain in other players'
maps -- with the introduction of gameloss_style (bug #20577), it's no longer
guaranteed that players' cities will have disappeared when news of the
player's demise reaches us, they might now be under new management. However,
if the player slot ever ends up reused to make room for a new player, as in
create_command_newcomer(), then we will need to remove the dead players' info
from other player maps at that time, which will look a little odd --
information will disappear from your map for no apparent reason -- but
probably won't occur much in practice. The alternative, remembering player
colours etc for an unbounded number of dead players, is probably not worth the
effort.)
_______________________________________________________
Reply to this item at:
<http://gna.org/bugs/?21384>
_______________________________________________
Message sent via/by Gna!
http://gna.org/
_______________________________________________
Freeciv-dev mailing list
[email protected]
https://mail.gna.org/listinfo/freeciv-dev