This repository has been archived by the owner on Oct 12, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Having a C++ symbol demangler is very useful, with this it will be possible to implement the C++ symbol demangle in the stacktrace. The demangling is done in Posix platform by function __cxa_demangle presents in Itanium C++ ABI (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#demangler). Itanium C++ ABI is used practically in all modern C++ compilers on Posix, however old compilers (like GCC < 3.0) used a different name mangling, this is not a problem because DMD in fact only supports Itanium C++ ABI on Posix. For Windows instead the implementation it is provided by the UnDecorateSymbolName function present in the Debug Help Library. (https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-undecoratesymbolname) Signed-off-by: Ernesto Castellotti <[email protected]>
- Loading branch information
Ernesto Castellotti
committed
Apr 1, 2020
1 parent
2a0cf25
commit 9ccee09
Showing
12 changed files
with
310 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
Added experimental `C++` symbol demanling in the stacktrace | ||
|
||
This feature is availableby passing the following switches to your executable (not to the compiler): | ||
- `--DRT-cpptrace=enable:y`: Enable demangling of C++ symbols | ||
- `--DRT-cpptrace=prefix:<your_prefix>`: Change the prefix preceding the demangled C++ name (by default would be `[C++]`) | ||
- `--DRT-cpptrace=noprefix:n`: Disable adding the prefix to C ++ demangle names | ||
|
||
To use this function in the Posix platform you will need to link your executable to the phobos shared library, compile the program by passing -defaultlib=libphobos2.so to DMD. | ||
|
||
Example: | ||
|
||
``` | ||
module cpp_trace.d | ||
|
||
extern(C++) void f1() | ||
{ | ||
throw new Exception("exception"); | ||
} | ||
|
||
void main() | ||
{ | ||
try | ||
{ | ||
f1(); | ||
} | ||
catch (Exception e) | ||
{ | ||
import core.stdc.stdio; | ||
auto str = e.toString(); | ||
printf("%.*s\n", cast(int)str.length, str.ptr); | ||
} | ||
} | ||
``` | ||
|
||
If you run the executable with the following switches `./<executable> --DRT-cpptrace=enable:y`, you would get this output: | ||
|
||
``` | ||
object.Exception@cpp_trace.d(3): exception | ||
---------------- | ||
src/cpp_trace.d:5 [C++] f1() [ADDR] | ||
src/cpp_trace.d:12 _Dmain [ADDR] | ||
``` | ||
|
||
Instead, if you run the executable with the following switches `./<executable> --DRT-cpptrace=enable:y --DRT-cpptrace=prefix:CPP`, you would get this output: | ||
|
||
``` | ||
object.Exception@cpp_trace.d(5): exception | ||
---------------- | ||
src/cpp_trace.d:5 [CPP] f1() [ADDR] | ||
src/cpp_trace.d:12 _Dmain [ADDR] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/** | ||
* This module provides the demangling of C++ symbols for stacktrace | ||
* | ||
* Copyright: Copyright © 2020, The D Language Foundation | ||
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). | ||
* Authors: Ernesto Castellotti | ||
* Source: $(DRUNTIMESRC core/internal/_cppdemangle.d) | ||
*/ | ||
module core.internal.cpptrace; | ||
|
||
import core.internal.cppdemangle : CPPDemangle, CPPDemangleStatus; | ||
import core.stdc.stdio : fprintf, stderr; | ||
import core.stdc.stdlib : exit; | ||
|
||
/** | ||
* Demangles C++ mangled names passing the runtime options to cppdemangle. | ||
* | ||
* If it is not a C++ mangled name or cppdemangle is not supported by your platform, the original mangled C++ name will be returned. | ||
* The optional destination buffer and return will be contains the same string if the demangle is successful. | ||
* This function is used to demangle C++ symbols in the stacktrace. | ||
* | ||
* Params: | ||
* buf = The string to demangle. | ||
* dst = The destination buffer, if the size of the destination buffer is <= the size of cppdemangle output the return string would be incomplete. | ||
* | ||
* Returns: | ||
* The demangled name or the original string if the name is not a mangled C++ name. | ||
*/ | ||
char[] demangleCppTrace(const(char)[] buf, char[] dst) | ||
{ | ||
import core.internal.cppdemangle : copyResult; | ||
|
||
if (!CPPTrace.config.enable) | ||
{ | ||
return copyResult(buf, dst); | ||
} | ||
|
||
return CPPTrace.instance.cppdemangle(buf, dst, !CPPTrace.config.noprefix, CPPTrace.config.prefix); | ||
} | ||
|
||
private struct CPPTrace | ||
{ | ||
__gshared CPPDemangle instance; | ||
__gshared Config config; | ||
|
||
static this() | ||
{ | ||
import core.internal.parseoptions : initConfigOptions; | ||
initConfigOptions(config, "cpptrace"); | ||
|
||
version (Posix) | ||
{ | ||
version (Shared) | ||
{ | ||
// OK! CPPDemangling may be supported | ||
} | ||
else | ||
{ | ||
if (config.enable) | ||
{ | ||
fprintf(stderr, "C++ demangling is only supported if phobos is dynamically linked. Recompile the program by passing -defaultlib=libphobos2.so to DMD\n"); | ||
exit(1); | ||
assert(0); | ||
} | ||
} | ||
} | ||
|
||
if (config.enable) | ||
{ | ||
auto result = CPPDemangle.inizialize(); | ||
|
||
final switch (result) | ||
{ | ||
case CPPDemangleStatus.INIZIALIZED: | ||
{ | ||
instance = CPPDemangle.instance(); | ||
return; | ||
} | ||
|
||
case CPPDemangleStatus.LOAD_ERROR: | ||
{ | ||
version (Posix) | ||
{ | ||
fprintf(stderr, "The C++ library for the C++ demangle could not be loaded with dlopen. Please disable the option for C++ demangling.\n"); | ||
} | ||
else version (Windows) | ||
{ | ||
fprintf(stderr, "The Debug Help Library could not be loaded. Please disable the option for C++ demangling.\n"); | ||
} | ||
|
||
exit(1); | ||
assert(0); | ||
} | ||
|
||
case CPPDemangleStatus.SYMBOL_ERROR: | ||
{ | ||
version (Posix) | ||
{ | ||
fprintf(stderr, "The __cxa_demangle symbol was not found in the C++ standard library (maybe it's not compatible). Please disable the option for C++ demangling.\n"); | ||
} | ||
else version (Windows) | ||
{ | ||
fprintf(stderr, "The UnDecorateSymbolName symbol was not found in the Debug Help Library (maybe it's not compatible). Please disable the option for C++ demangling.\n"); | ||
} | ||
|
||
exit(1); | ||
assert(0); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private struct Config | ||
{ | ||
bool enable; | ||
bool noprefix; | ||
string prefix = "[C++]"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
object.Exception@src/cpp_trace.d(40): exception | ||
---------------- | ||
src/cpp_trace.d:40 [C++] f1() [ADDR] | ||
src/cpp_trace.d:5 _Dmain [ADDR] | ||
object.Exception@src/cpp_trace.d(47): exception | ||
---------------- | ||
src/cpp_trace.d:47 [C++] S1::f1() [ADDR] | ||
src/cpp_trace.d:16 _Dmain [ADDR] | ||
object.Exception@src/cpp_trace.d(57): exception | ||
---------------- | ||
src/cpp_trace.d:57 [C++] C1<unsigned char>::f1(unsigned char, unsigned char*, unsigned char&) [ADDR] | ||
src/cpp_trace.d:28 _Dmain [ADDR] |
Oops, something went wrong.