Actual source code: demangle.c
1: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for and RTLD_* */
2: #include <petsc/private/petscimpl.h>
4: #if defined(PETSC_HAVE_DLFCN_H)
5: #include <dlfcn.h>
6: #endif
8: #if defined(__cplusplus) && defined(PETSC_HAVE_CXXABI_H)
9: #include <cxxabi.h>
10: #endif
12: /*@C
13: PetscDemangleSymbol - Convert a C++-mangled symbol name to its human-readable form using `abi::__cxa_demangle()` when available
15: Not Collective
17: Input Parameter:
18: . mangledName - the mangled symbol name (typically obtained from `dladdr()`)
20: Output Parameter:
21: . name - newly-allocated, null-terminated demangled name; caller must `PetscFree()` it
23: Level: developer
25: Note:
26: When no demangler is available (or when `mangledName` is `NULL`), `name` is set to `NULL`.
28: .seealso: `PetscStackView()`, `PetscStackPrint()`
29: @*/
30: PetscErrorCode PetscDemangleSymbol(const char mangledName[], char **name)
31: {
32: char *(*cxa_demangle)(const char *, char *, size_t *, int *) = PETSC_NULLPTR;
33: char *newname;
34: int status;
36: PetscFunctionBegin;
37: if (mangledName) PetscAssertPointer(mangledName, 1);
38: PetscAssertPointer(name, 2);
40: *name = PETSC_NULLPTR;
41: if (!mangledName) PetscFunctionReturn(PETSC_SUCCESS);
43: #if defined(__cplusplus) && defined(PETSC_HAVE_CXXABI_H)
44: cxa_demangle = __cxxabiv1::__cxa_demangle;
45: #endif
47: #if defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
48: if (!cxa_demangle) {
49: void *symbol = PETSC_NULLPTR;
50: #if defined(PETSC_HAVE_RTLD_DEFAULT)
51: symbol = dlsym(RTLD_DEFAULT, "__cxa_demangle");
52: #endif
53: if (!symbol) {
54: int mode = 0;
55: void *handle = PETSC_NULLPTR;
56: #if defined(PETSC_HAVE_RTLD_LAZY)
57: mode |= RTLD_LAZY;
58: #endif
59: #if defined(PETSC_HAVE_RTLD_LOCAL)
60: mode |= RTLD_LOCAL;
61: #endif
62: #if defined(PETSC_HAVE_RTLD_NOLOAD)
63: mode |= RTLD_NOLOAD;
64: #endif
65: #ifdef __APPLE__
66: if (!handle) handle = dlopen("libc++.1.dylib", mode);
67: #else
68: if (!handle) handle = dlopen("libstdc++.so.6", mode);
69: #endif
70: if (handle) {
71: symbol = dlsym(handle, "__cxa_demangle");
72: dlclose(handle);
73: }
74: }
75: *(void **)(&cxa_demangle) = symbol;
76: }
77: #endif
79: if (!cxa_demangle) {
80: PetscCall(PetscStrallocpy(mangledName, name));
81: PetscFunctionReturn(PETSC_SUCCESS);
82: }
84: newname = cxa_demangle(mangledName, PETSC_NULLPTR, PETSC_NULLPTR, &status);
85: if (status) {
86: PetscCheck(status != -1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate memory for symbol %s", mangledName);
87: PetscCheck(status == -2, PETSC_COMM_SELF, PETSC_ERR_LIB, "Demangling failed for symbol %s", mangledName);
88: /* Mangled name is not a valid name under the C++ ABI mangling rules */
89: PetscCall(PetscStrallocpy(mangledName, name));
90: PetscFunctionReturn(PETSC_SUCCESS);
91: }
92: PetscCall(PetscStrallocpy(newname, name));
93: free(newname);
94: PetscFunctionReturn(PETSC_SUCCESS);
95: }