Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

零星的崩溃 #2229

Open
bethebest0622 opened this issue Dec 9, 2024 · 6 comments
Open

零星的崩溃 #2229

bethebest0622 opened this issue Dec 9, 2024 · 6 comments
Assignees

Comments

@bethebest0622
Copy link

bethebest0622 commented Dec 9, 2024

您好,我们使用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

可以请您看一下吗

@marty1885
Copy link
Member

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

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

@mrclassfree
Copy link

mrclassfree commented Dec 20, 2024

你好,我也碰到了崩溃的现象,通过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
Copy link
Member

an-tao commented Dec 20, 2024

你好,我也碰到了崩溃的现象,通过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)

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

@marty1885
Copy link
Member

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

@an-tao
Copy link
Member

an-tao commented Dec 20, 2024

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

@mrclassfree
Copy link

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

现在基本断定应该是这个接口的问题,也检查了代码没有发现有访问无效内存的地方,后来我从Task改为callback方式,暂时没有发现crashed的现象:
Task 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;
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants