drogon icon indicating copy to clipboard operation
drogon copied to clipboard

零星的崩溃

Open bethebest0622 opened this issue 1 year ago • 6 comments

您好,我们使用drogon有段时间了,还是比较稳定的,但最近零星出现一些崩溃,堆栈信息如下:

(gdb) where
#0  0x00007f956e54115d in std::__detail::_List_node_base::_M_hook (this=0x7f9568103460, __position=0x7f95683bb420)
    at /home/nwani/m3/conda-bld/compilers_linux-64_1560109574129/work/.build/x86_64-conda_cos6-linux-gnu/src/gcc/libstdc++-v3/src/c++98/list.cc:132
#1  0x00007f956ec13eea in trantor::SessionManager::store(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, trantor::InetAddress, ssl_session_st*, trantor::EventLoop*) ()
   from /usr/local/lib/libhttp_util.so
#2  0x00007f956ec14e58 in OpenSSLProvider::processHandshake() () from /usr/local/lib/libhttp_util.so
#3  0x00007f956ec16fb7 in OpenSSLProvider::recvData(trantor::MsgBuffer*) () from /usr/local/lib/libhttp_util.so
#4  0x00007f956ec07185 in trantor::TcpConnectionImpl::readCallback() () from /usr/local/lib/libhttp_util.so
#5  0x00007f956ebfae68 in trantor::Channel::handleEventSafely() () from /usr/local/lib/libhttp_util.so
#6  0x00007f956ebfaf01 in trantor::Channel::handleEvent() () from /usr/local/lib/libhttp_util.so
#7  0x00007f956ebeab8c in trantor::EventLoop::loop() () from /usr/local/lib/libhttp_util.so
#8  0x00007f956eb1c90a in drogon::HttpAppFrameworkImpl::run() () from /usr/local/lib/libhttp_util.so
#9  0x00007f956e55419d in std::execute_native_thread_routine (__p=0xdc0bd0) at /home/nwani/m3/conda-bld/compilers_linux-64_1560109574129/work/.build/x86_64-conda_cos6-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:80
#10 0x00007f956e09f832 in start_thread () from /lib64/libc.so.6
#11 0x00007f956e03f480 in clone3 () from /lib64/libc.so.6
(gdb) where
#0  0x00007f0ad7d058ff in std::__detail::_Map_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::_List_iterator<trantor::SessionManager::SessionData> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::_List_iterator<trantor::SessionManager::SessionData> > >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/local/lib/libhttp_util.so
#1  0x00007f0ad7d05f16 in trantor::SessionManager::store(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, trantor::InetAddress, ssl_session_st*, trantor::EventLoop*) ()
   from /usr/local/lib/libhttp_util.so
#2  0x00007f0ad7d06e58 in OpenSSLProvider::processHandshake() () from /usr/local/lib/libhttp_util.so
#3  0x00007f0ad7d08fb7 in OpenSSLProvider::recvData(trantor::MsgBuffer*) () from /usr/local/lib/libhttp_util.so
#4  0x00007f0ad7cf9185 in trantor::TcpConnectionImpl::readCallback() () from /usr/local/lib/libhttp_util.so
#5  0x00007f0ad7cece68 in trantor::Channel::handleEventSafely() () from /usr/local/lib/libhttp_util.so
#6  0x00007f0ad7cecf01 in trantor::Channel::handleEvent() () from /usr/local/lib/libhttp_util.so
#7  0x00007f0ad7cdcb8c in trantor::EventLoop::loop() () from /usr/local/lib/libhttp_util.so
#8  0x00007f0ad7cddaf0 in trantor::EventLoopThread::loopFuncs() () from /usr/local/lib/libhttp_util.so
#9  0x00007f0ad7200b23 in execute_native_thread_routine () from /lib64/libstdc++.so.6
#10 0x00007f0ad76a11ca in start_thread () from /lib64/libpthread.so.0
#11 0x00007f0ad68078d3 in clone () from /lib64/libc.so.6

可以请您看一下吗

bethebest0622 avatar Dec 09 '24 11:12 bethebest0622

可以提供運行環境資訊嗎?

  • CPU
  • 給 Drogon 的線程數目
  • Drogon 版本
  • 服務端還是客戶端

marty1885 avatar Dec 09 '24 13:12 marty1885

