Project

General

Profile

Bug #858072

in fill_grid_sprite_array() [tilespec.c::5181]: assertion 't->sprites.player[plrid].grid_borders [pedge->type][1] != NULL' failed (2.6.1+, gtk3.22, civ2civ3_earth)

Added by Chippo Elder 5 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Client
Target version:
Start date:
Due date:
% Done:

0%

Estimated time:

Description

It happened as I expected to see the city dialog for my first city appear.

2: Loading tileset "amplio2".
2: Loading tileset "delta2".
2: Loading tileset "amplio2".
2: Loading tileset "amplio_earth".
[New Thread 0x7fffca7fc700 (LWP 226314)]
[Thread 0x7fffca7fc700 (LWP 226314) exited]
[New Thread 0x7fffca7fc700 (LWP 226358)]
0: in fill_grid_sprite_array() [tilespec.c::5181]: assertion 't->sprites.player[plrid].grid_borders [pedge->type][1] != NULL' failed.
0: Please report this message at https://www.hostedredmine.com/projects/freeciv

Thread 1 "freeciv-gtk3.22" received signal SIGABRT, Aborted.
raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt full
#0 raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:50
set = {__val = {0, 140737330257056, 93825057789552, 140737488331904, 140737488339151, 93824997435104, 7, 48, 0, 18229502520279517440, 93824997438016, 0, 21474836480, 140737488331936, 140733193388032, 93824997436288}}
pid = <optimized out>
tid = <optimized out>
#1 0x000055555573fede in fc_assert_fail
(file=file@entry=0x55555577eac1 "tilespec.c", function=function@entry=0x555555781d40 <__FUNCTION__.32224> "fill_grid_sprite_array", line=line@entry=5181, assertion=assertion@entry=0x5555557806b8 "t->sprites.player[plrid].grid_borders [pedge->type][1] != NULL", message=0x5555557ad4ec "nologmsg:%s") at log.c:523
level = LOG_FATAL
#2 0x000055555560af3b in fill_grid_sprite_array (t=t@entry=0x5555564059d0, sprs=0x7fffffffab38,
sprs@entry=0x7fffffffab20, ptile=ptile@entry=0x0, pedge=pedge@entry=0x7fffffffb380, citymode=citymode@entry=0x55555987dd00, pcity=0x0, punit=0x0, pcorner=0x0) at tilespec.c:5151
plrid = <optimized out>
owner0 = <optimized out>
owner1 = <optimized out>
known = {true, true}
unit = {false, false}
worked = {false, false}
i = <optimized out>
pfocus_units = 0x555555d36cc0
city = {false, true}
saved_sprs = 0x7fffffffab20
FUNCTION = "fill_grid_sprite_array"
#3 0x000055555560bd22 in fill_sprite_array (t=<optimized out>, sprs=sprs@entry=0x7fffffffab20, layer=layer@entry=LAYER_GRID1, ptile=<optimized out>,
ptile@entry=0x0, pedge=0x7fffffffb380, pcorner=0x0, punit=0x0, pcity=0x0, citymode=0x55555987dd00, putype=0x0) at tilespec.c:5823
tileno = <optimized out>
dir = <optimized out>
textras_near = {{vec = "`\000\000\000\060\000\000"}, {vec = "\000IYI\365\063\374", <incomplete sequence \374>}, {vec = "\000\000\000\000\000\000\000"}, {vec = " \253\377\377\377\177\000"}, {vec = "\020\264\377\377\377\177\000"}, {vec = "\320TJ\\UU\000"}, {vec = "\220\000\000\000\000\000\000"}, {vec = "H\000\000\000\000\000\000"}}
textras = {vec = "\000\000\000\000\000\000\000"}
tterrain_near = {0x7fffffffab38, 0x555555619a0c <canvas_put_sprite_full+92>, 0x60, 0x30, 0x3000000060, 0xfcfc33f549594900, 0x55555599f600 <civ_terrains+896>, 0x90}
pterrain = <optimized out>
save_sprs = 0x7fffffffab20
owner = 0x0
do_draw_unit = <optimized out>
solid_bg = <optimized out>
FUNCTION = "fill_sprite_array"
#4 0x00005555555db454 in put_one_element
(pcanvas=pcanvas@entry=0x7fffffffb410, zoom=zoom@entry=1, layer=layer@entry=LAYER_GRID1, ptile=ptile@entry=0x0, pedge=<optimized out>, pcorner=<optimized out>, punit=<optimized out>, pcity=0x0, canvas_x=72, canvas_y=-12, citymode=0x55555987dd00, putype=0x0) at mapview_common.c:1325
tile_sprs = {{foggable = false, sprite = 0x555556bb8970, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x55555c470420, offset_x = 24, offset_y = 24}, {foggable = false, sprite = 0x55555c97da60, offset_x = 48, offset_y = 12}, {foggable = false, sprite = 0x55555760bc60, offset_x = 0, offset_y = 12}, {foggable = false, sprite = 0x555555b0a780, offset_x = 48, offset_y = 0}, {foggable = false, sprite = 0x555557077f10, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x3ff0000000000000, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x3ff0000000000000, offset_x = 1466267472, offset_y = 21845}, {foggable = false, s--Type <RET> for more, q to quit, c to continue without paging--c
prite = 0x7ffff6b56393 <g_hash_table_lookup+67>, offset_x = 807411744, offset_y = 0}, {foggable = false, sprite = 0x555555c85970, offset_x = 1, offset_y = 0}, {foggable = 192, sprite = 0x555555aabe30, offset_x = -20744, offset_y = 32767}, {foggable = false, sprite = 0x7fffffffadd0, offset_x = -154729340, offset_y = 32767}, {foggable = false, sprite = 0x0, offset_x = 1440983392, offset_y = 21845}, {foggable = 176, sprite = 0x555555e3a8e0, offset_x = -21616, offset_y = 32767}, {foggable = 224, sprite = 0x7fffffffadd0, offset_x = 1433, offset_y = 21845}, {foggable = 48, sprite = 0x555558efacc0, offset_x = -154777824, offset_y = 32767}, {foggable = 32, sprite = 0x555555e85370, offset_x = 1440983904, offset_y = 21845}, {foggable = 240, sprite = 0x555555dd9420, offset_x = -21808, offset_y = 32767}, {foggable = true, sprite = 0x7fff00000000, offset_x = 16, offset_y = 32767}, {foggable = 22, sprite = 0x555500000016, offset_x = -152306230, offset_y = 32767}, {foggable = 160, sprite = 0x7fffffffae0c, offset_x = 2, offset_y = -65536}, {foggable = 79, sprite = 0x7fffffffae40, offset_x = 0, offset_y = 0}, {foggable = 144, sprite = 0xfcfc33f549594900, offset_x = 0, offset_y = 0}, {foggable = 208, sprite = 0x0, offset_x = -152304650, offset_y = 32767}, {foggable = false, sprite = 0xc00000018000, offset_x = 1497208432, offset_y = 21845}, {foggable = false, sprite = 0x0, offset_x = -152286839, offset_y = 32767}, {foggable = 32, sprite = 0xfcfc33f549594900, offset_x = -20176, offset_y = 32767}, {foggable = 224, sprite = 0x0, offset_x = -152293619, offset_y = 32767}, {foggable = 96, sprite = 0x7ffff6ec5877, offset_x = 1497208432, offset_y = 21845}, {foggable = 2, sprite = 0xffffffff800000, offset_x = 16777215, offset_y = 0}, {foggable = false, sprite = 0xc0, offset_x = 0, offset_y = 384}, {foggable = 192, sprite = 0x18000000000, offset_x = 192, offset_y = 0}, {foggable = false, sprite = 0x6000000c0, offset_x = 1509763744, offset_y = 21845}, {foggable = 160, sprite = 0x555555d90770, offset_x = 31, offset_y = 0}, {foggable = false, sprite = 0x0, offset_x = 24, offset_y = 32767}, {foggable = false, sprite = 0x7fffffffae70, offset_x = -20880, offset_y = 32767}, {foggable = false, sprite = 0x3, offset_x = 0, offset_y = 1072693248}, {foggable = false, sprite = 0x0, offset_x = 0, offset_y = 1072693248}, {foggable = false, sprite = 0x0, offset_x = 0, offset_y = 1072693248}, {foggable = false, sprite = 0x0, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0xffff000000000000, offset_x = 1465607712, offset_y = 21845}, {foggable = false, sprite = 0x0, offset_x = -155936457, offset_y = 32767}, {foggable = 192, sprite = 0x38, offset_x = 1492102352, offset_y = 21845}, {foggable = false, sprite = 0x0, offset_x = -155936457, offset_y = 32767}, {foggable = 192, sprite = 0x0, offset_x = 15, offset_y = 0}, {foggable = 208, sprite = 0x7fffffffaff0, offset_x = 1230588160, offset_y = -50580491}, {foggable = 176, sprite = 0x555558efacc0, offset_x = 1552938112, offset_y = 21845}, {foggable = 189, sprite = 0x555557ac19d0, offset_x = 0, offset_y = 21845}, {foggable = 15, sprite = 0x55555987dd00, offset_x = -20496, offset_y = 32767}, {foggable = 87, sprite = 0x0, offset_x = 1230588160, offset_y = 1}, {foggable = false, sprite = 0x4034000000000000, offset_x = 1470896592, offset_y = 21845}, {foggable = 20, sprite = 0x7f0030202020, offset_x = 0, offset_y = 1072693248}, {foggable = true, sprite = 0x7fffffffb1a0, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x0, offset_x = -134432496, offset_y = 32767}, {foggable = false, sprite = 0x7ffff69340f3 <__gconv_lookup_cache+819>, offset_x = -19936, offset_y = 32767}, {foggable = false, sprite = 0x55555a42b370, offset_x = 1468822128, offset_y = 21845}, {foggable = 128, sprite = 0x7ffff6b56393 <g_hash_table_lookup+67>, offset_x = 1468872336, offset_y = 21845}, {foggable = 224, sprite = 0x7fffffffb130, offset_x = 0, offset_y = 0}, {foggable = 144, sprite = 0xfcfc33f549594900, offset_x = 1497208432, offset_y = 21845}, {foggable = 112, sprite = 0x7fffffffb130, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x7ffff6f16068, offset_x = 33, offset_y = 0}, {foggable = 160, sprite = 0x7fffffffb130, offset_x = 2, offset_y = 0}, {foggable = 232, sprite = 0x0, offset_x = 1497336784, offset_y = 21845}, {foggable = 158, sprite = 0x0, offset_x = 384, offset_y = 192}, {foggable = false, sprite = 0xc00000018000, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x7fff00000018, offset_x = 0, offset_y = 0}, {foggable = 80, sprite = 0x7fffffffb150, offset_x = 0, offset_y = 3}, {foggable = 3, sprite = 0x3ff0000000000000, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x3ff0000000000000, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x3ff0000000000000, offset_x = 0, offset_y = 0}, {foggable = false, sprite = 0x0, offset_x = 0, offset_y = 1072693248}, {foggable = false, sprite = 0x5555593e9540, offset_x = -155801564, offset_y = 32767}, {foggable = false, sprite = 0x0, offset_x = 808333344, offset_y = 37}, {foggable = 161, sprite = 0x0, offset_x = 1439129576, offset_y = 21845}, {foggable = false, sprite = 0xc000, offset_x = 384, offset_y = 0}, {foggable = 100, sprite = 0xc00000000000, offset_x = 1439129576, offset_y = 21845}, {foggable = false, sprite = 0xfcfc33f549594900, offset_x = 1439129576, offset_y = 21845}, {foggable = 112, sprite = 0x0, offset_x = 1439129576, offset_y = 21845}, {foggable = 128, sprite = 0x0, offset_x = 1439129568, offset_y = 21845}, {foggable = 125, sprite = 0x0, offset_x = 1432060696, offset_y = 21845}}
count = <optimized out>
fog = <optimized out>
#5 0x00005555555aca74 in city_dialog_redraw_map (pcity=0x55555987dd00, pcanvas=pcanvas@entry=0x7fffffffb410) at citydlg_common.c:208
punit = <optimized out>
pcity_draw = <optimized out>
canvas_x = <optimized out>
canvas_y = <optimized out>
canvas_x_g = -2184
canvas_y_g = 5244
ptile = 0x0
pedge = <optimized out>
pcorner = <optimized out>
ptile_r1 = 2
ptile_y0 = 437
ptile_index = 44
ptile_yi = 439
ptile_r2 = 4
ptile_w = 96
ptile_x0 = -95
ptile_y1 = <optimized out>
ptile_count = 361
ptile_xi = -89
ptile_di = 528
ptile_h = 48
ptile_x1 = <optimized out>
ptilepedge = {type = EDGE_WE, tile = {0x555557bb7d10, 0x555557bb97e0}}
ptilepcorner = {tile = {0x555557bb62f0, 0x555557bb7e18, 0x555557bb9890, 0x555557bb7dc0}}
ptile_si = 350
x_0 = <optimized out>
y_0 = <optimized out>
x_w = <optimized out>
y_h = <optimized out>
canvas_x_0 = -2256
_tile_y = <optimized out>
canvas_y_0 = 5256
_tile_x = <optimized out>
canvas_x_w = <optimized out>
canvas_y_h = <optimized out>
layer = LAYER_GRID1
tmp = 0x0
#6 0x00005555556207bc in city_dialog_update_map (pdialog=0x555557ac19d0) at citydlg.c:1915
store = {surface = 0x5555593d9670, drawable = 0x0, zoom = 1}
#7 0x0000555555622f7e in real_city_dialog_refresh (pcity=0x55555987dd00) at citydlg.c:492
pdialog = 0x555557ac19d0
#8 0x00005555556242bc in create_city_dialog (pcity=0x55555987dd00) at citydlg.c:1693
pdialog = 0x555557ac19d0
close_command = 0x555557808c00
vbox = <optimized out>
hbox = <optimized out>
cbox = <optimized out>
ebox = <optimized out>
citizen_bar_width = <optimized out>
citizen_bar_height = <optimized out>
pb = <optimized out>
pdialog = <optimized out>
#9 real_city_dialog_popup (pcity=0x55555987dd00) at citydlg.c:554
pdialog = <optimized out>
#10 0x0000555555613e2d in cities_update_callback (data=<optimized out>) at update_queue.c:607
need_update = <optimized out>
pcity_iter = 0x0
pcity = 0x55555987dd00
pcity_player = <optimized out>
_pslotpcity_player = 0x555557311800
#11 cities_update_callback (data=<optimized out>) at update_queue.c:580
#12 0x0000555555613c02 in update_unqueue (data=<optimized out>) at update_queue.c:319
callback = 0x555555613d80 <cities_update_callback>
uq_data = <optimized out>
MY_mem_MY_iter = 0x7fffffffb550 "0\267sUUU"
MY_it_MY_iter = 0x7fffffffb550
MY_iter = 0x7fffffffb550
hash = 0x555556310920
#13 0x000055555558280f in idle_callback_wrapper (data=0x555556bc46c0) at gui_main.c:2239
cb = 0x555556bc46c0
#14 0x00007ffff6b6871e in g_main_context_dispatch () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#15 0x00007ffff6b68ad0 in () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#16 0x00007ffff6b68dc3 in g_main_loop_run () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 0x00007ffff736fc2d in gtk_main () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#18 0x0000555555585666 in ui_main (argc=<optimized out>, argc@entry=1, argv=<optimized out>, argv@entry=0x7fffffffbbe8) at gui_main.c:1880
toplevel_font_name = <optimized out>
sig = <optimized out>
FUNCTION = "ui_main"
#19 0x00005555555afcfe in client_main (argc=1, argv=0x7fffffffbbe8) at client_main.c:685
i = 2
loglevel = LOG_NORMAL
ui_options = <optimized out>
ui_separator = <optimized out>
option = <optimized out>
fatal_assertions = 6
aii = 1
FUNCTION = "client_main"
#20 0x00007ffff69281e3 in __libc_start_main (main=0x555555582480 <main>, argc=2, argv=0x7fffffffbbe8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffbbd8) at ../csu/libc-start.c:308
result = <optimized out>
unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, 2771111663927134788, 93824992421008, 140737488337888, 0, 0, 8296090603518790212, 8296106230405892676}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x7fffffffbc00, 0x7ffff7ffe190}, data = {prev = 0x0, cleanup = 0x0, canceltype = -17408}}}
not_first_call = <optimized out>
#21 0x00005555555824be in _start () at gui_main.c:1657

