drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.51k stars 1.1k forks source link

MySQL client cause SIGBUS on ARM64 macOS #884

Closed kotori2 closed 3 years ago

kotori2 commented 3 years ago

Describe the bug As title

To Reproduce Install dragon via Vcpkg and compile this sample app:

#include <drogon/drogon.h>

using namespace drogon;
int main() {
    auto app = &drogon::app();
    drogon::app().createDbClient("mysql", "127.0.0.1", 3306, "db", "root",
                                 "root", 4, "", "mysql", false, "utf8");
    app->run();
    return 0;
}

Expected behavior App will run

Screenshots

image

Desktop (please complete the following information):

Smartphone (please complete the following information): NA

Additional context

MySQL Server version: 8.0.25 Homebrew
kotori2 commented 3 years ago

Crash point:

image
kotori2 commented 3 years ago

If I copy and paste parseConnString and pass an identical conn info string to it, it will not crash at all. Could it be a macOS STL bug?

marty1885 commented 3 years ago

I don't have ARM64 MacOS X. Can confirm the same code works on ARM64 Linux and ARM64 FreeBSD with both LLVM and GCC. This looks like a standard library or a compiler bug. May you build Drogon and your application with Address Sanitizer (-fsanitize=address) on? Or try a different compiler.

kotori2 commented 3 years ago

I don't have ARM64 MacOS X. Can confirm the same code works on ARM64 Linux and ARM64 FreeBSD with both LLVM and GCC. This looks like a standard library or a compiler bug. May you build Drogon and your application with Address Sanitizer (-fsanitize=address) on? Or try a different compiler.

Got some messages that looks useless... Gonna try debug with Xcode

image
kotori2 commented 3 years ago

The crash point actually changed and it seems like MySQL bug now...

image
marty1885 commented 3 years ago

I think it could be a MySQL bug. But by the looks of how ASan generates useless messages, it's likely a compiler bug...

kotori2 commented 3 years ago

nvm it just CLion didn't parsed Asan messages correctly.

AddressSanitizer:DEADLYSIGNAL
=================================================================
==68308==ERROR: AddressSanitizer: BUS on unknown address 0x4f4f61806e5a (pc 0x4f4f61806e5a bp 0x00019670502c sp 0x00010d10f400 T1)
    #0 0x4f4f61806e5a  (<unknown module>)

==68308==Register values:
 x[0] = 0x000000000be06bf0   x[1] = 0x0000000000000001   x[2] = 0x0000000000000000   x[3] = 0x0000000000000000
 x[4] = 0x0000000000000000   x[5] = 0x0000000000000000   x[6] = 0x0000000000000000   x[7] = 0x0000000000000000
 x[8] = 0x0000000000000000   x[9] = 0x00000000000077d3  x[10] = 0x000000010d10f400  x[11] = 0x000000010d10f3e0
