boostorg / stacktrace

C++ library for storing and printing backtraces.
https://boost.org/libs/stacktrace
424 stars 71 forks source link

Flawed safe_dump_to(..) API #62

Closed cmannett85 closed 6 years ago

cmannett85 commented 6 years ago

I'm trying to save a stacktrace to raw memory using the safe_dump_to(void *, std::size_t) function, however the function returns the number of stack frames (plus the termination frame) written - not the number of bytes written.

This means that when I come to read this data, I have no idea what to put in the size field of stacktrace::from_dump(const void *, std::size_t, const allocator_type &). At first I assumed that I could use sizeof(boost::stacktrace::frame) * frames, but the frame type contains heap allocated memory (std::strings) so that won't work.

This SSCE demonstrates the problem:

#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;
}

It outputs:

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

The second 'ST' line is just to show what is expected. The first line fails because I'm trying to treat the frame count as a byte size, which it obviously isn't.

So how is the API supposed to be used?

apolukhin commented 6 years ago

You're right the API may be confusing.

from_dump takes the size argument that is the buffer size. In other words it usually should be the same as the buffer size that you've passed to the safe_dump_to.

Here' a non trivial example on that https://github.com/boostorg/stacktrace/blob/c63afe54a24da91bf0f0c879fbab8202accb44ea/example/terminate_handler.cpp#L173

If you do wish to get the actually consumed bytes, you should sizeof(boost::stacktrace::frame::native_frame_ptr_t) * frames. I'll update the reference to reflect that.

apolukhin commented 6 years ago

Updated and regenerated the docs