Project

General

Profile

Bug #858212

Qt heap-use-after-free entering Pick Nation screen (2.6.1+)

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

Status:
Closed
Priority:
Normal
Category:
gui-qt
Target version:
Start date:
Due date:
% Done:

0%

Estimated time:

Description

This BT/dump/thingy has appeared in another ticket #858069, but that ticket has 3 different dumps for between 3 and 5 different bugs and a completely inappropriate title.

To trigger it you need to compile with -fsanatize=address and I used llvm, but it should be the same with gcc. Then, sadly, you have to play for a while. Load a savegame, do a turn or two, start a New Game with a new ruleset, play a turn. Then when it's primed, Leave Game, Start New Game, don't touch anything (ruleset says default) except you click Pick Nation, and it dumps (which is quite pretty, with colours and all).

I can reliably reproduce it, but any exact written instructions never seem to work more than once.

chippo@chippo-Aspire-V3-731:~$ ASAN_OPTIONS="detect_leaks=0" freeciv-qt-26 -F
2: Loading tileset "amplio2".
2: Loading tileset "delta2".
2: Loading tileset "amplio2".
QSocketNotifier: Invalid socket 41 and type 'Read', disabling...
2: last message repeated 2 times
2: Loading tileset "delta2". =================================================================
2826ERROR: AddressSanitizer: heap-use-after-free on address 0x6030027b16b8 at pc 0x00000099c5e4 bp 0x7ffe6f90c350 sp 0x7ffe6f90c348
READ of size 1 at 0x6030027b16b8 thread T0
#0 0x99c5e3 in skip_intl_qualifier_prefix /home/chippo/Downloads/git_clones/freeciv/utility/fcintl.c:48:7
#1 0x845c3c in nation_set_by_rule_name /home/chippo/Downloads/git_clones/freeciv/common/nation.c:766:23
#2 0x726c40 in races_dialog::nationset_changed(int) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:984:10
#3 0x5924f0 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/meta_dialogs.cpp:369:21
#4 0x7efc52de9467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
#5 0x7efc5270fc74 in QComboBox::currentIndexChanged(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270c74)
#6 0x7efc52712075 (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x273075)
#7 0x7efc5271489c (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x27589c)
#8 0x7efc52714af2 in QComboBox::setCurrentIndex(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x275af2)
#9 0x723098 in races_dialog::update_nationset_combo() /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:487:18
#10 0x720f6c in races_dialog::races_dialog(player*, QWidget*) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:414:3
#11 0x7270e8 in popup_races_dialog /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:1034:23
#12 0x5a4170 in fc_client::slot_pick_nation() /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/pages.cpp:2045:3
#13 0x5565a6 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (fc_client::*)()>::call(void (fc_client::*)(), fc_client*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:152:13
#14 0x5564c8 in void QtPrivate::FunctionPointer<void (fc_client::*)()>::call<QtPrivate::List<>, void>(void (fc_client::*)(), fc_client*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:185:13
#15 0x5563e7 in QtPrivate::QSlotObject<void (fc_client::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:414:17
#16 0x7efc52de95c7 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b15c7)
#17 0x7efc526fe235 in QAbstractButton::clicked(bool) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x25f235)
#18 0x7efc526fe45d (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x25f45d)
#19 0x7efc526ff8a2 (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x2608a2)
#20 0x7efc526ffa64 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x260a64)
#21 0x7efc5264c04d in QWidget::event(QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1ad04d)
#22 0x7efc52609a85 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa85)
#23 0x7efc52613052 in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x174052)
#24 0x7efc52dbda99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
#25 0x7efc52612156 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173156)
#26 0x7efc5266814c (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1c914c)
#27 0x7efc5266afdb (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1cbfdb)
#28 0x7efc52609a85 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa85)
#29 0x7efc52612dff in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173dff)
#30 0x7efc52dbda99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
#31 0x7efc531a5d72 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x126d72)
#32 0x7efc531a75fa in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x1285fa)
#33 0x7efc5318126a in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x10226a)
#34 0x7efc39df628d (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x7928d)
#35 0x7efc5089084c in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5184c)
#36 0x7efc50890acf (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51acf)
#37 0x7efc50890b72 in g_main_context_iteration (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51b72)
#38 0x7efc52e156a4 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dd6a4)
#39 0x7efc52dbc63a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28463a)
#40 0x7efc52dc43a5 in QCoreApplication::exec() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28c3a5)
#41 0x74fe90 in fc_client::fc_main(QApplication*) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/fc_client.cpp:257:3
#42 0x50daa7 in qtg_ui_main(int, char**) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/gui_main.cpp:191:17
#43 0x50d369 in ui_main /home/chippo/Downloads/git_clones/freeciv/client/gui_interface.c:59:3
#44 0x5f96dd in client_main /home/chippo/Downloads/git_clones/freeciv/client/client_main.c:685:3
#45 0x50d87a in main /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/gui_main.cpp:114:10
#46 0x7efc520971e2 in __libc_start_main /build/glibc-4WA41p/glibc-2.30/csu/../csu/libc-start.c:308:16
#47 0x46341d in _start (/usr/local/bin/freeciv-qt-26+0x46341d)

