零星的崩溃
您好,我们使用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
可以请您看一下吗
可以提供運行環境資訊嗎?
- CPU
- 給 Drogon 的線程數目
- Drogon 版本
- 服務端還是客戶端
你好,我也碰到了崩溃的现象,通过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)
你好,我也碰到了崩溃的现象,通过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)
看着是有非法的内存访问,请确定你使用的变量在上下文环境里是有效的,可以贴一下相关的代码我看看
感覺是不同地方。OpenSSL 的 session manager 跟 Coroutine.. OpenSSL session 那個我真看不出是什麼問題。沒道理 map 自己炸阿
最好有必现的代码能在自己的环境里重现跟踪
着是有非法的内存访问,请确定你使用的变量在上下文环境里是有效的,可以贴一下相关的代码我看
现在基本断定应该是这个接口的问题,也检查了代码没有发现有访问无效内存的地方,后来我从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;
}
}