This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Handle PIEs in libbacktrace
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Alexey Samsonov <samsonov at google dot com>
- Cc: Dmitry Vyukov <dvyukov at google dot com>, Ian Lance Taylor <iant at google dot com>, Konstantin Serebryany <konstantin dot s dot serebryany at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 6 Dec 2013 10:53:37 +0100
- Subject: Re: [PATCH] Handle PIEs in libbacktrace
- Authentication-results: sourceware.org; auth=none
- References: <20131206075033 dot GE892 at tucnak dot redhat dot com> <CACT4Y+b4Txm5oWOCEC71OmU5+4sbxgpkx=6ziiXD7DPfBrpeoA at mail dot gmail dot com> <20131206082507 dot GF892 at tucnak dot redhat dot com> <CACT4Y+bn6bPbqcX4TghnQBKUe=JtVbxxrtKxA--z-5399hKUeg at mail dot gmail dot com> <CAGSYnCNgAB8G4mVFnA_TEkVyLKn2=ag_ef1ecrNn8HZTJtF1nw at mail dot gmail dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, Dec 06, 2013 at 12:53:02PM +0400, Alexey Samsonov wrote:
> ASan calls this function only for global variables (not functions). It
> is needed because
> we use a different machinery to pass global names to ASan runtime - we
> register globals
> by a call from instrumented code, which also tells runtime the
> (mangled) global name.
Well, given that it demangled just fine even function names, I guess it
calls it always and just it would do nothing for function names demangled
already by llvm-symbolizer if using the external symbolizer.
> OTOH, in TSan we rely on symbolization to demangle names of global variables.
Then we need something like following, with which all tests pass. I'm not
using Demangle method from the symbolizer, because getting it requires a
mutex that is already held.
The alternative would be to just (perhaps under #ifdef SANITIZER_CP_DEMANGLE)
compile in libiberty/cp-demangle.c (similarly how libstdc++ compiles it in)
as part of libsanitizer/libiberty/ or even libsanitizer/libbacktrace/,
and tweak it, so that like libsanitizer/libbacktrace it uses internal_memcpy
etc. and uses InternalAlloc/InternalFree. The problem is that cp-demangle.c
uses only realloc and free, and doesn't provide any hint on how large the
previously allocated memory chunk is. So, either there is some easy way
how to query the size of InternalAlloc returned allocation, or we would need
to allocate uptr extra and store there number of bytes allocated
and emulate realloc/free that way.
--- libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc.jj 2013-12-05 12:04:28.000000000 +0100
+++ libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc 2013-12-06 10:36:02.285059188 +0100
@@ -25,6 +25,15 @@
# endif
#endif
+// C++ demangling function, as required by Itanium C++ ABI. This is weak,
+// because we do not require a C++ ABI library to be linked to a program
+// using sanitizers; if it's not present, we'll just use the mangled name.
+namespace __cxxabiv1 {
+ extern "C" SANITIZER_WEAK_ATTRIBUTE
+ char *__cxa_demangle(const char *mangled, char *buffer,
+ size_t *length, int *status);
+}
+
namespace __sanitizer {
#if SANITIZER_LIBBACKTRACE
@@ -39,6 +48,19 @@ struct SymbolizeCodeData {
uptr module_offset;
};
+char *MaybeDemangleAndDup(const char *symname) {
+ const char *demangled = symname;
+ if (symname[0] == '_' && symname[1] == 'Z' && __cxxabiv1::__cxa_demangle) {
+ demangled = __cxxabiv1::__cxa_demangle(symname, 0, 0, 0);
+ if (demangled == NULL)
+ demangled = symname;
+ }
+ char *ret = internal_strdup(demangled);
+ if (demangled != symname)
+ __builtin_free ((void *) demangled);
+ return ret;
+}
+
extern "C" {
static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,
const char *filename, int lineno,
@@ -49,7 +71,7 @@ static int SymbolizeCodePCInfoCallback(v
info->Clear();
info->FillAddressAndModuleInfo(addr, cdata->module_name,
cdata->module_offset);
- info->function = internal_strdup(function);
+ info->function = MaybeDemangleAndDup(function);
if (filename)
info->file = internal_strdup(filename);
info->line = lineno;
@@ -67,7 +89,7 @@ static void SymbolizeCodeCallback(void *
info->Clear();
info->FillAddressAndModuleInfo(addr, cdata->module_name,
cdata->module_offset);
- info->function = internal_strdup(symname);
+ info->function = MaybeDemangleAndDup(symname);
cdata->n_frames = 1;
}
}
@@ -76,7 +98,7 @@ static void SymbolizeDataCallback(void *
uintptr_t symval, uintptr_t symsize) {
DataInfo *info = (DataInfo *)vdata;
if (symname && symval) {
- info->name = internal_strdup(symname);
+ info->name = MaybeDemangleAndDup(symname);
info->start = symval;
info->size = symsize;
}
Jakub