0x6030027b16b8 is located 24 bytes inside of 32-byte region [0x6030027b16a0,0x6030027b16c0)
freed by thread T0 here:
#0 0x4db09d in free (/usr/local/bin/freeciv-qt-26+0x4db09d)
#1 0x524722 in QTypedArrayData<char>::deallocate(QArrayData*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qarraydata.h:239:9
#2 0x5226b6 in QByteArray::~QByteArray() /usr/include/x86_64-linux-gnu/qt5/QtCore/qbytearray.h:476:57
#3 0x726c1b in races_dialog::nationset_changed(int) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:982:3
#4 0x5924f0 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/meta_dialogs.cpp:369:21
#5 0x7efc52de9467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
#6 0x7efc5270fc74 in QComboBox::currentIndexChanged(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270c74)

previously allocated by thread T0 here:
#0 0x4db639 in realloc (/usr/local/bin/freeciv-qt-26+0x4db639)
#1 0x7efc52c025df in QArrayData::reallocateUnaligned(QArrayData*, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xca5df)

SUMMARY: AddressSanitizer: heap-use-after-free /home/chippo/Downloads/git_clones/freeciv/utility/fcintl.c:48:7 in skip_intl_qualifier_prefix
Shadow bytes around the buggy address:
0x0c06804ee280: fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 07 fa
0x0c06804ee290: fa fa fd fd fd fa fa fa fd fd fd fd fa fa fd fd
0x0c06804ee2a0: fd fd fa fa 00 00 00 fa fa fa fd fd fd fd fa fa
0x0c06804ee2b0: 00 00 00 00 fa fa 00 00 00 fa fa fa fd fd fd fd
0x0c06804ee2c0: fa fa fd fd fd fd fa fa fd fd fd fa fa fa fd fd
=>0x0c06804ee2d0: fd fd fa fa fd fd fd[fd]fa fa fd fd fd fa fa fa
0x0c06804ee2e0: fd fd fd fd fa fa 00 00 00 fa fa fa fa fa fa fa
0x0c06804ee2f0: fa fa fa fa fa fa fa fa fd fd fd fa fa fa fd fd
0x0c06804ee300: fd fd fa fa fd fd fd fd fa fa fd fd fd fa fa fa
0x0c06804ee310: fd fd fd fd fa fa fd fd fd fd fa fa 00 00 05 fa
0x0c06804ee320: fa fa fd fd fd fa fa fa 00 00 00 00 fa fa fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
2826ABORTING


Related issues

Related to Freeciv - Bug #859139: Qt: Temporary QByteArrays often used after their lifetime has endedClosed

History

#1 Updated by Marko Lindqvist 5 months ago

Which commit this was with? gui-qt/dialogs.cpp has changed several times recently (within a week) and I suspect those line numbers in your trace are not the same as in current S2_6 HEAD.

#2 Updated by Marko Lindqvist 5 months ago

Chippo Elder wrote:

