我正在尝试使用boost::stacktrace::safe_dump_to(void*, std::size_t)
函数将堆栈跟踪保存到原始内存,但是该函数返回写入的堆栈帧数(加上终止帧)-不是字节数。
这意味着当我要读取此数据时,我不知道要在boost::stacktrace::stacktrace::from_dump(const void *, std::size_t, const allocator_type &)
的size字段中输入什么。起初,我以为我可以使用sizeof(boost::stacktrace::frame) * frames
,但是frame
类型包含堆分配的内存(std::string
s),因此无法使用。
这个SSCE demonstrates问题:
#include <iostream>
#include <boost/stacktrace.hpp>
int main()
{
auto buf = std::array<char, 8192>{};
const auto size = boost::stacktrace::safe_dump_to(buf.data(), buf.size());
const auto st = boost::stacktrace::stacktrace::from_dump(buf.data(), size);
std::cout << "ST from dump (" << size << " bytes): " << st << std::endl
<< "ST: " << boost::stacktrace::stacktrace{} << std::endl;
return EXIT_SUCCESS;
}
它输出:
ST from dump (4 bytes):
ST: 0# 0x00000000004016A7 in ./a.out
1# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
2# 0x0000000000401759 in ./a.out
第二行“ ST”仅用于显示预期的结果。第一行失败,因为我试图将帧数视为字节大小,显然不是。
那么应该如何使用API?
答案 0 :(得分:1)
在回读时只需使用相同的尺寸:
const auto st = boost::stacktrace::stacktrace::from_dump(buf.data(), buf.size());
毕竟,在写入转储文件时使用了该限制,因此已知大小小于该限制。
#include <iostream>
#include <boost/stacktrace.hpp>
int main()
{
auto buf = std::array<char, 8192>{};
const auto size = boost::stacktrace::safe_dump_to(buf.data(), buf.size());
const auto st = boost::stacktrace::stacktrace::from_dump(buf.data(), buf.size());
std::cout << "ST from dump (" << size << " frames): " << st << std::endl
<< "ST: " << boost::stacktrace::stacktrace{} << std::endl;
}
打印
ST from dump (4 frames): 0# 0x00000000004016B9 in ./a.out
1# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
2# 0x0000000000401869 in ./a.out
ST: 0# 0x00000000004017AF in ./a.out
1# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
2# 0x0000000000401869 in ./a.out
如评论中所述,文档here中的关于safe_dump_to
的一些小知识
转储是
void*
的二进制序列化数组,因此您可以使用od -tx8 -An stacktrace_dump_failename
Linux命令或boost::stacktrace::stacktrace::from_dump
函数来读取它们