x[12] = 0x0000000196705008  x[13] = 0x0000000000000000  x[14] = 0x0000000000000881  x[15] = 0x000000008000001f
x[16] = 0x832b4f4f61806e5a  x[17] = 0x0000000196705008  x[18] = 0x0000000000000000  x[19] = 0x0000000000000000
x[20] = 0x832b4f4f61806e5a  x[21] = 0x0000000000000000  x[22] = 0x000000016f9159d0  x[23] = 0xff1c000196704cd8
x[24] = 0x000000016f9159b0  x[25] = 0x0000000000000000  x[26] = 0x0000000200000000  x[27] = 0x0000000000000000
x[28] = 0x0000000000000000     fp = 0x000000010d10f400     lr = 0x000000019670502c     sp = 0x000000010d10f400
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: BUS (<unknown module>)
Thread T1 created by T0 here:
    #0 0x1070615b0 in wrap_pthread_create+0x54 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x395b0)
    #1 0x101d1ad70 in std::__1::__libcpp_thread_create(_opaque_pthread_t**, void* (*)(void*), void*) __threading_support:501
    #2 0x101d1ab74 in std::__1::thread::thread<trantor::EventLoopThread::EventLoopThread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0, void>(trantor::EventLoopThread::EventLoopThread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0&&) thread:307
    #3 0x101d1a408 in std::__1::thread::thread<trantor::EventLoopThread::EventLoopThread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0, void>(trantor::EventLoopThread::EventLoopThread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0&&) thread:299
    #4 0x101d1a298 in trantor::EventLoopThread::EventLoopThread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) EventLoopThread.cc:25
    #5 0x101d1a540 in trantor::EventLoopThread::EventLoopThread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) EventLoopThread.cc:26
    #6 0x101d20a14 in std::__1::__compressed_pair_elem<trantor::EventLoopThread, 1, false>::__compressed_pair_elem<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, 0ul>(std::__1::piecewise_construct_t, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>, std::__1::__tuple_indices<0ul>) memory:1935
    #7 0x101d20958 in std::__1::__compressed_pair<std::__1::allocator<trantor::EventLoopThread>, trantor::EventLoopThread>::__compressed_pair<std::__1::allocator<trantor::EventLoopThread>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::piecewise_construct_t, std::__1::tuple<std::__1::allocator<trantor::EventLoopThread>&>, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>) memory:2019
    #8 0x101d2061c in std::__1::__compressed_pair<std::__1::allocator<trantor::EventLoopThread>, trantor::EventLoopThread>::__compressed_pair<std::__1::allocator<trantor::EventLoopThread>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::piecewise_construct_t, std::__1::tuple<std::__1::allocator<trantor::EventLoopThread>&>, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>) memory:2020
    #9 0x101d204e4 in std::__1::__shared_ptr_emplace<trantor::EventLoopThread, std::__1::allocator<trantor::EventLoopThread> >::__shared_ptr_emplace<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::allocator<trantor::EventLoopThread>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) memory:3297
    #10 0x101d2002c in std::__1::__shared_ptr_emplace<trantor::EventLoopThread, std::__1::allocator<trantor::EventLoopThread> >::__shared_ptr_emplace<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::allocator<trantor::EventLoopThread>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) memory:3298
    #11 0x101d1f1b4 in std::__1::enable_if<!(is_array<trantor::EventLoopThread>::value), std::__1::shared_ptr<trantor::EventLoopThread> >::type std::__1::make_shared<trantor::EventLoopThread, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) memory:4038
    #12 0x101d1efd0 in trantor::EventLoopThreadPool::EventLoopThreadPool(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) EventLoopThreadPool.cc:23
    #13 0x101d1f28c in trantor::EventLoopThreadPool::EventLoopThreadPool(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) EventLoopThreadPool.cc:20
    #14 0x101ba7da0 in drogon::orm::DbClientImpl::DbClientImpl(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, drogon::orm::ClientType) DbClientImpl.cc:53
    #15 0x101ba8744 in drogon::orm::DbClientImpl::DbClientImpl(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, drogon::orm::ClientType) DbClientImpl.cc:59
    #16 0x101ba7254 in std::__1::__compressed_pair_elem<drogon::orm::DbClientImpl, 1, false>::__compressed_pair_elem<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&, 0ul, 1ul, 2ul>(std::__1::piecewise_construct_t, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&>, std::__1::__tuple_indices<0ul, 1ul, 2ul>) memory:1935
    #17 0x101ba7174 in std::__1::__compressed_pair<std::__1::allocator<drogon::orm::DbClientImpl>, drogon::orm::DbClientImpl>::__compressed_pair<std::__1::allocator<drogon::orm::DbClientImpl>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&>(std::__1::piecewise_construct_t, std::__1::tuple<std::__1::allocator<drogon::orm::DbClientImpl>&>, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&>) memory:2019
    #18 0x101ba6c54 in std::__1::__compressed_pair<std::__1::allocator<drogon::orm::DbClientImpl>, drogon::orm::DbClientImpl>::__compressed_pair<std::__1::allocator<drogon::orm::DbClientImpl>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&>(std::__1::piecewise_construct_t, std::__1::tuple<std::__1::allocator<drogon::orm::DbClientImpl>&>, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&>) memory:2020
    #19 0x101ba6b54 in std::__1::__shared_ptr_emplace<drogon::orm::DbClientImpl, std::__1::allocator<drogon::orm::DbClientImpl> >::__shared_ptr_emplace<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType>(std::__1::allocator<drogon::orm::DbClientImpl>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&) memory:3297
    #20 0x101ba66c8 in std::__1::__shared_ptr_emplace<drogon::orm::DbClientImpl, std::__1::allocator<drogon::orm::DbClientImpl> >::__shared_ptr_emplace<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType>(std::__1::allocator<drogon::orm::DbClientImpl>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&) memory:3298
    #21 0x101ba3e04 in std::__1::enable_if<!(is_array<drogon::orm::DbClientImpl>::value), std::__1::shared_ptr<drogon::orm::DbClientImpl> >::type std::__1::make_shared<drogon::orm::DbClientImpl, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&, drogon::orm::ClientType&&) memory:4038
    #22 0x101ba3f04 in drogon::orm::DbClient::newMysqlClient(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long) DbClient.cc:48
    #23 0x1015cfcfc in Database::get_mysql_direct() Database.cpp:61
    #24 0x1015d057c in Database::update_database() Database.cpp:68
    #25 0x1005730d0 in main main.cc:40
    #26 0x1966d544c in start+0x0 (libdyld.dylib:arm64e+0x1844c)

==68308==ABORTING
an-tao commented 3 years ago

@kotori2 What's the version of your compiler?

kotori2 commented 3 years ago

@an-tao

Apple clang version 12.0.5 (clang-1205.0.22.9)
Target: arm64-apple-darwin20.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

@marty1885 Can confirm it's a mariadb bug. A simple program like this will throw the same error :

int main() {
    MYSQL mysql;
    mysql_init(&mysql);
    auto r = mysql_options(&mysql, MYSQL_OPT_NONBLOCK, nullptr);
    MYSQL *ret = nullptr;
    mysql_real_connect_start(&ret,
                             &mysql,
                             "127.0.0.1",
                             "root",
                             "root",
                             "mysql",
                             3306,
                             NULL,
                             0);

    return 0;
}
kotori2 commented 3 years ago

https://jira.mariadb.org/browse/CONC-553

Seems like this will work on x86 because they are using assembly instead of C functions. getcontext and swapcontext seems deprecated on macOS for 12 years.