Load a savegame, do a turn or two, start a New Game with a new ruleset, play a turn. Then when it's primed, Leave Game, Start New Game, don't touch anything (ruleset says default) except you click Pick Nation, and it dumps (which is quite pretty, with colours and all).

Do you use "Pick Nation" when starting the earlier games, or do you go by the random nation selection that is the default?

#3 Updated by Chippo Elder 5 months ago

Marko Lindqvist wrote:

Which commit this was with?

The dump I'm going to show you below is from 2.6.1+ (modified ec0f40dcfb), gui-qt client.

Marko Lindqvist wrote:

Do you use "Pick Nation" when starting the earlier games, or do you go by the random nation selection that is the default?

The latter. This is the first time during this program run that you touch the Pick Nation button.

So I followed my own instructions above and get this:

chippo@chippo-Aspire-V3-731:~$ ASAN_OPTIONS="abort_on_error=1:disable_coredump=0:unmap_shadow_on_exit=1" freeciv-qt-26
2: Loading tileset "amplio2".
2: Loading tileset "delta2".
QSocketNotifier: Invalid socket 41 and type 'Read', disabling...
2: Loading tileset "amplio2".
2: Loading tileset "delta2".
QSocketNotifier: Invalid socket 41 and type 'Read', disabling...
2: Loading tileset "delta2".
2: Loading tileset "amplio2".
2: Loading tileset "delta2".
=================================================================
==28888==ERROR: AddressSanitizer: heap-use-after-free on address 0x6030002b8598 at pc 0x0000009758f4 bp 0x7fff21e4b570 sp 0x7fff21e4b568
READ of size 1 at 0x6030002b8598 thread T0
#0 0x9758f3 in skip_intl_qualifier_prefix /home/chippo/Downloads/git_clones/freeciv/utility/fcintl.c:48:7
#1 0x82f3cc in nation_set_by_rule_name /home/chippo/Downloads/git_clones/freeciv/common/nation.c:766:23
#2 0x719750 in races_dialog::nationset_changed(int) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:984:10
#3 0x592450 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/meta_dialogs.cpp:369:21
#4 0x7f1a53d70467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
#5 0x7f1a53696c74 in QComboBox::currentIndexChanged(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270c74)
#6 0x7f1a53699075 (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x273075)
#7 0x7f1a5369b89c (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x27589c)
#8 0x7f1a5369b9bc (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x2759bc)
#9 0x7f1a536a1524 (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x27b524)
#10 0x7f1a53d70467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
#11 0x7f1a53696de5 in QComboBoxPrivateContainer::itemSelected(QModelIndex const&) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270de5)
#12 0x7f1a536974f9 in QComboBoxPrivateContainer::eventFilter(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x2714f9)
#13 0x7f1a53d447aa in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2857aa)
#14 0x7f1a53590a74 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa74)
#15 0x7f1a5359a052 in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x174052)
#16 0x7f1a53d44a99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
#17 0x7f1a53599156 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173156)
#18 0x7f1a535efad3 (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1c9ad3)
#19 0x7f1a535f1fdb (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1cbfdb)
#20 0x7f1a53590a85 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa85)
#21 0x7f1a53599dff in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173dff)
#22 0x7f1a53d44a99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
#23 0x7f1a5412cd72 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x126d72)
#24 0x7f1a5412e5fa in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x1285fa)
#25 0x7f1a5410826a in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x10226a)
#26 0x7f1a39dd128d (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x7928d)
#27 0x7f1a5181784c in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5184c)
#28 0x7f1a51817acf (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51acf)
#29 0x7f1a51817b72 in g_main_context_iteration (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51b72)
#30 0x7f1a53d9c6a4 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dd6a4)
#31 0x7f1a53d4363a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28463a)
#32 0x7f1a53d4b3a5 in QCoreApplication::exec() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28c3a5)
#33 0x742200 in fc_client::fc_main(QApplication*) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/fc_client.cpp:257:3
#34 0x50daf7 in qtg_ui_main(int, char**) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/gui_main.cpp:191:17
#35 0x50d3b9 in ui_main /home/chippo/Downloads/git_clones/freeciv/client/gui_interface.c:59:3
#36 0x5f9346 in client_main /home/chippo/Downloads/git_clones/freeciv/client/client_main.c:685:3
#37 0x50d8ca in main /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/gui_main.cpp:114:10
#38 0x7f1a5301e1e2 in __libc_start_main /build/glibc-4WA41p/glibc-2.30/csu/../csu/libc-start.c:308:16
#39 0x46341d in _start (/usr/local/bin/freeciv-qt-26+0x46341d)

