Wolfgang Thallergcc-9.16fbf4227 years agoHistory
147 lines · 4.3 KB · D
RawDownload
/** * NetBSD implementation of glibc's $(LINK2 http://www.gnu.org/software/libc/manual/html_node/Backtraces.html backtrace) facility. * * Copyright: Copyright Martin Nowak 2012. * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Authors:   Martin Nowak * Source:    $(DRUNTIMESRC core/sys/netbsd/_execinfo.d) */module core.sys.netbsd.execinfo; version (NetBSD):extern (C):nothrow: version (GNU)    version = BacktraceExternal; version (BacktraceExternal){    size_t backtrace(void**, size_t);    char** backtrace_symbols(const(void*)*, size_t);    void backtrace_symbols_fd(const(void*)*, size_t, int);    char** backtrace_symbols_fmt(const(void*)*, size_t, const char*);    int backtrace_symbols_fd_fmt(const(void*)*, size_t, int, const char*);}else{    import core.sys.netbsd.dlfcn;     // Use extern (D) so that these functions don't collide with libexecinfo.     extern (D) int backtrace(void** buffer, int size)    {        import core.thread : thread_stackBottom;         void** p, pend=cast(void**)thread_stackBottom();        version (D_InlineAsm_X86)            asm nothrow @trusted { mov p[EBP], EBP; }        else version (D_InlineAsm_X86_64)            asm nothrow @trusted { mov p[RBP], RBP; }        else            static assert(false, "Architecture not supported.");         int i;        for (; i < size && p < pend; ++i)        {            buffer[i] = *(p + 1);            auto pnext = cast(void**)*p;            if (pnext <= p) break;            p = pnext;        }        return i;    }      extern (D) char** backtrace_symbols(const(void*)* buffer, int size)    {        static void* realloc(void* p, size_t len) nothrow        {            static import cstdlib=core.stdc.stdlib;            auto res = cstdlib.realloc(p, len);            if (res is null) cstdlib.free(p);            return res;        }         if (size <= 0) return null;         size_t pos = size * (char*).sizeof;        char** p = cast(char**)realloc(null, pos);        if (p is null) return null;         Dl_info info;        foreach (i, addr; buffer[0 .. size])        {            if (dladdr(addr, &info) == 0)                (cast(ubyte*)&info)[0 .. info.sizeof] = 0;            fixupDLInfo(addr, info);             immutable len = formatStackFrame(null, 0, addr, info);            assert(len > 0);             p = cast(char**)realloc(p, pos + len);            if (p is null) return null;             formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);             p[i] = cast(char*)pos;            pos += len;        }        foreach (i; 0 .. size)        {            pos = cast(size_t)p[i];            p[i] = cast(char*)p + pos;        }        return p;    }      extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)    {        import core.sys.posix.unistd : write;        import core.stdc.stdlib : alloca;         if (size <= 0) return;         Dl_info info;        foreach (i, addr; buffer[0 .. size])        {            if (dladdr(addr, &info) == 0)                (cast(ubyte*)&info)[0 .. info.sizeof] = 0;            fixupDLInfo(addr, info);             enum maxAlloca = 1024;            enum min = (size_t a, size_t b) => a <= b ? a : b;            immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);            assert(len > 0);             auto p = cast(char*)alloca(len);            if (p is null) return;             formatStackFrame(p, len, addr, info) >= len || assert(0);            p[len - 1] = '\n';            write(fd, p, len);        }    }      private void fixupDLInfo(const(void)* addr, ref Dl_info info)    {        if (info.dli_fname is null) info.dli_fname = "???";        if (info.dli_fbase is null) info.dli_fbase = null;        if (info.dli_sname is null) info.dli_sname = "???";        if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr;    }      private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)    {        import core.stdc.stdio : snprintf;         immutable off = addr - info.dli_saddr;        immutable len = snprintf(p, plen, "%p <%s+%zd> at %s",                                 addr, info.dli_sname, off, info.dli_fname);        assert(len > 0);        return cast(size_t)len + 1; // + '\0'    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t