Closed JaydenFish closed 2 years ago
SPSCVarQueue只能保证8字节(sizeof(MsgHeader))对齐,所以不建议写入很大的复杂对象,可以考虑写入指针或智能指针。
new (out) fmt::remove_cvref_t<Arg>(std::forward<Arg>(arg));
写入时在这里崩溃的.
我尝试定义了以下结构体并用logi写入队列,没有发现异常情况,你可以把你的结构定义发一下吗?
struct alignas(64) MyType
{
MyType(int val)
: v(val) {}
alignas(64) int v;
};
template<>
struct fmt::formatter<MyType> : formatter<int>
{
// parse is inherited from formatter<string_view>.
template<typename FormatContext>
auto format(const MyType& val, FormatContext& ctx) {
return formatter<int>::format(val.v, ctx);
}
};
完蛋,我把fmtlogT多实例化了一个,用于写普通文件, 这个会崩溃, 原来那个logi不会.
就是写对齐的对象才崩溃,其他对象不会.
好奇怪,看不出来有啥问题.
代码放在 https://github.com/JaydenFish/test
make test1 && bin/test1
多谢大佬.
我把问题解决了, 不好意思.
这个问题又冒出来了. 下面这段代码:
#include <cstdint>
#include <fmt/core.h>
#include <fmtlog/fmtlog.h>
using namespace std;
struct alignas(64) MyType {
int v { 0 };
};
template <>
struct fmt::formatter<MyType> : formatter<int> {
template <typename FormatContext>
auto format(const MyType& val, FormatContext& ctx)
{
return formatter<int>::format(val.v, ctx);
}
};
int main()
{
fmtlog::setHeaderPattern("{HMSF},{l},STK,");
fmtlog::setLogLevel(fmtlog::DBG);
fmtlog::flushOn(fmtlog::ERR);
fmtlog::setFlushDelay(10000000);
fmtlog::setLogFile("testlog", false);
MyType t {};
logi("{},{}", t.v, t);
logi("{},{}", t.v, t);
return 0;
}
用最新的fmtlog和fmt8.1.1, 用gcc11, -O3 -g编译.
直接运行, SIGSEGV.
去掉alignas(64), 没问题.
2个logi去掉1个,没问题.
去掉编译的O3,没问题.
2个logi都改成logi("{}", t);
没问题
修复了,pull下最新的代码试试。
对齐到64字节的struct. 写到log里, 会崩溃. 把alignas(64)去掉就没问题了. 好像是SPSCVarQueue入队出队的时候出了问题.