Comment faire Adresssanitizer pas arrêter après une erreur (et d'autres questions)

J'exécute OS X, 10.8.5; j'ai installé llvm 3.4 via homebrew (clang version 3.4 (tags/RELEASE_34 / final) ), et je construis avec-fsanitize=adresse. Je peux obtenir un travail asan avec des programmes de démo simples, mais en construisant contre notre codebase, j'ai plusieurs problèmes (bien que je voudrais vraiment juste une réponse à #1):

  1. les bibliothèques tierces génèrent des erreurs asan, et asan termine mon application à la première occurrence. Je pense qu'il y aurait une sorte d'option (runtime/compiler-time) pour dire à asan de continuer après avoir trouvé une erreur. Plus précisément, je vois ceci:

    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
    ...
    

    cette erreur ne provoque pas l'arrêt de l'application quand elle est en cours d'exécution.

  2. Je ne peux pas obtenir de code pour faire le lien En utilisant les options-fsanitize=undefined (ou-fsanitize=address,undefined). J'inclus la ligne-fsanitize=undefined dans Mes commandes de compilation et de lien, mais j'obtiens des erreurs de lien telles que comme:

        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)
    
  3. Je ne peux pas faire fonctionner les listes noires, et-mllvm-asan-globals=0 ou-mllvm-asan-stack=0 ne semble pas fonctionner comme je m'y attendais. Par exemple, ce dernier ne supprime pas la génération de l'erreur listée au numéro 1 ci-dessus, et la création d'une liste noire qui ressemble à celle ci-dessous ne supprime pas les erreurs non plus:

    fun:QDirPrivate::initFileLists
    fun:get_count
    fun:*opendir2*
    
  4. enfin, les exécutables générés avec ces options Asan provoquent un crash de lldb. J'utilise la lldb livrée avec Outils XCode 5; il n'y avait pas lldb déployé avec le paquet homebew llvm, et je ne sais pas comment le construire. Les instructions de construction entrez la description du lien ici avoir un lien mort qui pointe vers la source que vous êtes censé utiliser; extraire la source directement du dépôt svn, en utilisant:

    svn co http://llvm.org/svn/llvm-project/lldb/tags/RELEASE_34/final lldb
    

    produit un code qui ne se compile pas (erreurs fournies sur demande).

15
demandé sur Steve Broberg 2014-03-27 22:22:38

3 réponses

Vous pouvez construire votre projet avec -fsanitize=address -fsanitize-recover=address drapeaux, et de courir avec la variable d'environnement ASAN_OPTIONS=halt_on_error=0. Source:https://github.com/google/sanitizers/wiki/AddressSanitizer

11
répondu robert 2016-05-24 08:07:49
  1. Les bugs D'adressabilité (en particulier les corruptions de mémoire comme l'écriture OOB que vous avez mentionnée) sont généralement assez graves pour qu'on s'en inquiète. Les ignorer ne peut pas annuler leurs effets, et le programme est très susceptible de se planter dans un endroit totalement sans rapport après que vous avez sauté une corruption tas. Vous pouvez essayer de construire votre propre Clang à des vérifications dans readdir_r désactivé, mais je vais essayer de corriger l'erreur en premier lieu.
  2. pouvez-vous s'il vous plaît déposer un bogue avec les étapes de reproduction à http://code.google.com/p/address-sanitizer?
  3. les listes noires ne désactivent les contrôles d'adressabilité dans les fonctions de la liste noire qu'en ne les instrumentant pas, elles ne vérifient pas les piles pour certains cadres. Votre vérification particulière se produit dans une fonction interceptor compilée dans la bibliothèque runtime, de sorte que vous ne pouvez même pas la mettre sur liste noire. Si l'erreur #1 se trouve dans une bibliothèque système et ne peut pas être facilement contournée, nous pouvons envisager d'ajouter une option runtime pour désactiver le readdir_r vérifier.
  4. Encore une fois, un rapport de bogue sera appréciée.
5
répondu Glider 2014-04-30 10:06:36

au fait -- j'ai trouvé un moyen de contourner ce débordement de tas dans Qt si vous le construisez à partir de la source. Je crois que le problème est lié à 32-bit / 64-bit inodes (_DARWIN_FEATURE_64_BIT_INODE n'est pas défini quand je construis Qt pour une raison quelconque).

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));
1
répondu rryan 2015-12-07 06:30:06