aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gcc.gnu.org>2019-04-21 10:02:02 +0000
committerIain Buclaw <ibuclaw@gcc.gnu.org>2019-04-21 10:02:02 +0000
commit6d679a7d9d8dbf9bc2c67cc0be747af2a9557314 (patch)
tree8d227445beafa88f89bded3527ff4476c68fb962 /libphobos
parent42d3fe9afb0a107c2a7956e0feb4b20ff41cc611 (diff)
downloadgcc-6d679a7d9d8dbf9bc2c67cc0be747af2a9557314.zip
gcc-6d679a7d9d8dbf9bc2c67cc0be747af2a9557314.tar.gz
gcc-6d679a7d9d8dbf9bc2c67cc0be747af2a9557314.tar.bz2
libphobos: Merge upstream druntime 4b2674b3
Adds version (BacktraceExternal) for using libexecinfo instead of internal implementation on FreeBSD, NetBSD, and DragonFly. Reviewed-on: https://github.com/dlang/druntime/pull/2560 From-SVN: r270482
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/runtime.d3
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/execinfo.d208
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/execinfo.d204
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/execinfo.d204
5 files changed, 331 insertions, 290 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index dd5f621..405be92 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-70b9fea60246e63d936ad6826b1b48b6e0f1de8f
+4b2674b36b1f6aac75db2a5aa38d67d4be55a987
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index 0ead047..1fd5440 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -519,9 +519,8 @@ extern (C) bool runModuleUnitTests()
{
static enum MAXFRAMES = 128;
void*[MAXFRAMES] callstack;
- int numframes;
- numframes = backtrace( callstack.ptr, MAXFRAMES );
+ auto numframes = backtrace( callstack.ptr, MAXFRAMES );
backtrace_symbols_fd( callstack.ptr, numframes, 2 );
}
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/execinfo.d b/libphobos/libdruntime/core/sys/dragonflybsd/execinfo.d
index 9d2d615..9f91a0b 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/execinfo.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/execinfo.d
@@ -9,125 +9,139 @@
module core.sys.dragonflybsd.execinfo;
version (DragonFlyBSD):
+extern (C):
+nothrow:
-extern (C) nothrow @system:
+version (GNU)
+ version = BacktraceExternal;
-import core.sys.dragonflybsd.dlfcn;
-
-// Use extern (D) so that these functions don't collide with libexecinfo.
-
-extern (D) int backtrace(void** buffer, int size)
+version (BacktraceExternal)
{
- 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;
+ 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.dragonflybsd.dlfcn;
+ // Use extern (D) so that these functions don't collide with libexecinfo.
-extern (D) char** backtrace_symbols(const(void*)* buffer, int size)
-{
- static void* realloc(void* p, size_t len) nothrow
+ extern (D) int backtrace(void** buffer, int size)
{
- static import cstdlib=core.stdc.stdlib;
- auto res = cstdlib.realloc(p, len);
- if (res is null) cstdlib.free(p);
- return res;
+ 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;
}
- 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])
+ extern (D) char** backtrace_symbols(const(void*)* buffer, int 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);
+ 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;
- formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);
-
- p[i] = cast(char*)pos;
- pos += len;
+ 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;
}
- foreach (i; 0 .. size)
+
+
+ extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)
{
- pos = cast(size_t)p[i];
- p[i] = cast(char*)p + pos;
+ 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);
+ }
}
- 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;
+ 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;
+ }
- if (size <= 0) return;
- Dl_info info;
- foreach (i, addr; buffer[0 .. size])
+ private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)
{
- if (dladdr(addr, &info) == 0)
- (cast(ubyte*)&info)[0 .. info.sizeof] = 0;
- fixupDLInfo(addr, info);
+ import core.stdc.stdio : snprintf;
- enum maxAlloca = 1024;
- enum min = (size_t a, size_t b) => a <= b ? a : b;
- immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);
+ 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);
-
- 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);
+ return cast(size_t)len + 1; // + '\0'
}
}
-
-
-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'
-}
diff --git a/libphobos/libdruntime/core/sys/freebsd/execinfo.d b/libphobos/libdruntime/core/sys/freebsd/execinfo.d
index 7b4ad6c0..cbdf702 100644
--- a/libphobos/libdruntime/core/sys/freebsd/execinfo.d
+++ b/libphobos/libdruntime/core/sys/freebsd/execinfo.d
@@ -12,122 +12,136 @@ version (FreeBSD):
extern (C):
nothrow:
-import core.sys.freebsd.dlfcn;
+version (GNU)
+ version = BacktraceExternal;
-// Use extern (D) so that these functions don't collide with libexecinfo.
-
-extern (D) int backtrace(void** buffer, int size)
+version (BacktraceExternal)
{
- 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;
+ 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.freebsd.dlfcn;
+ // Use extern (D) so that these functions don't collide with libexecinfo.
-extern (D) char** backtrace_symbols(const(void*)* buffer, int size)
-{
- static void* realloc(void* p, size_t len) nothrow
+ extern (D) int backtrace(void** buffer, int size)
{
- static import cstdlib=core.stdc.stdlib;
- auto res = cstdlib.realloc(p, len);
- if (res is null) cstdlib.free(p);
- return res;
+ 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;
}
- 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])
+ extern (D) char** backtrace_symbols(const(void*)* buffer, int 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);
+ 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;
- formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);
-
- p[i] = cast(char*)pos;
- pos += len;
+ 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;
}
- foreach (i; 0 .. size)
+
+
+ extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)
{
- pos = cast(size_t)p[i];
- p[i] = cast(char*)p + pos;
+ 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);
+ }
}
- 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;
+ 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;
+ }
- if (size <= 0) return;
- Dl_info info;
- foreach (i, addr; buffer[0 .. size])
+ private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)
{
- if (dladdr(addr, &info) == 0)
- (cast(ubyte*)&info)[0 .. info.sizeof] = 0;
- fixupDLInfo(addr, info);
+ import core.stdc.stdio : snprintf;
- enum maxAlloca = 1024;
- enum min = (size_t a, size_t b) => a <= b ? a : b;
- immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);
+ 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);
-
- 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);
+ return cast(size_t)len + 1; // + '\0'
}
}
-
-
-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'
-}
diff --git a/libphobos/libdruntime/core/sys/netbsd/execinfo.d b/libphobos/libdruntime/core/sys/netbsd/execinfo.d
index 6287557..97b2a45 100644
--- a/libphobos/libdruntime/core/sys/netbsd/execinfo.d
+++ b/libphobos/libdruntime/core/sys/netbsd/execinfo.d
@@ -12,122 +12,136 @@ version (NetBSD):
extern (C):
nothrow:
-import core.sys.netbsd.dlfcn;
+version (GNU)
+ version = BacktraceExternal;
-// Use extern (D) so that these functions don't collide with libexecinfo.
-
-extern (D) int backtrace(void** buffer, int size)
+version (BacktraceExternal)
{
- 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;
+ 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) char** backtrace_symbols(const(void*)* buffer, int size)
-{
- static void* realloc(void* p, size_t len) nothrow
+ extern (D) int backtrace(void** buffer, int size)
{
- static import cstdlib=core.stdc.stdlib;
- auto res = cstdlib.realloc(p, len);
- if (res is null) cstdlib.free(p);
- return res;
+ 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;
}
- 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])
+ extern (D) char** backtrace_symbols(const(void*)* buffer, int 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);
+ 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;
- formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);
-
- p[i] = cast(char*)pos;
- pos += len;
+ 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;
}
- foreach (i; 0 .. size)
+
+
+ extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)
{
- pos = cast(size_t)p[i];
- p[i] = cast(char*)p + pos;
+ 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);
+ }
}
- 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;
+ 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;
+ }
- if (size <= 0) return;
- Dl_info info;
- foreach (i, addr; buffer[0 .. size])
+ private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)
{
- if (dladdr(addr, &info) == 0)
- (cast(ubyte*)&info)[0 .. info.sizeof] = 0;
- fixupDLInfo(addr, info);
+ import core.stdc.stdio : snprintf;
- enum maxAlloca = 1024;
- enum min = (size_t a, size_t b) => a <= b ? a : b;
- immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);
+ 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);
-
- 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);
+ return cast(size_t)len + 1; // + '\0'
}
}
-
-
-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'
-}