google / sanitizers

AddressSanitizer, ThreadSanitizer, MemorySanitizer
Other
11.55k stars 1.04k forks source link

hwasan false positive on ubuntu 24.04 arm64 #1791

Open Dalzhim opened 2 months ago

Dalzhim commented 2 months ago

Here are two small programs which trigger what looks like a false positive to me. These issues weren't detected by hwasan when running with gcc-13 on ubuntu 23.10. They are detected with ubuntu 24.04 using gcc-14's sanitizers. I reproduce the issues on a macOS arm64 system running ubuntu 24.04 inside VMware. Here are the two sample programs where one crashes inside GoogleTest and the other crashes in compiler-generated destructors for complex types coming from the Boost library. These independent issues lead me to believe the common factor : hwasan is actually the culprit. I could be wrong though but I'll leave that up to the domain experts. Here are the minimal repros.

// The GTest library is the official package associated with ubuntu 24.04 noble numbat
// Compiler invocation example : g++ -std=c++20 -O0 -g -fsanitize=hwaddress -I/usr/include -L/usr/lib/aarch64-linux-gnu main.cpp /usr/lib/aarch64-linux-gnu/libgtest.a -o a.out
#include <gtest/gtest.h>
#include <string>

struct S
{
    void f()
    {
        std::string s;
        throw 1;
    }
};

TEST(MySuite, Throw)
{
    S s;
    EXPECT_ANY_THROW(s.f());
}

int main(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
        ::testing::FLAGS_gtest_death_test_style = "fast";
    return RUN_ALL_TESTS();
}
// Tested against Boost 1.83 and Boost 1.86
// Compiler invocation example : g++ -std=c++20 -O0 -g -fsanitize=hwaddress -I$BOOST_ROOT main.cpp -o a.out
#include <boost/tokenizer.hpp>
#include <gtest/gtest.h>
#include <map>
#include <string>

class S
{
public:
    void Set()
    {
        std::string haystack;
        boost::tokenizer<boost::char_separator<char>> tok(haystack, boost::char_separator<char>("/"));
        is.Set();
    }

    class IS
    {
    public:
        void Set()
        {
            auto it = m.find(0);
            if (it == m.end()) {
                m[0] = 0;
            } else {
                throw std::invalid_argument("Duplication de la paire <Verbe, Route>.");
            }
        }

    private:
        std::map<int, int> m;
    };

private:
    IS is;
};

int main(int argc, char** argv)
{
    S s;
    s.Set();
    try {
        s.Set();
    } catch (...) {
        return 0;
    }
    return 1;
}