你好,我也碰到了崩溃的现象,通过DUMP分析也找不出原因,有大牛能帮忙分析一下吗? Drogon信息: Version: 1.9.8 Git commit: 882c1d9ecd3526d8ef0bcb452a6ffef74e02e91c Compilation: Compiler: c++ Compiler ID: GNU Compilation flags: -O3 -DNDEBUG -std=c++17 -I/usr/include/jsoncpp -I/usr/local/include Libraries: postgresql: no (pipeline mode: no) mariadb: yes sqlite3: no ssl/tls backend: OpenSSL brotli: no hiredis: yes c-ares: no yaml-cpp: no 系统环境信息: Operating system: Linux 0.0.0 Linux 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64 CPU: amd64 family 23 model 49 stepping 0 8 CPUs

DUMP分析结果文件上传到附件中[ result12202.txt ](url)

mrclassfree avatar Dec 20 '24 03:12 mrclassfree

你好,我也碰到了崩溃的现象,通过DUMP分析也找不出原因,有大牛能帮忙分析一下吗? Drogon信息: Version: 1.9.8 Git commit: 882c1d9 Compilation: Compiler: c++ Compiler ID: GNU Compilation flags: -O3 -DNDEBUG -std=c++17 -I/usr/include/jsoncpp -I/usr/local/include Libraries: postgresql: no (pipeline mode: no) mariadb: yes sqlite3: no ssl/tls backend: OpenSSL brotli: no hiredis: yes c-ares: no yaml-cpp: no 系统环境信息: Operating system: Linux 0.0.0 Linux 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64 CPU: amd64 family 23 model 49 stepping 0 8 CPUs

DUMP分析结果文件上传到附件中[ result12202.txt ](url)

看着是有非法的内存访问,请确定你使用的变量在上下文环境里是有效的,可以贴一下相关的代码我看看

an-tao avatar Dec 20 '24 06:12 an-tao

感覺是不同地方。OpenSSL 的 session manager 跟 Coroutine.. OpenSSL session 那個我真看不出是什麼問題。沒道理 map 自己炸阿

marty1885 avatar Dec 20 '24 06:12 marty1885

最好有必现的代码能在自己的环境里重现跟踪

an-tao avatar Dec 20 '24 06:12 an-tao

着是有非法的内存访问,请确定你使用的变量在上下文环境里是有效的,可以贴一下相关的代码我看

