Bug #1854
openSegmentation in Qt client during server quit.
0%
Description

During the client's `tile_virtual_destroy()`, one of the pcity->tile pointers gets set to garbage.
The first half of `tile_virtual_destroy()` succeeds, but segfaults as soon as the code attempts to retrieve the pointer to the city. The city pointer is fine, but the pcity->tile pointer is garbage.
void tile_virtual_destroy(struct tile *vtile)
{
struct city *vcity;
if (!vtile) {
return;
}
if (vtile->units) {
unit_list_iterate(vtile->units, vunit) {
if (unit_is_virtual(vunit)) {
unit_virtual_destroy(vunit);
}
} unit_list_iterate_end;
unit_list_destroy(vtile->units);
vtile->units = nullptr;
}
vcity = tile_city(vtile);
if (vcity) {
if (city_is_virtual(vcity)) {
destroy_city_virtual(vcity);
}
tile_set_worked(vtile, nullptr);
}
free(vtile);
}
Here is the offending line:
vcity = tile_city(vtile);
Which calls `is_city_center()`:
struct city *tile_city(const struct tile *ptile)
{
struct city *pcity = ptile->worked;
if (pcity != nullptr && is_city_center(pcity, ptile)) {
return pcity;
}
return nullptr;
}
Which segfaults in `city_tile()` because the city tile pointer is corrupted in:
static inline bool is_city_center(const struct city *pcity,
const struct tile *ptile)
{
if (!pcity || !pcity->tile || !ptile) {
return FALSE;
}
return tile_index(city_tile(pcity)) == tile_index(ptile);
}
`city_tile()` is a macro:
#define city_tile(_pcity_) (_pcity_)->tile
Files
Updated by John Robertson 9 days ago
I have attached the saved game file, but have not been able to duplicate the issue.
Updated by John Robertson 9 days ago
[beginning backwards]
I have not duplicated this since, but the steps were:
- play a couple of turns
- issue server command to save the game
- issue server command to quit the server
- BOOM Qt client segfaults
Updated by John Robertson 9 days ago
(since this is not readily duplicatable, I expect the issue to be closed; reported for information purposes only)
Updated by John Robertson 8 days ago
duplicated again. Curious if several turns are required before the server side save and quit.
Updated by Marko Lindqvist 1 day ago
Maybe city->tile pointer is not corrupt per se, but the tile it points to has already been freed.
Maybe valgrind could provide some insight, such as providing stack trace of the point where the memory had been freed, if you could reproduce this in a valgrind session (or even if not - the bad access might be there always, but crashes only sometimes)