The International Simutrans Forum

Development => Patches & Projects => Topic started by: janry on May 24, 2026, 11:47:43 PM

Title: sanitizer crash when generating a world - something with bridge?
Post by: janry on May 24, 2026, 11:47:43 PM
I got this on git 42fe65938dd3353c5d913b470a1de6475d24dfb0, svn 11973:
[jan@plamisty hextrans]$ ASAN_OPTIONS="print_stacktrace=1:abort_on_error=1:detect_leaks=0" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" ./build/simutrans/simutrans  -set_basedir /usr/share/simutrans/ -server
/home/jan/Desktop/hextrans/src/simutrans/world/simcity.cc:4019:32: runtime error: member call on address 0x7e11cf101e68 which does not point to an object of type 'grund_t'
0x7e11cf101e68: note: object has a possibly invalid vptr: abs(offset to top) too big
 ff 00 00 03  90 4f 4c ce 81 7b 00 00  e0 14 37 ce 71 7b 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
    #0 0x557bd26d44b9 in stadt_t::build_road(koord, player_t*, bool) /home/jan/Desktop/hextrans/src/simutrans/world/simcity.cc:4019
    #1 0x557bd26d772a in stadt_t::build() /home/jan/Desktop/hextrans/src/simutrans/world/simcity.cc:4113
    #2 0x557bd269a3bb in stadt_t::step_grow_city(bool) /home/jan/Desktop/hextrans/src/simutrans/world/simcity.cc:1811
    #3 0x557bd2692080 in stadt_t::change_size(long long, bool) /home/jan/Desktop/hextrans/src/simutrans/world/simcity.cc:1440
    #4 0x557bd2726457 in karte_t::distribute_cities(int, int, short, short) /home/jan/Desktop/hextrans/src/simutrans/world/simworld.cc:872
    #5 0x557bd273f5da in karte_t::enlarge_map(settings_t const*, signed char const*) /home/jan/Desktop/hextrans/src/simutrans/world/simworld.cc:1906
    #6 0x557bd2731207 in karte_t::init(settings_t*, signed char const*) /home/jan/Desktop/hextrans/src/simutrans/world/simworld.cc:1280
    #7 0x557bd24e528a in tool_work_world_t::init(player_t*) /home/jan/Desktop/hextrans/src/simutrans/tool/simtool.cc:8794
    #8 0x557bd1af9b46 in nwc_tool_t::do_command(karte_t*) /home/jan/Desktop/hextrans/src/simutrans/network/network_cmd_ingame.cc:1296
    #9 0x557bd27a0b9b in karte_t::do_network_world_command(network_world_command_t*) /home/jan/Desktop/hextrans/src/simutrans/world/simworld.cc:6049
    #10 0x557bd279e6ea in karte_t::process_network_commands(int*) /home/jan/Desktop/hextrans/src/simutrans/world/simworld.cc:5996
    #11 0x557bd27a4f05 in karte_t::interactive(unsigned int) /home/jan/Desktop/hextrans/src/simutrans/world/simworld.cc:6206
    #12 0x557bd233857a in simu_main(int, char**) /home/jan/Desktop/hextrans/src/simutrans/simmain.cc:1703
    #13 0x557bd235e59f in sysmain(int, char**) /home/jan/Desktop/hextrans/src/simutrans/sys/simsys.cc:1541
    #14 0x557bd2a54f3f in main /home/jan/Desktop/hextrans/src/simutrans/sys/simsys_s2.cc:1202
    #15 0x7f41cef2c740  (/usr/lib/libc.so.6+0x27740) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049)
    #16 0x7f41cef2c878 in __libc_start_main (/usr/lib/libc.so.6+0x27878) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049)
    #17 0x557bd0b02804 in _start (/home/jan/Desktop/hextrans/build/simutrans/simutrans+0x3e68804) (BuildId: ad56ae1f4e95069d82ab4edfcaefe5923b967dd6)


And the hypothesis, which I'm not sure about:

stadt_t::build_road cached bd_next as a grund_t* before calling bridge_builder_t::build_bridge. When build_bridge retypes the endpoint (boden_t -> brueckenboden_t ramp), the cached pointer dangles, and the following bd_next->get_pos().get_2d() is a member call on freed memory. UBSAN -fsanitize=vptr surfaces it as "object has a possibly invalid vptr: abs(offset to top) too big" from city growth during karte_t::enlarge_map.

And a fix

Capture end before the call so the koord is computed off a still- live grund_t.

diff --git a/src/simutrans/world/simcity.cc b/src/simutrans/world/simcity.cc
index 0ab1815b7..0be14f430 100644
--- a/src/simutrans/world/simcity.cc
+++ b/src/simutrans/world/simcity.cc
@@ -4015,8 +4015,8 @@ bool stadt_t::build_road(const koord k, player_t* player_, bool forced)
  return false;
  }
  }
- bridge_builder_t::build_bridge(NULL, bd->get_pos(), bd_next->get_pos(), zv, bridge_height, bridge, welt->get_city_road());
  koord end = bd_next->get_pos().get_2d();
+ bridge_builder_t::build_bridge(NULL, bd->get_pos(), bd_next->get_pos(), zv, bridge_height, bridge, welt->get_city_road());
  build_road( end+zv, NULL, false);
  // try to build a house near the bridge end
  uint32 old_count = buildings.get_count();
Title: Re: sanitizer crash when generating a world - something with bridge?
Post by: prissi on May 25, 2026, 08:38:08 AM
Sounds like a reasonable explanation when first construction failed and then terraform in the err branch. Anyway, moved end way up should fix this. (And mark_dirty() need to go too, but replaing ground should mark it dirty automatically.) Thank you.