0x6030002b8598 is located 24 bytes inside of 32-byte region [0x6030002b8580,0x6030002b85a0)
freed by thread T0 here:
#0 0x4db0ed in free (/usr/local/bin/freeciv-qt-26+0x4db0ed)
#1 0x524772 in QTypedArrayData<char>::deallocate(QArrayData*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qarraydata.h:239:9
#2 0x522706 in QByteArray::~QByteArray() /usr/include/x86_64-linux-gnu/qt5/QtCore/qbytearray.h:476:57
#3 0x71972b in races_dialog::nationset_changed(int) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/dialogs.cpp:982:3
#4 0x592450 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/chippo/Downloads/git_clones/freeciv/client/gui-qt/meta_dialogs.cpp:369:21
#5 0x7f1a53d70467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
#6 0x7f1a53696c74 in QComboBox::currentIndexChanged(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270c74)

previously allocated by thread T0 here:
#0 0x4db689 in realloc (/usr/local/bin/freeciv-qt-26+0x4db689)
#1 0x7f1a53b895df in QArrayData::reallocateUnaligned(QArrayData*, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xca5df)

SUMMARY: AddressSanitizer: heap-use-after-free /home/chippo/Downloads/git_clones/freeciv/utility/fcintl.c:48:7 in skip_intl_qualifier_prefix
Shadow bytes around the buggy address:
0x0c068004f060: fa fa fa fa fa fa fa fa fd fd fd fd fa fa fa fa
0x0c068004f070: fa fa fa fa fa fa fa fa fa fa fd fd fd fd fa fa
0x0c068004f080: fa fa fa fa fa fa fa fa fa fa fa fa fd fd fd fa
0x0c068004f090: fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa fd fd
0x0c068004f0a0: fd fd fa fa fd fd fd fd fa fa fa fa fa fa fa fa
=>0x0c068004f0b0: fd fd fd[fd]fa fa fa fa fa fa fa fa 00 00 00 fa
0x0c068004f0c0: fa fa 00 00 00 00 fa fa fd fd fd fd fa fa fa fa
0x0c068004f0d0: fa fa fa fa 00 00 00 00 fa fa fa fa fa fa fa fa
0x0c068004f0e0: 00 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa
0x0c068004f0f0: fa fa fd fd fd fd fa fa fd fd fd fa fa fa fa fa
0x0c068004f100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
@==28888==ABORTING
AddressSanitizer:DEADLYSIGNAL
Aborted (core dumped)

And since I worked out my ASAN core dump troubles, I can get a full backtrace:

Core was generated by `freeciv-qt-26'.
Program terminated with signal SIGABRT, Aborted.
#0 _GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7f1a4e3baac0 (LWP 28888))]
(gdb) bt full
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
set = {
_val = {0, 5106555, 895, 0, 0, 281470681751461, 0, 0, 0, 0, 0, 0, 0, 0, 206158430216, 140733762021568}}
pid = <optimized out>
tid = <optimized out>
#1 0x00007f1a5301c899 in __GI_abort () at abort.c:79
save_stage = 1
act = {__sigaction_handler = {sa_handler = 0x3fe6b5ce50b7821a, sa_sigaction = 0x3fe6b5ce50b7821a}, sa_mask = {__val = {0, 139751067971584, 13731440, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0}}, sa_flags = 0, sa_restorer = 0xc85e68 <__asan::error_message_buf_mutex>}
sigs = {__val = {32, 0 <repeats 15 times>}}
#2 0x00000000004f8e27 in ()
#3 0x00000000004f7801 in ()
#4 0x00000000004df389 in ()
#5 0x00000000004e0aff in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#6 0x00000000004e11d8 in __asan_report_load1 ()
#7 0x00000000009758f4 in skip_intl_qualifier_prefix (str=0x6030002b8598 "all") at fcintl.c:48
ptr = <optimized out>
#8 0x000000000082f3cd in nation_set_by_rule_name (name=0x2 <error: Cannot access memory at address 0x2>) at nation.c:766
qname = <optimized out>
#9 0x0000000000719751 in races_dialog::nationset_changed(int) (this=<optimized out>, index=<optimized out>) at dialogs.cpp:984
rule_name = {static null = {<No data fields>}, d = 0x60300087bcb0}
poption = 0x627000f7adb0
rn = 0x6030002b8598 "all"
#10 0x0000000000592451 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
(_o=0x2, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at meta_dialogs.cpp:369
_t = 0x2
#11 0x00007f1a53d70468 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#12 0x00007f1a53696c75 in QComboBox::currentIndexChanged(int) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007f1a53699076 in () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007f1a5369b89d in () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#15 0x00007f1a5369b9bd in () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007f1a536a1525 in () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007f1a53d70468 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#18 0x00007f1a53696de6 in QComboBoxPrivateContainer::itemSelected(QModelIndex const&) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#19 0x00007f1a536974fa in QComboBoxPrivateContainer::eventFilter(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007f1a53d447ab in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#21 0x00007f1a53590a75 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007f1a5359a053 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007f1a53d44a9a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#24 0x00007f1a53599157 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) ()
at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007f1a535efad4 in () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007f1a535f1fdc in () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007f1a53590a86 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
--Type <RET> for more, q to quit, c to continue without paging--c
#28 0x00007f1a53599e00 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007f1a53d44a9a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#30 0x00007f1a5412cd73 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#31 0x00007f1a5412e5fb in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#32 0x00007f1a5410826b in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#33 0x00007f1a39dd128e in () at /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#34 0x00007f1a5181784d in g_main_context_dispatch () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007f1a51817ad0 in () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#36 0x00007f1a51817b73 in g_main_context_iteration () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#37 0x00007f1a53d9c6a5 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#38 0x00007f1a53d4363b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#39 0x00007f1a53d4b3a6 in QCoreApplication::exec() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#40 0x0000000000742201 in fc_client::fc_main(QApplication*) (this=<optimized out>, qapp=<optimized out>) at fc_client.cpp:257
#41 0x000000000050daf8 in qtg_ui_main(int, char**) (argc=<optimized out>, argv=<optimized out>) at gui_main.cpp:191
app_icon = <optimized out>
qpm = <optimized out>
#42 0x000000000050d3ba in ui_main (argc=2, argv=0x7fff21e4a5b0) at gui_interface.c:59
#43 0x00000000005f9347 in client_main (argc=1, argv=<optimized out>) at client_main.c:685
loglevel = <optimized out>
fatal_assertions = -1
option = <optimized out>
ui_separator = <optimized out>
ui_options = <optimized out>
aii = 1
i = <optimized out>
#44 0x000000000050d8cb in main(int, char**) (argc=2, argv=0x7fff21e4a5b0) at gui_main.cpp:114

#4 Updated by Marko Lindqvist 5 months ago

I still don't fully understand what happens here. If we're lucky, attached wild experiment helps, but I'm not surprised if it doesn't.

#5 Updated by Marko Lindqvist 5 months ago

If the problem is in the lifetime of the temporary QByteArray when using construct like 'char *buf = str.toLocal8Bit().data()', the bad news is that Qt-client and ruledit code has lots of such usage.
And I now think it's a bug in principle, even if this one is not about it.

grep -r "data()" client/qui-qt tools/ruledit

#6 Updated by Chippo Elder 5 months ago

Marko Lindqvist wrote:

I still don't fully understand what happens here. If we're lucky, attached wild experiment helps, but I'm not surprised if it doesn't.

I can't trigger it anymore. I tried a lot. The combination of the two patches (0007-Do-not-unqueue-mapview-updates-when-tileset-is-not-f.patch and QByteArrayLifetime.patch) has done the trick. Close the ticket.

#7 Updated by Chippo Elder 5 months ago

In my efforts to discover why I no longer have a fixed-ghost-seen tree (and for simpler repeatibility reasons), I dropped the QByteArrayLifetime.patch from my workflow. Now I'm being hit by use-after-free regularly.

So I'm putting it back in.

This last one happened under quite different circumstances than earlier reported. I had been playing around in several savegames during that session in different rulesets etc. I had just started a New Game, had configured ruleset, players and difficulty. I had not gone into game options yet, 'cos that's where the Save is, and I want that ruleset to remember that I always want the Extended set of Nations. I was already in the choose-your-nation screen, fiddling with moving that window around on my screen and clicking all around on it, looking for I-dunno-what. Then I wanted to switch to Extended and clicked on the dropdown. It appeared in the correct place. I paused a good while, to take a screenshot, file it, and some other stuff. Then I clicked on Extended and the dump happened.

This BT looks very similar to the last, but there are some largish differences like the "set = {__val = {" values, so I'll include it here in case.

Core was generated by `freeciv-qt-26 -F'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7fd803b0eb80 (LWP 1282733))]
(gdb) bt full
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
        set = 
            {__val = {0, 281470681751461, 140724658498656, 140724658498656, 140724658498656, 5200464, 206158430216, 140724658499296, 140724658499104, 5111467, 140724658498720, 13250856, 140724658502544, 140724658502536, 140724658502448, 13849992}}
        pid = <optimized out>
        tid = <optimized out>