现在基本断定应该是这个接口的问题,也检查了代码没有发现有访问无效内存的地方,后来我从Task改为callback方式,暂时没有发现crashed的现象: Task<HttpResponsePtr> Store::auth2(const HttpRequestPtr req) { auto jsonTmp = req->getJsonObject(); if (!jsonTmp || !jsonTmp->isMember("data")) { Json::Value jsonRet; jsonRet["data"] = Json::objectValue; jsonRet["code"] = 403; jsonRet["msg"] = gCrypto.a2u("参数格式错误"); auto resp = HttpResponse::newHttpJsonResponse(jsonRet); co_return resp; }

auto strData = jsonTmp->get("data", "").asString();
auto [bSucess, rValue] = gCrypto.DeAES_CBC("[email protected]", "cqwskj@2024", strData);
if (!bSucess) {
    Json::Value jsonRet;
    jsonRet["data"] = Json::objectValue;
    jsonRet["code"] = 403;
    jsonRet["msg"] = gCrypto.a2u("参数内容错误: " + rValue + ", data: " + strData);
    auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
    co_return resp;
}
LOG_DEBUG << "auth value:" << rValue;

Json::Reader jsonReader;
Json::Value jsonBody;
try {
    if (!jsonReader.parse(gCrypto.a2u(rValue), jsonBody)) {
        Json::Value jsonRet;
        jsonRet["data"] = Json::objectValue;
        jsonRet["code"] = 403;
        jsonRet["msg"] = gCrypto.a2u("参数内容解析错误: " + rValue);
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }
    if (!jsonBody.isMember("barcode") || !jsonBody.isMember("nonce")) {
        Json::Value jsonRet;
        jsonRet["data"] = Json::objectValue;
        jsonRet["code"] = 403;
        jsonRet["msg"] = gCrypto.a2u("缺少关键参数: " + rValue);
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }
} catch (...) {
    Json::Value jsonRet;
    jsonRet["data"] = Json::objectValue;
    jsonRet["code"] = 501;
    jsonRet["msg"] = gCrypto.a2u("解析参数主体发生错误");
    auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
    co_return resp;
}

auto db = app().getDbClient();
CoroMapper<WsStore> mpStore(db);
bool isCreaed = false;
try {
    auto fee_site = jsonBody.get("barcode", "").asString();
    Criteria criteria(WsStore::Cols::_fee_site, CompareOperator::EQ, fee_site);
    auto store = co_await mpStore.findOne(criteria);
    isCreaed = true;

    store.setLoggedAt(trantor::Date::now());
    store.setSdkVersion(jsonBody.get("sdk_version", "0.0.0.0").asString());
    co_await mpStore.update(store);

    // 判断状态和有效时间
    if (store.getValueOfStatus() == 0) {
        Json::Value jsonRet;
        jsonRet["data"] = Json::objectValue;
        jsonRet["code"] = 406;
        jsonRet["msg"] = gCrypto.a2u("门店已停用");
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }
    if (store.getValueOfExpinTime() < trantor::Date::now()) {
        Json::Value jsonRet;
        jsonRet["data"] = Json::objectValue;
        jsonRet["code"] = 701;
        jsonRet["msg"] = gCrypto.a2u("授权已过期");
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }

    // 加密响应内容
    Json::Value jsonData;
    jsonData["barcode"] = store.getValueOfFeeSite();
    jsonData["barname"] = store.getValueOfName();
    jsonData["expires"] = store.getValueOfExpinTime().toDbStringLocal();
    jsonData["appid"] = "21142";
    jsonData["timestamp"] = _GetNowTimetamp();
    auto [bSucess, rValue] = gCrypto.EnAES_CBC(store.getValueOfFeeSite(), jsonBody["nonce"].asString(), jsonData.toStyledString());
    if (!bSucess) {
        Json::Value jsonRet;
        jsonRet["data"] = Json::objectValue;
        jsonRet["code"] = 500;
        jsonRet["msg"] = gCrypto.a2u("数据加密失败");
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }

    Json::Value jsonRet;
    jsonRet["data"]["token"] = rValue;
    jsonRet["code"] = 0;
    jsonRet["msg"] = gCrypto.a2u("SUCESS");
    auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
    co_return resp;
} catch (const DrogonDbException &e) {
    if (isCreaed) {
        Json::Value jsonRet;
        jsonRet["code"] = 500;
        jsonRet["msg"] = gCrypto.a2u("数据库错误: ") + e.base().what();
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }
} catch (...) {
    Json::Value jsonRet;
    jsonRet["data"] = Json::objectValue;
    jsonRet["code"] = 501;
    jsonRet["msg"] = gCrypto.a2u("授权验证发生未知错误");
    auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
    co_return resp;
}

// 没有创建门店,准备新增门店,设置3个月使用时间
if (!isCreaed) {
    try {
        WsStore store;
        store.setCreatedAt(trantor::Date::now());
        store.setLoggedAt(trantor::Date::now());
        store.setSdkVersion(jsonBody.get("sdk_version", "0.0.0.0").asString());
        store.setDataVersion(jsonBody.get("data_version", "0.0.0.0").asString());
        store.setExpinTime(trantor::Date::now().after(7776000)); // 3个月
        store.setFeeSite(jsonBody["barcode"].asString());
        store.setName(jsonBody.get("barname", "").asString());
        co_await mpStore.insert(store);

        // 加密响应内容
        Json::Value jsonData;
        jsonData["barcode"] = store.getValueOfFeeSite();
        jsonData["barname"] = store.getValueOfName();
        jsonData["expires"] = store.getValueOfExpinTime().toDbStringLocal();
        jsonData["appid"] = "21142";
        jsonData["timestamp"] = _GetNowTimetamp();
        auto [bSucess, rValue] = gCrypto.EnAES_CBC(store.getValueOfFeeSite(), jsonBody["nonce"].asString(), jsonData.toStyledString());
        if (!bSucess) {
            Json::Value jsonRet;
            jsonRet["data"] = Json::objectValue;
            jsonRet["code"] = 500;
            jsonRet["msg"] = gCrypto.a2u("数据加密失败: " + rValue);
            auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
            co_return resp;
        }

        Json::Value jsonRet;
        jsonRet["data"]["token"] = rValue;
        jsonRet["code"] = 0;
        jsonRet["msg"] = gCrypto.a2u("SUCESS");
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    } catch (const DrogonDbException &e) {
        Json::Value jsonRet;
        jsonRet["code"] = 500;
        jsonRet["msg"] = gCrypto.a2u("新建门店错误: ") + e.base().what();
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    } catch (...) {
        Json::Value jsonRet;
        jsonRet["data"] = Json::objectValue;
        jsonRet["code"] = 501;
        jsonRet["msg"] = gCrypto.a2u("授权新建门店发生未知错误");
        auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
        co_return resp;
    }
} else {
    LOG_ERROR << "================> 授权验证退出 未知错误,不应该运行到此位置";
    Json::Value jsonRet;
    jsonRet["code"] = 501;
    jsonRet["data"] = Json::objectValue;
    auto resp = HttpResponse::newHttpJsonResponse(jsonRet);
    co_return resp;
}

}

mrclassfree avatar Jan 08 '25 08:01 mrclassfree