5

I'm trying a project that uses Qt with MSVC 2019 with Address Sanitizer. I built with Address Sanitizer the project, but didn't rebuild all libs, including Qt.

it crashes inside Qt in resource initialization (with qRegisterResourceData in the call stack).

Is this:

  • Misuse of address sanitizer, like, I should rebuild Qt DLLs with it too?
  • An issue in Qt I should investigate deeper?
  • Known Qt issue?

I've recreated the issue in Widget application created by Wizard by default. The call stack is as follows:

>   KernelBase.dll!RaiseException() Unknown
    QtWidgetsApplication1.exe!__vcasan::OnAsanReport(const char * description, const char * report, bool __throw) Line 602  C++
    QtWidgetsApplication1.exe!__vcasan::ReportCallback(const char * szReport) Line 325  C++
    clang_rt.asan_dbg_dynamic-x86_64.dll!__asan::ScopedInErrorReport::~ScopedInErrorReport(void)    Unknown
    clang_rt.asan_dbg_dynamic-x86_64.dll!__asan::ReportMallocUsableSizeNotOwned(unsigned __int64,struct __sanitizer::BufferedStackTrace *)  Unknown
    clang_rt.asan_dbg_dynamic-x86_64.dll!__asan::asan_malloc_usable_size(void const *,unsigned __int64,unsigned __int64)    Unknown
    clang_rt.asan_dbg_dynamic-x86_64.dll!_recalloc()    Unknown
    ucrtbased.dll!_register_onexit_function::__l2::<lambda>() Line 112  C++
    ucrtbased.dll!__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) &,void <lambda>(void)>(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, _register_onexit_function::__l2::int <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 204    C++
    ucrtbased.dll!__acrt_lock_and_call<int <lambda>(void)>(const __acrt_lock_id lock_id, _register_onexit_function::__l2::int <lambda>(void) && action) Line 980    C++
    ucrtbased.dll!_register_onexit_function(_onexit_table_t * table, int(*)() function) Line 149    C++
    Qt5Cored.dll!_onexit(int(*)() function) Line 267    C++
    Qt5Cored.dll!atexit(void(*)() function) Line 275    C++
    Qt5Cored.dll!QPropertyAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) Line 268   C++
    Qt5Cored.dll!QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) Line 991   C++
    Qt5Cored.dll!QAbstractAnimation::start(QAbstractAnimation::DeletionPolicy policy) Line 1362 C++
    Qt5Widgetsd.dll!QWidgetAnimator::animate(QWidget * widget, const QRect & _final_geometry, bool animate) Line 114    C++
    Qt5Widgetsd.dll!QToolBarAreaLayout::apply(bool animate) Line 936    C++
    Qt5Widgetsd.dll!QMainWindowLayoutState::apply(bool animated) Line 687   C++
    Qt5Widgetsd.dll!QMainWindowLayout::applyState(QMainWindowLayoutState & newState, bool animate) Line 2759    C++
    Qt5Widgetsd.dll!QMainWindowLayout::setGeometry(const QRect & _r) Line 1979  C++
    Qt5Widgetsd.dll!QLayoutPrivate::doResize() Line 596 C++
    Qt5Widgetsd.dll!QLayout::activate() Line 1119   C++
    Qt5Widgetsd.dll!QWidgetPrivate::setVisible(bool visible) Line 8083  C++
    Qt5Widgetsd.dll!QWidget::setVisible(bool visible) Line 8044 C++
    Qt5Widgetsd.dll!QWidget::show() Line 7670   C++
    QtWidgetsApplication1.exe!main(int argc, char * * argv) Line 9  C++
    QtWidgetsApplication1.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 97    C++
    QtWidgetsApplication1.exe!invoke_main() Line 107    C++
    QtWidgetsApplication1.exe!__scrt_common_main_seh() Line 288 C++
    QtWidgetsApplication1.exe!__scrt_common_main() Line 331 C++
    QtWidgetsApplication1.exe!WinMainCRTStartup(void * __formal) Line 17    C++
    kernel32.dll!BaseThreadInitThunk()  Unknown
    ntdll.dll!RtlUserThreadStart()  Unknown

The output:

Address 0x01c416f8eda0 is a wild pointer.
SUMMARY: AddressSanitizer: bad-malloc_usable_size (C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\clang_rt.asan_dbg_dynamic-x86_64.dll+0x18004e63a) in _asan_wrap_GlobalSize+0x4b948
Address Sanitizer Error: bad-malloc_usable_size
Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
  • Please provide crash report (at least crashed thread call stack). – Marek R Oct 22 '21 at 15:03
  • 1
    I may be outdated on this topic, but a while back (CppCon 20) the only option to avoid recompiling all libs was to statically linking the "parent" executable to the asan lib - https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/ – diogoslima Oct 22 '21 at 19:37
  • Reported to Developer Community https://developercommunity.visualstudio.com/t/address-sanitizer-reports-presumably-false-error-o/1562042 – Alex Guteniev Oct 24 '21 at 08:14

1 Answers1

8

The issue is load order.

Qt happens to load before ASan and load C/C++ runtime before ASan DLLs loaded. Qt performs some initialization. So the memory is malloced without ASan knowledge, and later ASan sees realloc without prior malloc, which it reports.

Building Qt with ASan should resolve the issue, I have not tried that, as I have found a workaround that does not involve Qt rebuild.

The workaround: just make Qt DLLs import ASan DLLs. For me it is via the following commands:

setdll /d:clang_rt.asan_dbg_dynamic-x86_64.dll <path_to_deployed_debug_app>\Qt5Cored.dll

setdll /d:clang_rt.asan_dynamic-x86_64.dll <path_to_deployed_release_app>\Qt5Core.dll

setdll is a tool from Detours library that may be obtained from https://github.com/microsoft/Detours and then built using nmake.

clang_rt.asan_dynamic-x86_64.dll and clang_rt.asan_dbg_dynamic-x86_64.dll should be available directly or from %path% when executing this, the most convenient way is to execute the command from VS Tools command prompt.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
  • I managed to get things started thanks to your response but it seems that VS2019 sanitizer version does not track leaks. In clang/gcc linux version one does not need to specify anything for this feature. – Ghita Nov 04 '21 at 13:27
  • @Ghita, address sanitizer in MSVC is currently limited, but I believe more features will be added with VS2022 updates. Not sure about leaks though. – Alex Guteniev Nov 04 '21 at 13:50
  • 1
    @Ghita, maybe if your code is ready to compile with clang-cl toolset, you can try ASan from there – Alex Guteniev Nov 04 '21 at 15:38
  • Yeah. I initially tried that because of maturity. Seems though that I need to rebuild QT also for that with clang-cl and didn't find how to do it. There seems to be some kind of binary incompatibilities (link time) if QT is not build with that :-) – Ghita Nov 04 '21 at 16:09
  • clang-cl targets to be binary compatible, and is able to consume MSVC STL and SDK headers. So if it was not able to link Qt binaries, it might be worth investigating and reporting a repro to https://bugs.llvm.org – Alex Guteniev Nov 04 '21 at 16:13