提升::堆栈跟踪::safe_dump_to输出大小

boost::stacktrace::safe_dump_to output size

本文关键字:输出 to dump 跟踪 safe 提升 堆栈      更新时间:2023-10-16

我正在尝试使用boost::stacktrace::safe_dump_to(void*, std::size_t)函数将堆栈跟踪保存到原始内存中,但是该函数返回写入的堆栈帧数(加上终止帧(数 -而不是写入的字节数。

这意味着当我来读取这些数据时,我不知道在boost::stacktrace::stacktrace::from_dump(const void *, std::size_t, const allocator_type &)的大小字段中放什么。 起初我以为我可以使用sizeof(boost::stacktrace::frame) * frames,但是frame类型包含堆分配的内存(std::strings(,因此这不起作用。

此 SSCE 演示了该问题:

#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?

只需在回读上使用相同的尺寸:

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

更新

正如评论中提到的,这里的文档中有一些关于safe_dump_to的花絮

转储是void*的二进制序列化数组,因此您可以使用od -tx8 -An stacktrace_dump_failenameLinux 命令或使用boost::stacktrace::stacktrace::from_dump函数读取它们

恕我直言,前面的答案似乎没有回答太多问题,所以我尝试这个。

正如你提到的,我们从 safe_dump_to(( 得到的大小是一个帧数,而不是缓冲区大小。

文档指出:

返回:

存储的呼叫序列深度,包括终止零 框架。要获取实际消耗的字节数,请将此值乘以 sizeof(boost::stacktrace::frame::native_frame_ptr_t(

所以调用应该是:

const auto st = boost::stacktrace::stacktrace::from_dump(buf.data(),
size * sizeof(boost::stacktrace::frame::native_frame_ptr_t));