#pragma once
#include <exception>
#include <vector>
#include "string.h"
#include "refcnt.h"
#include "function.h"
namespace
panda {
struct
ArgumentsHolder:
public
Refcnt { };
using
ArgumentsHolderSP = iptr<ArgumentsHolder>;
struct
Stackframe:
public
Refcnt {
string file;
string library;
string name;
string mangled_name;
std::uint64_t address = 0;
std::uint64_t offset = 0;
std::uint64_t line_no = 0;
ArgumentsHolderSP args;
virtual
~Stackframe();
};
using
StackframeSP = iptr<Stackframe>;
using
StackFrames = std::vector<StackframeSP>;
struct
BacktraceBackend: Refcnt {
virtual
bool
produce_frame(StackFrames& result,
size_t
i) = 0;
};
using
BacktraceBackendSP = iptr<BacktraceBackend>;
struct
BacktraceInfo : Refcnt {
BacktraceInfo(std::vector<StackframeSP>&& frames_) : frames(std::move(frames_)) {}
virtual
~BacktraceInfo();
const
std::vector<StackframeSP>& get_frames()
const
noexcept
{
return
frames;}
virtual
string to_string()
const
noexcept
;
StackFrames frames;
};
using
BacktraceInfoSP = iptr<BacktraceInfo>;
struct
Backtrace;
using
RawTrace = std::vector<
void
*>;
using
RawTraceProducer =
int
(*)(
void
**,
int
);
using
BacktraceProducer = BacktraceBackendSP(*)(
const
Backtrace& raw_traces);
struct
Backtrace {
static
const
constexpr
int
max_depth = 150;
Backtrace ()
noexcept
;
Backtrace (
const
Backtrace &other)
noexcept
;
virtual
~Backtrace ();
Backtrace& operator=(
const
Backtrace& other) =
default
;
iptr<BacktraceInfo> get_backtrace_info()
const
noexcept
;
const
RawTrace& get_trace ()
const
noexcept
{
return
buffer; }
static
void
install_producer (
const
BacktraceProducer& producer)
noexcept
;
static
void
uninstall_producer(
const
BacktraceProducer& producer)
noexcept
;
static
string dump_trace()
noexcept
;
std::vector<
void
*> buffer;
};
template
<
typename
T>
struct
bt : T, Backtrace {
template
<
typename
...Args>
bt (Args&&... args)
noexcept
: T(std::forward<Args...>(args...)) {}
};
struct
exception : std::exception, Backtrace {
exception ()
noexcept
;
exception (
const
string& whats)
noexcept
;
exception (
const
exception& oth)
noexcept
;
exception& operator= (
const
exception& oth)
noexcept
;
const
char
* what ()
const
noexcept
override;
virtual
string whats ()
const
noexcept
;
private
:
mutable
string _whats;
};
}