#1  0x00007fd808e64899 in __GI_abort () at abort.c:79
        save_stage = 1
        act = 
          {__sigaction_handler = {sa_handler = 0x400, sa_sigaction = 0x400}, sa_mask = {__val = {13850928, 140565873823744, 13850928, 2, 2, 2, 140724658499064, 140565873823840, 4686603, 2, 0, 0, 0, 0, 0, 0}}, sa_flags = 0, sa_restorer = 0xca3128 <__asan::error_message_buf_mutex>}
        sigs = {__val = {32, 0 <repeats 15 times>}}
#2  0x00000000004fa157 in  ()
#3  0x00000000004f8b31 in  ()
#4  0x00000000004e06b9 in  ()
#5  0x00000000004e1e2f in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()                                                                                                          
#6  0x00000000004e2508 in __asan_report_load1 ()
#7  0x00000000009510a4 in skip_intl_qualifier_prefix (str=0x603000723058 "all") at fcintl.c:48
        ptr = <optimized out>
#8  0x00000000007fa6ed in nation_set_by_rule_name (name=0x2 <error: Cannot access memory at address 0x2>) at nation.c:766
        qname = <optimized out>
#9  0x0000000000728531 in races_dialog::nationset_changed(int) (this=<optimized out>, index=<optimized out>) at dialogs.cpp:984
        rule_name = {static null = {<No data fields>}, d = 0x6030008cd190}
        poption = 0x62700003fdb0
        rn = 0x603000723058 "all" 