m-ruleset-tileset-plrcolors.patch (4.34 KB) m-ruleset-tileset-plrcolors.patch master Jacob Nevins, 2020-02-06 01:12 AM
30-26-ruleset-tileset-plrcolors.patch (4.34 KB) 30-26-ruleset-tileset-plrcolors.patch S3_0, S2_6 Jacob Nevins, 2020-02-06 01:12 AM

History

#1 Updated by Jacob Nevins 5 months ago

So, we were trying to draw borders, and we couldn't find an appropriate border sprite for one of the players. (The second one, but maybe the first was NULL.) And this happened when we were popping up a city dialog (which I think ought not to show any terrain that wasn't already on the main map?)

This rings a faint bell. One way this can happen is if something goes wrong with producing player-specific coloured border sprites from the generic ones when player colours are initialised. Haven't got proof that that went wrong here.

Haven't tried reproducing yet, but I've played a fair amount of civ2civ3_earth in the past and don't recall encountering trouble here.

#2 Updated by Marko Lindqvist 5 months ago

This is trivially reproducible. civ2civ3_earth ruleset + tileset does not show any borders.

Jacob Nevins wrote:

And this happened when we were popping up a city dialog (which I think ought not to show any terrain that wasn't already on the main map?)

I think the thing here is that there's no territory, and thus no borders, before the first city is founded. As soon as one founds the city, borders should appear.

#3 Updated by Marko Lindqvist 5 months ago

This only happens if one loads amplio_earth tileset from the ruleset's suggested tileset dialog. It does not happen if client is started with -t amplio_earth, nor does it happen if one refuses to load amplio_earth from the dialog but changes the tileset only once in game.

#4 Updated by Jacob Nevins 5 months ago

Yes, now I can reproduce this from cazfi's instructions. (For completeness: with freeciv-gtk3.22, and selecting the ruleset from the client dropdown rather than with "-r" or anything; I haven't checked if those things are necessary.)

