我正在嘗試一個將 Qt 與 MSVC 2019 與 Address Sanitizer 結合使用的專案。我使用 Address Sanitizer 構建了該專案,但沒有重建所有庫,包括 Qt。
它在資源初始化(qRegisterResourceData在呼叫堆疊中)時在 Qt 內崩潰。
這是:
- 濫用地址清理程式,例如,我也應該用它重建 Qt DLL 嗎?
- Qt 中的一個問題我應該深入調查嗎?
- 已知的 Qt 問題?
默認情況下,我在向導創建的小部件應用程式中重新創建了該問題。呼叫堆疊如下:
> 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
輸出:
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
uj5u.com熱心網友回復:
問題是加載順序。
Qt 恰好在 ASan 之前加載并在 ASan DLL 加載之前加載 C/C 運行時。Qt 執行一些初始化。所以記憶體是在malloc沒有 ASan 知識的情況下被編輯的,后來 ASanrealloc沒有先見malloc,它報告了。
使用 ASan 構建 Qt 應該可以解決問題,我還沒有嘗試過,因為我找到了一種不涉及 Qt 重建的解決方法。
解決方法:只需讓 Qt DLL 匯入 ASan DLL。對我來說,它是通過以下命令:
setdll /d:clang_rt.asan_dbg_dynamic-x86_64.dll <path_to_deployed_debug_app>\Qt5Cored.dll <path_to_deployed_debug_app>\Qt5Guid.dll
setdll /d:clang_rt.asan_dynamic-x86_64.dll <path_to_deployed_release_app>\Qt5Core.dll <path_to_deployed_release_app>\Qt5Gui.dll
setdll是 Detours 庫中的一個工具,可以從https://github.com/microsoft/Detours獲得,然后使用nmake.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/335102.html
上一篇:Qmlc 不同的委托qtmvc
