[llvm] r269992 - Work around a glibc bug: backtrace() spuriously fails if

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 13:24:15 PDT 2016


I reverted this commit in r270267 because it has been breaking the FreeBSD bots:

http://lab.llvm.org:8011/builders/lld-x86_64-freebsd <http://lab.llvm.org:8011/builders/lld-x86_64-freebsd>

-Chris

> On May 18, 2016, at 3:26 PM, Richard Smith via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> 
> Author: rsmith
> Date: Wed May 18 17:26:36 2016
> New Revision: 269992
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=269992&view=rev
> Log:
> Work around a glibc bug: backtrace() spuriously fails if
> - glibc is dynamically linked, and
> - libgcc_s is unavailable (for instance, another library is being used to
>   provide the compiler runtime or libgcc is statically linked), and
> - the target is x86_64.
> 
> If we run backtrace() and it fails to find any stack frames, try using
> _Unwind_Backtrace instead if available.
> 
> Modified:
>    llvm/trunk/cmake/config-ix.cmake
>    llvm/trunk/lib/Support/Unix/Signals.inc
> 
> Modified: llvm/trunk/cmake/config-ix.cmake
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=269992&r1=269991&r2=269992&view=diff
> ==============================================================================
> --- llvm/trunk/cmake/config-ix.cmake (original)
> +++ llvm/trunk/cmake/config-ix.cmake Wed May 18 17:26:36 2016
> @@ -144,6 +144,7 @@ endif()
> # function checks
> check_symbol_exists(arc4random "stdlib.h" HAVE_DECL_ARC4RANDOM)
> check_symbol_exists(backtrace "execinfo.h" HAVE_BACKTRACE)
> +check_symbol_exists(_Unwind_Backtrace "unwind.h" HAVE_UNWIND_BACKTRACE)
> check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE)
> check_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
> check_symbol_exists(setrlimit sys/resource.h HAVE_SETRLIMIT)
> 
> Modified: llvm/trunk/lib/Support/Unix/Signals.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Signals.inc?rev=269992&r1=269991&r2=269992&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/Unix/Signals.inc (original)
> +++ llvm/trunk/lib/Support/Unix/Signals.inc Wed May 18 17:26:36 2016
> @@ -45,6 +45,9 @@
> #if HAVE_LINK_H
> #include <link.h>
> #endif
> +#if HAVE_UNWIND_BACKTRACE
> +#include <unwind.h>
> +#endif
> 
> using namespace llvm;
> 
> @@ -309,17 +312,61 @@ static bool findModulesAndOffsets(void *
> }
> #endif // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) && ...
> 
> +#if defined(ENABLE_BACKTRACES) && defined(HAVE_UNWIND_BACKTRACE)
> +static int unwindBacktrace(void **StackTrace, int MaxEntries) {
> +  if (MaxEntries < 0)
> +    return 0;
> +
> +  // Skip the first frame ('unwindBacktrace' itself).
> +  int Entries = -1;
> +
> +  auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
> +    // Apparently we need to detect reaching the end of the stack ourselves.
> +    void *IP = (void *)_Unwind_GetIP(Context);
> +    if (!IP)
> +      return _URC_END_OF_STACK;
> +
> +    assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
> +    if (Entries >= 0)
> +      StackTrace[Entries] = IP;
> +
> +    if (++Entries == MaxEntries)
> +      return _URC_END_OF_STACK;
> +    return _URC_NO_REASON;
> +  };
> +
> +  _Unwind_Backtrace(
> +      [](_Unwind_Context *Context, void *Handler) {
> +        return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
> +      },
> +      static_cast<void *>(&HandleFrame));
> +  return std::max(Entries, 0);
> +}
> +#endif
> +
> // PrintStackTrace - In the case of a program crash or fault, print out a stack
> // trace so that the user has an indication of why and where we died.
> //
> // On glibc systems we have the 'backtrace' function, which works nicely, but
> // doesn't demangle symbols.
> void llvm::sys::PrintStackTrace(raw_ostream &OS) {
> -#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
> -  static void* StackTrace[256];
> +#if defined(ENABLE_BACKTRACES)
> +  static void *StackTrace[256];
> +  int depth = 0;
> +#if defined(HAVE_BACKTRACE)
>   // Use backtrace() to output a backtrace on Linux systems with glibc.
> -  int depth = backtrace(StackTrace,
> +  if (!depth)
> +    depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
> +#endif
> +#if defined(HAVE_UNWIND_BACKTRACE)
> +  // Try _Unwind_Backtrace() if backtrace() failed.
> +  if (!depth)
> +    depth = unwindBacktrace(StackTrace,
>                         static_cast<int>(array_lengthof(StackTrace)));
> +#endif
> +  if (!depth)
> +    return;
> +
>   if (printSymbolizedStackTrace(StackTrace, depth, OS))
>     return;
> #if HAVE_DLFCN_H && __GNUG__
> @@ -369,7 +416,7 @@ void llvm::sys::PrintStackTrace(raw_ostr
>     }
>     OS << '\n';
>   }
> -#else
> +#elif defined(HAVE_BACKTRACE)
>   backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
> #endif
> #endif
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160520/cf61b453/attachment.html>


More information about the llvm-commits mailing list