Alien-libpanda

 view release on metacpan or  search on metacpan

t/exception.cc  view on Meta::CPAN

#include "test.h"
#include <panda/exception.h>
#include <panda/from_chars.h>
#include <regex>
#include <cxxabi.h>
#include <iostream>

#if defined(__unix__)
#include <execinfo.h>

using namespace panda;

iptr<BacktraceInfo> glib_produce(const RawTrace& buffer);
static BacktraceProducer glib_producer(glib_produce);

static bool _init() {
    Backtrace::install_producer(glib_producer);
    return true;
}
static bool init = _init();

static std::regex re("(.+)\\((.+)\\+0x(.+)\\) \\[0x(.+)\\]");

static StackframePtr as_frame (const char* symbol) {
    using guard_t = std::unique_ptr<char*, std::function<void(char**)>>;
    auto r = StackframePtr(new Stackframe());
    std::cmatch what;
    if (regex_match(symbol, what, re)) {
        panda::string dll           (what[1].first, what[1].length());
        panda::string mangled_name  (what[2].first, what[2].length());
        panda::string symbol_offset (what[3].first, what[3].length());
        panda::string address       (what[4].first, what[4].length());

        int status;
        char* demangled_name = abi::__cxa_demangle(mangled_name.c_str(), nullptr, nullptr, &status);
        guard_t guard;
        //printf("symbol = %s, d = %s, o=%s\n", symbol, demangled_name ? demangled_name : "[n/a]", mangled_name.c_str());
        if (demangled_name) {
            guard = guard_t(&demangled_name, [](char** ptr) { free(*ptr); });
        } else {
            demangled_name = (char*)mangled_name.c_str();
        }
        r->name = demangled_name;
        r->mangled_name = mangled_name;
        r->file = "n/a";
        r->library = dll;
        r->line_no = 0;

        std::uint64_t addr = 0;
        // +2 to skip 0x prefix
        auto addr_r = from_chars(address.data(), address.data() + address.length(), addr, 16);
        if (!addr_r.ec) { r->address = addr; }
        else            { r->address = 0; }

        std::uint64_t offset = 0;
        // +2 to skip 0x prefix
        auto offset_r = from_chars(symbol_offset.data(), symbol_offset.data() + symbol_offset.size(), offset, 16);
        if (!offset_r.ec) { r->offset = offset; }
        else              { r->offset = 0; }
        //printf("symbol = %s\n", symbol);
    }
    return r;
}

struct glib_backtrace: BacktraceInfo {

    glib_backtrace(std::vector<StackframePtr>&& frames_):frames{std::move(frames_)}{}



( run in 0.490 second using v1.01-cache-2.11-cpan-39bf76dae61 )