#10 0x0000000000593a11 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
    (_o=0x2, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at meta_dialogs.cpp:369
        _t = 0x2
#11 0x00007fd809ca8468 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#12 0x00007fd8095cec75 in QComboBox::currentIndexChanged(int) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007fd8095d1076 in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007fd8095d389d in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#15 0x00007fd8095d39bd in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007fd8095d9525 in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007fd809ca8468 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#18 0x00007fd8095cede6 in QComboBoxPrivateContainer::itemSelected(QModelIndex const&) ()
    at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#19 0x00007fd8095cf4fa in QComboBoxPrivateContainer::eventFilter(QObject*, QEvent*) ()
    at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
--Type <RET> for more, q to quit, c to continue without paging--c
#20 0x00007fd809c7c7ab in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5                                                                                                                   
#21 0x00007fd8094c8a75 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007fd8094d2053 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007fd809c7ca9a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#24 0x00007fd8094d1157 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5                                                               
#25 0x00007fd809527ad4 in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007fd809529fdc in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007fd8094c8a86 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007fd8094d1e00 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007fd809c7ca9a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#30 0x00007fd80a066d73 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5                                                                                                        
#31 0x00007fd80a0685fb in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#32 0x00007fd80a04226b in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5                                                                                                        
#33 0x00007fd7eff3128e in  () at /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#34 0x00007fd806ef184d in g_main_context_dispatch () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007fd806ef1ad0 in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#36 0x00007fd806ef1b73 in g_main_context_iteration () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#37 0x00007fd809cd46a5 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5                                                                                                                  
#38 0x00007fd809c7b63b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#39 0x00007fd809c833a6 in QCoreApplication::exec() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#40 0x0000000000751781 in fc_client::fc_main(QApplication*) (this=<optimized out>, qapp=<optimized out>) at fc_client.cpp:257
#41 0x000000000050ee76 in qtg_ui_main(int, char**) (argc=<optimized out>, argv=<optimized out>) at gui_main.cpp:193
        app_icon = <optimized out>
        qpm = <optimized out>
#42 0x000000000050e6fa in ui_main (argc=2, argv=0x7ffd0347ebd0) at gui_interface.c:59
#43 0x00000000005fafde in client_main (argc=1, argv=<optimized out>) at client_main.c:685
        loglevel = <optimized out>
        fatal_assertions = <optimized out>
        option = <optimized out>
        ui_separator = <optimized out>
        ui_options = 0
        aii = 1
        i = <optimized out>
#44 0x000000000050ebfb in main(int, char**) (argc=2, argv=0x7ffd0347ebd0) at gui_main.cpp:114

I betcha that with the QByteArrayLifetime.patch applied, I don't see this again.

#8 Updated by Chippo Elder 5 months ago

Seen in master, 3.0.92-dev (modified 5fa96c064c).

chippo@chippo-Aspire-V3-731:~$ ASAN_OPTIONS="abort_on_error=1:disable_coredump=0:unmap_shadow_on_exit=1:detect_leaks=0" freeciv-qt-dev -F
1: Lost connection to server: server disconnected.
QSocketNotifier: Invalid socket 41 and type 'Read', disabling...
3: Loading tileset "amplio2".
=================================================================
==592689==ERROR: AddressSanitizer: heap-use-after-free on address 0x6030002be868 at pc 0x0000009d06c4 bp 0x7fffb727e250 sp 0x7fffb727e248
READ of size 1 at 0x6030002be868 thread T0
    #0 0x9d06c3 in skip_intl_qualifier_prefix /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/utility/fcintl.c:48:7
    #1 0x86b6bc in nation_set_by_rule_name /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/common/nation.c:766:23
    #2 0x63c590 in races_dialog::nationset_changed(int) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/dialogs.cpp:1097:10
    #3 0x700f50 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/meta_dialogs.cpp:369:21
    #4 0x7fdc568d8467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
    #5 0x7fdc561fec74 in QComboBox::currentIndexChanged(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270c74)
    #6 0x7fdc56201075  (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x273075)
    #7 0x7fdc5620389c  (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x27589c)
    #8 0x7fdc562039bc  (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x2759bc)
    #9 0x7fdc56209524  (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x27b524)
    #10 0x7fdc568d8467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
    #11 0x7fdc561fede5 in QComboBoxPrivateContainer::itemSelected(QModelIndex const&) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270de5)
    #12 0x7fdc561ff4f9 in QComboBoxPrivateContainer::eventFilter(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x2714f9)
    #13 0x7fdc568ac7aa in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2857aa)
    #14 0x7fdc560f8a74 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa74)
    #15 0x7fdc56102052 in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x174052)
    #16 0x7fdc568aca99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
    #17 0x7fdc56101156 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173156)
    #18 0x7fdc56157ad3  (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1c9ad3)
    #19 0x7fdc56159fdb  (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1cbfdb)
    #20 0x7fdc560f8a85 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa85)
    #21 0x7fdc56101dff in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173dff)
    #22 0x7fdc568aca99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
    #23 0x7fdc56c94d72 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x126d72)
    #24 0x7fdc56c965fa in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x1285fa)
    #25 0x7fdc56c7026a in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0x10226a)
    #26 0x7fdc4e88f28d  (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x7928d)
    #27 0x7fdc53cf184c in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5184c)
    #28 0x7fdc53cf1acf  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51acf)
    #29 0x7fdc53cf1b72 in g_main_context_iteration (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51b72)
    #30 0x7fdc569046a4 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dd6a4)
    #31 0x7fdc568ab63a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28463a)
    #32 0x7fdc568b33a5 in QCoreApplication::exec() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28c3a5)
    #33 0x66a680 in fc_client::fc_main(QApplication*) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/fc_client.cpp:257:3
    #34 0x50e135 in qtg_ui_main(int, char**) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/gui_main.cpp:179:17
    #35 0x50d9b9 in ui_main /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui_interface.c:59:3
    #36 0x512627 in client_main /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/client_main.c:685:3
    #37 0x50deba in main /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/gui_main.cpp:100:10
    #38 0x7fdc55a961e2 in __libc_start_main /build/glibc-4WA41p/glibc-2.30/csu/../csu/libc-start.c:308:16
    #39 0x463a5d in _start (/usr/local/bin/freeciv-qt-dev+0x463a5d)

0x6030002be868 is located 24 bytes inside of 32-byte region [0x6030002be850,0x6030002be870)
freed by thread T0 here:
    #0 0x4db6dd in free (/usr/local/bin/freeciv-qt-dev+0x4db6dd)
    #1 0x5e2552 in QTypedArrayData<char>::deallocate(QArrayData*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qarraydata.h:239:9
    #2 0x5df696 in QByteArray::~QByteArray() /usr/include/x86_64-linux-gnu/qt5/QtCore/qbytearray.h:476:57
    #3 0x63c56b in races_dialog::nationset_changed(int) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/dialogs.cpp:1095:3
    #4 0x700f50 in races_dialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/meta_dialogs.cpp:369:21
    #5 0x7fdc568d8467 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1467)
    #6 0x7fdc561fec74 in QComboBox::currentIndexChanged(int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x270c74)

previously allocated by thread T0 here:
    #0 0x4dbc79 in realloc (/usr/local/bin/freeciv-qt-dev+0x4dbc79)
    #1 0x7fdc566f15df in QArrayData::reallocateUnaligned(QArrayData*, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xca5df)

SUMMARY: AddressSanitizer: heap-use-after-free /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/utility/fcintl.c:48:7 in skip_intl_qualifier_prefix
Shadow bytes around the buggy address:
  0x0c068004fcb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c068004fcc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c068004fcd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c068004fce0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c068004fcf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c068004fd00: fa fa fa fa fa fa fa fa fa fa fd fd fd[fd]fa fa
  0x0c068004fd10: fa fa fa fa fa fa fa fa fa fa fa fa fd fd fd fd
  0x0c068004fd20: fa fa fd fd fd fd fa fa 00 00 00 02 fa fa fd fd
  0x0c068004fd30: fd fd fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
  0x0c068004fd40: fd fd fd fd fa fa fd fd fd fa fa fa fd fd fd fa
  0x0c068004fd50: fa fa 00 00 00 00 fa fa 00 00 00 02 fa fa fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==592689==ABORTING
Aborted (core dumped)

I'm going to try the QByteArrayLifetime.patch and see if that helps.

#9 Updated by Chippo Elder 5 months ago

It applies cleanly in master and seems to do the job. I haven't managed to trigger this bug in master since applying it. I recommend that it gets committed.

#10 Updated by Marko Lindqvist 5 months ago

  • Status changed from New to In Progress
  • Assignee set to Marko Lindqvist
  • Target version set to 2.6.2

Marko Lindqvist wrote:

... the lifetime of the temporary QByteArray when using construct like 'char *buf = str.toLocal8Bit().data()', the bad news is that Qt-client and ruledit code has lots of such usage.

-> Bug #859139

#11 Updated by Marko Lindqvist 5 months ago

Patch with commit message. No functional changes.

#12 Updated by Marko Lindqvist 5 months ago

  • Status changed from Resolved to Closed

#13 Updated by Jacob Nevins 5 months ago

  • Related to Bug #859139: Qt: Temporary QByteArrays often used after their lifetime has ended added

Also available in: Atom PDF