c++执行到某步直接中断
在学习c++开源库时,使用了nlohmannJson,spdlog自带的fmt和cpp-httplib这三个库。发现部分代码段的日志不会打印,而且http返回也为空,代码段如下:
svr.Get("/login/status", [&cli](const httplib::Request &, httplib::Response &res)
{
json ret;
auto cliRes = cli.Get("/api/login/status");
info(fmt::format("get data : {0} {1}", cliRes->status, cliRes->body));
json data = json::parse(cliRes->body);
if (data.contains("data") && data["data"].contains("account") && data["data"]["account"].contains("id"))
{
long id = data["data"]["account"]["id"];
//错误代码
info(fmt::format("get user ID : {0} {1}", id, ret));
ret["result"] = (id == USER_ID ? "0" : "1");
}
else
{
error("ID field not found.");
ret["result"] = -1;
}
info(fmt::format("dump : {0}", ret.dump()));
res.set_content(ret.dump(), "text/plain");
});
gdb单步执行时,发现gdb在“info(fmt::format("get user ID : {0} {1}", id, ret));”卡住,使用curl测试发送请求时,返回为空,所以推测后面的代码全部没有执行。发生错误的原因,是因为ret是json对象,需要改为ret.dump(),返回string对象,fmt::format才能正常格式化字符串。
继续测试查找后面的代码全部没有执行的原因,给原来的“info(fmt::format("get user ID : {0} {1}"增加异常处理语句,改为:
try
{
info(fmt::format("get user ID : {0} {1}", id, ret);
}
catch (...)
{
std::cout << "Caught format error" << std::endl;
}
运行后,打印"Caught format error",证明确实抛出了异常。
一般的程序,抛出异常后,如果没有try/catch处理,就会一直传递到顶层,导致程序崩溃。但是,因为抛出异常的代码在httplib的lambda函数内,可能httplib有部分处理或者无视异常的代码,导致异常没有传递到顶层导致程序崩溃,httplib也没有报错或者打印日志。有空再看下httplib的代码,找到httplib的相关代码。