Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Enable demangling of C++ symbols in the stacktrace
Browse files Browse the repository at this point in the history
This allows you to view demangled and pretty printed C++ symbols
in the stacktrace.
Is especially useful considering that D is getting more and more support for C++.

Now the C++ symbols in the stacktrace will be printed like this:
        test.d:7 [C++] Test<int>::SomeName(int, long, int) [0x55711efee36f]
        test.d:18 [C++] testcpp() [0x557228e17978]

Signed-off-by: Ernesto Castellotti <[email protected]>
  • Loading branch information
Ernesto Castellotti committed Mar 26, 2020
1 parent 36d80f7 commit 5022f16
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/core/internal/cppdemangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* Authors: Ernesto Castellotti
* Source: $(DRUNTIMESRC core/internal/_cppdemangle.d)
*/
module core.internal.cppdemangle;

/**
* Demangles C++ mangled names.
Expand Down Expand Up @@ -60,7 +61,7 @@ char[] cppdemangle(const(char)[] buf, char[] dst, bool withPrefix = false, strin
}
}

private char[] copyResult(const(char)[] input, char[] dst) @safe @nogc nothrow
package char[] copyResult(const(char)[] input, char[] dst) @safe @nogc nothrow
{
auto len = input.length <= dst.length ? input.length : dst.length;
dst[0..len] = input[0..len];
Expand Down
34 changes: 34 additions & 0 deletions src/core/internal/cppstack.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module core.internal.cppstack;

__gshared Config config;

struct Config
{
bool enable;
bool noprefix;
string prefix = "[C++]";
}

version (Shared)
{
extern (C) pragma(crt_constructor) private void initCppStackConfig()
{
import core.internal.parseoptions : initConfigOptions;
initConfigOptions(config, "cppstack");
}
}

char[] demangleCppStack(const(char)[] buf, char[] dst)
{
import core.internal.cppdemangle : cppdemangle, copyResult;

version (Shared)
{
if (!config.enable) copyResult(buf, dst);
return cppdemangle(buf, dst, !config.noprefix, prefix);
}
else
{
return copyResult(buf, dst);
}
}
6 changes: 6 additions & 0 deletions src/core/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@ unittest
static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInfo
{
import core.demangle;
import core.internal.cppstack;
import core.stdc.stdlib : free;
import core.stdc.string : strlen, memchr, memmove;

Expand Down Expand Up @@ -888,6 +889,11 @@ private:

auto sym = demangle(buf[symBeg .. symEnd], fixbuf[symBeg .. $]);

if (sym == buf[symBeg .. symEnd]) // Retry with demangleCppStack
{
sym = demangleCppStack(buf[symBeg .. symEnd], fixbuf[symBeg .. $]);
}

if (sym.ptr !is fixbuf.ptr + symBeg)
{
// demangle reallocated the buffer, copy the symbol to fixbuf
Expand Down
10 changes: 9 additions & 1 deletion src/core/sys/windows/stacktrace.d
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module core.sys.windows.stacktrace;
version (Windows):

import core.demangle;
import core.internal.cppstack;
import core.runtime;
import core.stdc.stdlib;
import core.stdc.string;
Expand Down Expand Up @@ -294,7 +295,14 @@ private:
size_t decodeIndex = 0;
tempSymName = decodeDmdString(tempSymName, decodeIndex);
}
res ~= demangle(tempSymName, demangleBuf);
auto demangledName = demangle(tempSymName, demangleBuf);

if (demangledName == tempSymName) // Retry with demangleCppStack
{
demangledName = demangleCppStack(tempSymName, demangleBuf, true);
}

res ~= demangledName;
return res;
}

Expand Down
13 changes: 12 additions & 1 deletion src/rt/backtrace/dwarf.d
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,19 @@ bool runStateMachine(ref const(LineNumberProgram) lp, scope RunStateMachineCallb
const(char)[] getDemangledSymbol(const(char)[] btSymbol, return ref char[1024] buffer)
{
import core.demangle;
import core.internal.cppstack;

const mangledName = getMangledSymbolName(btSymbol);
return !mangledName.length ? buffer[0..0] : demangle(mangledName, buffer[]);
if (!mangledName.length) return buffer[0..0];

auto demangledName = demangle(mangledName, buffer[]);

if (demangledName == mangledName) // Retry with demangleCppStack
{
demangledName = demangleCppStack(mangledName, buffer[]);
}

return demangledName;
}

T read(T)(ref const(ubyte)[] buffer) @nogc nothrow
Expand Down

0 comments on commit 5022f16

Please sign in to comment.