#5 Updated by Jacob Nevins 5 months ago

I noticed in passing recently that the client pops up the tileset dialog on receiving the PACKET_RULESET_CONTROL packet (start of ruleset data), whereas PACKET_RULESETS_READY (end of ruleset data) feels like it would be safer? Maybe that's relevant? Haven't looked in detail.

#6 Updated by Jacob Nevins 5 months ago

tilespec_reread() is protected from the most obvious trouble of running at this point by a check for game.client.ruleset_ready, FALSE in this situation.

I feel the code path involved (game.client.ruleset_ready FALSE, game_fully_initialized FALSE) might be unique to the situation of loading a ruleset-preferred tileset, so it's plausible there's a bug specific to it.

#7 Updated by Jacob Nevins 5 months ago

So, the special conditions prevent tilespec_reread() calling tileset_player_init() for all players; and it is not consistently called later.

It is called for a few later-numbered players (but not the human), as a side effect of receiving PACKET_PLAYER_INFO. I'm guessing (but haven't proved) that doesn't happen for all players because PLAYER_INFO is an is-info packet, and nothing changed about the player from the server side.

#8 Updated by Jacob Nevins 5 months ago

The Qt client allows you to change the current tileset from the pregame screen, which feels like it ought to be an analogous situation.

But it doesn't run into the same problem, because it passes game_fully_initialized == client.conn.established, which is TRUE at this point. So it completely reinitialises tileset stuff from the player colours.

So, perhaps the answer is simply to pass game_fully_initialized as TRUE when switching tileset because of ruleset preference. It appears to mean something like "do we have a network connection", and if we're thinking about a specific ruleset we must do.

(Probably this is a spot fix we can apply for the next release, but it feels like we ought to be able to reduce the number of code paths and boolean conditions involved here...)

#9 Updated by Jacob Nevins 5 months ago

  • Category set to Client
  • Status changed from New to Resolved
  • Assignee set to Jacob Nevins
  • Target version set to 2.6.2

perhaps the answer is simply to pass game_fully_initialized as TRUE when switching tileset because of ruleset preference

There was one other minor tweak needed to avoid a crash.

This seems to work for me. (I also tested with auto-accept.) I haven't thoroughly tested other tileset-loading scenarios but I didn't break it on a quick play around.

The patch mostly, but not entirely, only affects the ruleset-overriding-tileset case.

#11 Updated by Jacob Nevins 5 months ago

...this area was last touched for gna bug #21231, and my patch more or less reverts that. But I think/hope there have probably been rearrangements since then that make my version safe (gna bug #21116, sort of thing).

#12 Updated by Jacob Nevins 5 months ago

  • Status changed from Resolved to Closed

Also available in: Atom PDF