Как сделать AddressSanitizer не останавливаться после одной ошибки (и других проблем)
Я запускаю OS X, 10.8.5; я установил llvm 3.4 через homebrew (clang version 3.4 (tags/RELEASE_34/final) ), и я строю с-fsanitize=address. Я могу заставить asan работать с простыми демо-программами, но при построении против нашей кодовой базы у меня есть несколько проблем (хотя я действительно хотел бы получить ответ на #1):
-
сторонние библиотеки генерируют ошибки asan, и asan завершает мое приложение при первом возникновении. Я думал, что будет будьте своего рода (время выполнения/время компиляции), чтобы сказать asan продолжать идти после обнаружения ошибки. В частности, я вижу следующее:
bash-3.2$ ASAN_SYMBOLIZER_PATH=/usr/local/Cellar/llvm34/3.4/lib/llvm-3.4/bin/llvm-symbolizer ./unit_test Start testing of PathTrieTest Config: Using QTest library 4.8.2, Qt 4.8.2 PASS : PathTrieTest::initTestCase() PASS : PathTrieTest::pathTrieNodeTest() ================================================================= ==76647==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61600019e588 at pc 0x10891ddd3 bp 0x11312ba90 sp 0x11312ba58 WRITE of size 48830 at 0x61600019e588 thread T3 #0 0x10891ddd2 in wrap_readdir_r (/usr/local/lib/llvm-3.4/lib/clang/3.4/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x11dd2) #1 0x10ac23571 in QFileSystemIterator::advance(QFileSystemEntry&, QFileSystemMetaData&) (/Volumes/ToolChain/qt-4.8/lib/QtCore.framework/Versions/4/QtCore+0xef571) #2 0x10abd86d3 in QDirIteratorPrivate::advance() (/Volumes/ToolChain/qt-4.8/lib/QtCore.framework/Versions/4/QtCore+0xa46d3) #3 0x10abd7a7f in QDirIteratorPrivate::QDirIteratorPrivate(QFileSystemEntry const&, QStringList const&, QFlags<QDir::Filter>, QFlags<QDirIterator::IteratorFlag>, bool) (/Volumes/ToolChain/qt-4.8/lib/QtCore.framework/Versions/4/QtCore+0xa3a7f) #4 0x10abd8b68 in QDirIterator::QDirIterator(QDir const&, QFlags<QDirIterator::IteratorFlag>) (/Volumes/ToolChain/qt-4.8/lib/QtCore.framework/Versions/4/QtCore+0xa4b68) #5 0x10abd7609 in QDirPrivate::initFileLists(QDir const&) const (/Volumes/ToolChain/qt-4.8/lib/QtCore.framework/Versions/4/QtCore+0xa3609) #6 0x10abd5394 in QDir::count() const (/Volumes/ToolChain/qt-4.8/lib/QtCore.framework/Versions/4/QtCore+0xa1394) #7 0x1084c205d in get_count(QFileInfo&) /Users/stebro/dev_vm/ui/ui/fsinfoprovider.cpp:36 ...
эта ошибка не приводит к завершению работы приложения, когда оно запущено незапланированным.
-
Я не могу получить код для связи при использовании параметров-fsanitize=undefined (или-fsanitize=address,undefined). Я включаю строку-fsanitize=undefined в обе мои команды compile & link, но я получаю такие ошибки ссылок as:
Undefined symbols for architecture x86_64: "typeinfo for __cxxabiv1::__class_type_info", referenced from: __ubsan::checkDynamicType(void*, void*, unsigned long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o) isDerivedFromAtOffset(__cxxabiv1::__class_type_info const*, __cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o) findBaseAtOffset(__cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o) "typeinfo for __cxxabiv1::__si_class_type_info", referenced from: isDerivedFromAtOffset(__cxxabiv1::__class_type_info const*, __cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o) findBaseAtOffset(__cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o) "typeinfo for __cxxabiv1::__vmi_class_type_info", referenced from: isDerivedFromAtOffset(__cxxabiv1::__class_type_info const*, __cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o) findBaseAtOffset(__cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.o)
-
Я не могу заставить черные списки работать, и -mllvm-asan-globals=0 или-mllvm-asan-stack=0 не работает, как я ожидал. Например, последние не подавляют генерацию ошибки, указанной в #1 выше, и создание черного списка, который выглядит так, как показано ниже, также не подавляет ошибки:
fun:QDirPrivate::initFileLists fun:get_count fun:*opendir2*
-
наконец, исполняемые файлы, созданные с помощью этих параметров asan, вызывают сбой lldb. Я использую lldb поставляется с инструментами XCode 5; не было lldb, развернутого с пакетом homebew llvm, и я не могу понять, как его построить. Инструкции по сборке Введите описание ссылки здесь есть мертвая ссылка, которая указывает на источник, который вы должны использовать; потянув источник непосредственно из репозитория svn, используя:
svn co http://llvm.org/svn/llvm-project/lldb/tags/RELEASE_34/final lldb
приводит к коду, который не компилируется (ошибки предоставляются по запросу).
3 ответов
вы можете построить свой проект с -fsanitize=address -fsanitize-recover=address
флаги и запуск с переменной окружения ASAN_OPTIONS=halt_on_error=0
.
Источник: https://github.com/google/sanitizers/wiki/AddressSanitizer
- ошибки Адресуемости (особенно повреждения памяти, такие как запись OOB, о которой Вы упомянули) обычно достаточно серьезны, чтобы беспокоиться. Игнорирование их не может отменить их эффекты, и программа, скорее всего, рухнет в совершенно не связанном месте после того, как вы пропустили повреждение кучи. Вы можете попытаться создать свой собственный Clang с проверками в readdir_r отключен, но я бы попытался исправить ошибку в первую очередь.
- можете ли вы подать ошибку с шагами воспроизведения на http://code.google.com/p/address-sanitizer ?
- черные списки отключают только проверки адресуемости в функциях черного списка, не инструментируя их, они не проверяют стеки для определенных кадров. Ваша конкретная проверка происходит в перехватчике функций, скомпилированном в библиотеку времени выполнения, поэтому вы даже не можете занести это в черный список. Если ошибка в #1 находится в некоторой системной библиотеке и не может быть легко обработана, мы можем посмотреть на добавление опции выполнения для отключения readdir_r проверяет.
- опять же, отчет об ошибке будет оценен.
кстати -- я нашел способ обойти это переполнение кучи в Qt, если вы строите его из источника. Я считаю, что проблема связана с 32-битными / 64-битными inodes (_DARWIN_FEATURE_64_BIT_INODE
не определяется, когда я по какой-то причине создаю Qt).
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 029b989..76b176f 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -75,6 +75,7 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX); if (maxPathName == size_t(-1)) maxPathName = FILENAME_MAX; + maxPathName = 99999; maxPathName += sizeof(QT_DIRENT) + 1; QT_DIRENT *p = reinterpret_cast(::malloc(maxPathName));