Attack from transport crash
I can't reproduce (with the head of S3_1), nor does valgrind reveal anything like accessing the Musketeer memory after it has died. Seems that the only way forward would be that you provide full backtrace of the crash yourself. https://www.freeciv.org/wiki/Bug_Reporting
Reply To cazfi
I can't reproduce (with the head of S3_1), nor does valgrind reveal anything like accessing the Musketeer memory after it has died. Seems that the only way forward would be that you provide full backtrace of the crash yourself. https://www.freeciv.org/wiki/Bug_Reporting
The head of S3_1 (v3.1.1+ from today) still crashes to me. Gdb backtrace:
#0 tile_to_canvas_pos (canvas_x=canvas_x@entry=0x7fffffffcda8, canvas_y=canvas_y@entry=0x7fffffffcdac, zoom=<optimized out>, ptile=ptile@entry=0xed407f99fe4eb523) at mapview_common.c:708 center_map_x = 14 center_map_y = 24 dx = 17 dy = 0 tile_x = <optimized out> tile_y = <optimized out> __FUNCTION__ = "tile_to_canvas_pos" #1 0x00005555555f1fde in tile_visible_and_not_on_border_mapcanvas (ptile=0xed407f99fe4eb523) at mapview_common.c:1281 canvas_x = 0 canvas_y = 0 xmin = -2276 ymin = 531 xmax = 2228 ymax = 2325 xsize = 1096 ysize = 667 scroll_x = -980 scroll_y = 602 border_x = 48 border_y = 24 same = false #2 0x00005555555d0c18 in unit_focus_advance () at control.c:725 focus_tile = 0x0 candidate = 0x55555cb08050 num_units_in_old_focus = 0 __FUNCTION__ = "unit_focus_advance" #3 0x00005555555cb10a in client_remove_unit (punit=0x0, punit@entry=0x55555cb08050) at climisc.c:100 pcity = <optimized out> ptile = 0x55555bfa0240 hc = 0 old_unit = {utype = 0x555556273e30 <unit_types+24048>, tile = 0x55555bfa0240, refcount = 1, facing = DIR8_NORTHWEST, owner = 0x555556c162f0, nationality = 0x555556c162f0, id = 126, homecity = 0, upkeep = {1, 0, 0, 1, 0, 0}, moves_left = 6, hp = 20, veteran = 0, fuel = 0, goto_tile = 0x0, activity = ACTIVITY_IDLE, activity_count = 0, activity_target = 0x0, changed_from = ACTIVITY_IDLE, changed_from_count = 0, changed_from_target = 0x0, ssa_controller = SSA_NONE, moved = false, paradropped = false, done_moving = false, transporter = 0x0, transporting = 0x555559f60f70, carrying = 0x0, battlegroup = -1, has_orders = false, orders = {length = 0, index = 0, repeat = false, vigilant = false, list = 0x0}, action_decision_want = ACT_DEC_ACTIVE, action_decision_tile = 0x55555bf9e2c0, stay = false, {client = {focus_status = FOCUS--Type <RET> for more, q to quit, c to continue without paging-- _AVAIL, transported_by = -1, occupied = false, colored = false, color_index = 0, asking_city_name = false, act_prob_cache = 0x0}, server = {debug = false, adv = 0x0, ais = {0x0, 0x0}, birth_turn = 0, ord_map = 0, ord_city = 0, vision = 0x0, action_timestamp = 0, action_turn = 0, moving = 0x0, dying = false, removal_callback = 0x0, upkeep_paid = {0, 0, 0, 0, 0, 0}}}} old = 1 update = true __FUNCTION__ = "client_remove_unit" #4 0x00005555555fe052 in handle_unit_remove (unit_id16=<optimized out>, unit_id32=<optimized out>) at packhand.c:560 punit = 0x55555cb08050 cargos = <optimized out> powner = 0x555556c162f0 need_economy_report_update = true __FUNCTION__ = "handle_unit_remove" #5 0x000055555560c2a1 in client_handle_packet (type=type@entry=PACKET_UNIT_REMOVE, packet=packet@entry=0x555557f4ccf0) at packhand_gen.c:207 #6 0x00005555555c719a in client_packet_input (packet=packet@entry=0x555557f4ccf0, type=62) at client_main.c:792 __FUNCTION__ = "client_packet_input" #7 0x00005555555ceec4 in input_from_server (fd=<optimized out>) at clinet.c:420 type = PACKET_UNIT_REMOVE packet = 0x555557f4ccf0 nb = <optimized out> __FUNCTION__ = "input_from_server" #8 0x00005555555c2494 in get_net_input (source=<optimized out>, condition=<optimized out>, data=<optimized out>) at gui_main.c:2222 #9 0x00007ffff6c6ac44 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #10 0x00007ffff6cc0258 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #11 0x00007ffff6c6a2b3 in g_main_loop_run () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #12 0x00007ffff74aacfd in gtk_main () at /lib/x86_64-linux-gnu/libgtk-3.so.0 #13 0x00005555555c50b2 in ui_main (argc=<optimized out>, argc@entry=1, argv=<optimized out>, argv@entry=0x7fffffffd9f8) at gui_main.c:1987 window_name = "Freeciv (gtk3.22)\000\000\000\000\000\000\000\000/\035k/\\rW\340\324\377\377\377\177\000\000\030\000\000\000\000\000\000\000\250t\206UUU\000\000曃UUU\000\000\000\000\000\000\000\000\000\000\030", '\000' <repetidos 23 veces>, "\340\353\210UUU\000\000Z\235\203UUU\000\000\001\000\000\000\000\000\000\000'l\201UUU", '\000' <repetidos 26 veces>, " \000\000\000\060\000\000\000\320\324\377\377\001\000\000\000\360\323\377\377\377\177\000\000colors.p\000/\035k/\\rW_backgro\200\377\377\377\377\377\377\377"... toplevel_font_name = <optimized out> sig = <optimized out> __FUNCTION__ = "ui_main" #14 0x00005555555c8455 in client_main (argc=1, argv=0x7fffffffd9f8, postpone_tileset=<optimized out>) at client_main.c:703 i = 1 loglevel = LOG_NORMAL ui_options = <optimized out> ui_separator = <optimized out> --Type <RET> for more, q to quit, c to continue without paging-- option = <optimized out> fatal_assertions = -1 aii = 2 uret = <optimized out> __FUNCTION__ = "client_main" #15 0x00007ffff6a15d90 in __libc_start_call_main (main=main@entry=0x5555555c1a10 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd9f8) at ../sysdeps/nptl/libc_start_call_main.h:58 self = <optimized out> result = <optimized out> unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, 913343395805536372, 140737488345592, 93824992680464, 93824996397528, 140737354125376, -913343396845576076, -913327234994265996}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}} not_first_call = <optimized out> #16 0x00007ffff6a15e40 in __libc_start_main_impl (main=0x5555555c1a10 <main>, argc=1, argv=0x7fffffffd9f8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd9e8) at ../csu/libc-start.c:392 #17 0x00005555555c1a45 in _start ()
This is gdb bt with qt6 client (this time S3_1 from 20 days ago):
#0 0x0000555555947141 in utype_can_do_action (putype=<optimized out>, act_id=<optimized out>) at unittype.c:449 __FUNCTION__ = "utype_can_do_action" #1 0x0000555555948f4e in utype_can_do_action_result (putype=0x55555c50a140, result=result@entry=ACTRES_FOUND_CITY) at unittype.c:465 paction_iter = 0x0 paction = <optimized out> __FUNCTION__ = "utype_can_do_action_result" #2 0x000055555594d19a in utype_is_cityfounder (utype=<optimized out>) at unittype.c:2974 No locales. #3 0x0000555555944479 in unit_is_cityfounder (punit=punit@entry=0x55555c4b46f0) at unit.c:2621 No locales. #4 0x000055555569eef0 in unit_drawn_with_city_outline (punit=punit@entry=0x55555c4b46f0, check_focus=check_focus@entry=true) at tilespec.c:5277 No locales. #5 0x0000555555673b66 in refresh_unit_mapcanvas (punit=punit@entry=0x55555c4b46f0, ptile=0x7ffff640ee80 <main_arena+512>, full_refresh=full_refresh@entry=true, write_to_screen=write_to_screen@entry=false) at mapview_common.c:515 No locales. #6 0x000055555564abe0 in current_focus_append (punit=0x55555c4b46f0) at control.c:448 No locales. #7 0x000055555564ad82 in unit_focus_set (punit=punit@entry=0x55555c4b46f0) at control.c:544 focus_changed = true __FUNCTION__ = "unit_focus_set" #8 0x000055555564b260 in unit_focus_set (punit=0x55555c4b46f0) at control.c:506 focus_changed = false focus_changed = <optimized out> __FUNCTION__ = "unit_focus_set" punit_old_iter = <optimized out> punit_old = <optimized out> punit_old_iter = <optimized out> punit_old = <optimized out> #9 unit_focus_advance () at control.c:750 candidate = 0x55555c4b46f0 num_units_in_old_focus = 0 __FUNCTION__ = "unit_focus_advance" #10 0x00005555556457aa in client_remove_unit (punit=0x0, punit@entry=0x55555c4b46f0) at climisc.c:100 pcity = <optimized out> ptile = 0x55555c457200 hc = 0 old_unit = {utype = 0x5555563c9a30 <unit_types+24048>, tile = 0x55555c457200, refcount = 1, facing = DIR8_NORTHWEST, owner = 0x55555ad34840, nationality = 0x55555ad34840, id = 126, homecity = 0, upkeep = {1, 0, 0, 1, 0, 0}, moves_left = 6, hp = 0, veteran = 0, fuel = 0, goto_tile = 0x0, --Type <RET> for more, q to quit, c to continue without paging-- activity = ACTIVITY_IDLE, activity_count = 0, activity_target = 0x0, changed_from = ACTIVITY_IDLE, changed_from_count = 0, changed_from_target = 0x0, ssa_controller = SSA_NONE, moved = false, paradropped = false, done_moving = false, transporter = 0x0, transporting = 0x55555c4b4850, carrying = 0x0, battlegroup = -1, has_orders = false, orders = {length = 0, index = 0, repeat = false, vigilant = false, list = 0x0}, action_decision_want = ACT_DEC_ACTIVE, action_decision_tile = 0x55555c455280, stay = false, {client = {focus_status = FOCUS_AVAIL, transported_by = -1, occupied = false, colored = false, color_index = 0, asking_city_name = false, act_prob_cache = 0x0}, server = {debug = false, adv = 0x0, ais = {0x0, 0x0}, birth_turn = 0, ord_map = 0, ord_city = 0, vision = 0x0, action_timestamp = 0, action_turn = 0, moving = 0x0, dying = false, removal_callback = 0x0, upkeep_paid = {0, 0, 0, 0, 0, 0}}}} old = 1 update = true __FUNCTION__ = "client_remove_unit" #11 0x00005555556786e2 in handle_unit_remove (unit_id16=<optimized out>, unit_id32=<optimized out>) at packhand.c:560 punit = 0x55555c4b46f0 cargos = <optimized out> powner = 0x55555ad34840 need_economy_report_update = true __FUNCTION__ = "handle_unit_remove" #12 0x0000555555686931 in client_handle_packet (type=type@entry=PACKET_UNIT_REMOVE, packet=packet@entry=0x55555c508d20) at packhand_gen.c:207 No locales. #13 0x000055555564183a in client_packet_input (packet=packet@entry=0x55555c508d20, type=62) at client_main.c:792 __FUNCTION__ = "client_packet_input" #14 0x0000555555649564 in input_from_server (fd=<optimized out>) at clinet.c:420 type = PACKET_UNIT_REMOVE packet = 0x55555c508d20 nb = <optimized out> __FUNCTION__ = "input_from_server" #15 0x0000555555700a64 in fc_client::server_input (this=0x5555572827a0, sock=19) at fc_client.cpp:505 No locales. #16 0x00007ffff7064023 in ?? () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #17 0x00007ffff7070baa in QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #18 0x00007ffff7071199 in QSocketNotifier::event(QEvent*) () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #19 0x00007ffff68d1d36 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt6Widgets.so.6 No symbol table info available. #20 0x00007ffff700ba58 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. --Type <RET> for more, q to quit, c to continue without paging-- #21 0x00007ffff7234bd7 in ?? () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #22 0x00007ffff3b7bd3b in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 No symbol table info available. #23 0x00007ffff3bd1258 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 No symbol table info available. #24 0x00007ffff3b793e3 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 No symbol table info available. #25 0x00007ffff7233eae in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #26 0x00007ffff7018adb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #27 0x00007ffff70140f3 in QCoreApplication::exec() () from /lib/x86_64-linux-gnu/libQt6Core.so.6 No symbol table info available. #28 0x0000555555701c4c in fc_client::fc_main (this=0x5555572827a0, qapp=0x55555651be00) at fc_client.cpp:273 No locales. #29 0x000055555563f7b3 in qtg_ui_main (argc=<optimized out>, argv=0x7fffffffda08) at gui_main.cpp:211 qpm = <optimized out> app_icon = {d = 0x5555568a69b0} tsret = 0 #30 0x0000555555642af5 in client_main (argc=1, argv=0x7fffffffda08, postpone_tileset=<optimized out>) at client_main.c:703 i = 1 loglevel = LOG_NORMAL ui_options = <optimized out> ui_separator = <optimized out> option = <optimized out> fatal_assertions = -1 aii = 2 uret = <optimized out> __FUNCTION__ = "client_main" #31 0x00007ffff621dd90 in __libc_start_call_main (main=main@entry=0x55555563d1c0 <main(int, char**)>, argc=argc@entry=1, argv=argv@entry=0x7fffffffda08) at ../sysdeps/nptl/libc_start_call_main.h:58 self = <optimized out> result = <optimized out> unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, 5550509266952179337, 140737488345608, 93824993186240, 93824997735288, 140737354125376, -5550509267952284023, -5550490249962402167}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}} not_first_call = <optimized out> #32 0x00007ffff621de40 in __libc_start_main_impl (main=0x55555563d1c0 <main(int, char**)>, argc=1, argv=0x7fffffffda08, init=<optimized out>, fini=<optimized out>, --Type <RET> for more, q to quit, c to continue without paging-- rtld_fini=<optimized out>, stack_end=0x7fffffffd9f8) at ../csu/libc-start.c:392 No locales. #33 0x000055555563ee55 in _start ()
So the problem seems to be in unit focus handling. Didn't figure out this particular issue yet, but while looking for it, found https://redmine.freeciv.org/issues/586
I see the problem now, from the Qt-client backtrace. client_remove_unit() has destroyed the unit, but has not yet removed it from the list of units on the tile. unit_focus_advance() notices the unit from the tile as a "new" (since it's already been removed from current focus) focus unit, and starts using it. My fix to https://redmine.freeciv.org/issues/586 makes it less likely that all this happens, but I'm not sure it covers all cases (this is not the bug it's meant to fix, anyway)
While osdn has refused to send my comments about the first patch, the second one has already been made. Now you likely want to test unit_focus_advanceIterateSafe.patch first, to see if it resolves the issue for you. Seems to me that the old code could have messed memory with undefined results.
If it doesn't help:
Can you try to reproduce the issue with attached DeathFromTransportDebug.patch applied, and paste the logs between BEGINS and ENDS.
For reference, here's what I got on S3_1 HEAD, and where I see no problems (the removed unit (pointer) is not getting back to focus, like seems to happen in your backtrace):
3: BEGINS 3: client_remove_unit() 0x556fcdfba580 at (14, 24) 3: client_remove_unit(): 1 units in focus. 3: End of control_unit_killed(): 0 units in focus. 3: unit_focus_advance(): urgent focus size 0 3: Center tile: (14, 24) 3: best focus candidate: 0x556fcc10bd40 3: ENDS
I'm glad you found the cause, I'll test the patch.
I confirm the patch (unit_focus_advanceIterateSafe.patch) fixes the crash I reported in this ticket, and also the crash from #62981 (healer killed by script). Thank you.
However, even if there are no crashes, I still find problematic the way the unit focus jumps to the next unit before you have finished the movement/actions. For example: * When I use goto to move a unit, when it arrives to the desired tile, the focus jumps to the next unit even when the current one still has remaining move points. * When I order to disembark, the unit is deselected before asking the desired action * And similar issues when I order diplomats or caravans to perform actions. They are deselected, the focus jumps to next unit, and I have to select them again to finish the action.
Since you could not reproduce the crash, I'm thinking it could be dependant on client settings, I'll test to change them, because it didn't happen in 3.0 to me.
I confirm the patch (unit_focus_advanceIterateSafe.patch) fixes the crash I reported in this ticket, and also the crash from #62981 (healer killed by script). Thank you.
However, even if there are no crashes, I still find problematic the way the unit focus jumps to the next unit before you have finished the movement/actions. For example:
Since you could not reproduce the crash, I'm thinking it could be dependant on client settings, I'll test to change them, because it didn't happen in 3.0 to me.
I'll plan to apply the fix also to S2_6. It applies cleanly.
While I couldn't reproduce the crash, I am seeing various odd behaviors with the focus advancement in general.
Reply To cazfi
While I couldn't reproduce the crash, I am seeing various odd behaviors with the focus advancement in general.
Similar to bug #62981, but this time with default ruleset (S3_1). Tested with client gtk3.22 and qt6.
If I load the attached savegame, I use the mouse to select one of the Musketers (all in sentry state) inside the Transport, and I use "drag and drop" (mouse gesture) to attack the adjacent enemy Mech Inf, then the Musketer is deselected, loses the sentry state, and it changes to a "waiting orders" state with a "?" icon. If I select the same Musketer again, and I click attack when the popup appear, the game crashes with a segmentation fault error:
in utype_can_do_action() [unittype.c::449]: assertion '(signed int)(utype_index(putype)) >= 0 && (signed int)(utype_index(putype)) < (signed int) sizeof((unit_can_act_cacheact_id).vec) * 8' failed.
I'm playing a game where this kind of crashes are common (any action performed from a transport with a sentry unit), but it uses to work if I just reload the game. This savegame crashes to me every time I try the same attack.