Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package backward-cpp for openSUSE:Factory 
checked in at 2022-09-29 18:12:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/backward-cpp (Old)
 and      /work/SRC/openSUSE:Factory/.backward-cpp.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "backward-cpp"

Thu Sep 29 18:12:04 2022 rev:4 rq:1006501 version:1.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/backward-cpp/backward-cpp.changes        
2021-02-16 09:19:26.563204598 +0100
+++ /work/SRC/openSUSE:Factory/.backward-cpp.new.2275/backward-cpp.changes      
2022-09-29 18:12:16.599128593 +0200
@@ -1,0 +2,13 @@
+Tue Sep 27 17:19:31 UTC 2022 - Stefan Br??ns <stefan.bru...@rwth-aachen.de>
+
+- Update to version 1.6
+  * RISC-V mcontext.
+  * Support for Apple Silicon.
+  * libunwind for Linux and macOS.
+  * C++17 compatibility.
+  * Various bug fixes
+- Enable unit tests
+- Change the devel package architecture to noarch, backward-cpp is
+  a header-only library.
+
+-------------------------------------------------------------------

Old:
----
  backward-cpp-1.5.tar.gz

New:
----
  backward-cpp-1.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ backward-cpp.spec ++++++
--- /var/tmp/diff_new_pack.M8vH66/_old  2022-09-29 18:12:17.143129656 +0200
+++ /var/tmp/diff_new_pack.M8vH66/_new  2022-09-29 18:12:17.147129665 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package backward-cpp
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           backward-cpp
-Version:        1.5
+Version:        1.6
 Release:        0
 Summary:        Stack trace printer for C++
 License:        MIT
@@ -34,6 +34,8 @@
 %package devel
 Summary:        Development files for backward-cpp
 Group:          Development/Libraries/C and C++
+# backward-cpp is a header only library
+BuildArch:      noarch
 
 %description devel
 Development files for backward-cpp, a stack trace printer for C++.
@@ -42,19 +44,22 @@
 %autosetup -n backward-cpp-%{version}
 
 %build
-%cmake -DCMAKE_INSTALL_LIBDIR=%{_libdir}
+# LIBDIR is only used for the CMake Config files, and
+# <prefix>/share/<name*> is a valid location
+%cmake -DCMAKE_INSTALL_LIBDIR=%{_datadir}
 %cmake_build
 
 %install
 %cmake_install
 
-%files
-%license LICENSE.txt
-%doc README.md
+%check
+%ctest
 
 %files devel
+%license LICENSE.txt
+%doc README.md
 %{_includedir}/backward.hpp
-%{_libdir}/backward
-%{_libdir}/backward/BackwardConfig.cmake
+%{_datadir}/backward
+%{_datadir}/backward/BackwardConfig.cmake
 
 %changelog

++++++ backward-cpp-1.5.tar.gz -> backward-cpp-1.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backward-cpp-1.5/BackwardConfig.cmake 
new/backward-cpp-1.6/BackwardConfig.cmake
--- old/backward-cpp-1.5/BackwardConfig.cmake   2020-04-14 04:24:48.000000000 
+0200
+++ new/backward-cpp-1.6/BackwardConfig.cmake   2021-08-13 00:49:08.000000000 
+0200
@@ -28,6 +28,8 @@
        "Use compiler's unwind API")
 set(STACK_WALKING_BACKTRACE FALSE CACHE BOOL
        "Use backtrace from (e)glibc for stack walking")
+set(STACK_WALKING_LIBUNWIND FALSE CACHE BOOL
+       "Use libunwind for stack walking")
 
 set(STACK_DETAILS_AUTO_DETECT TRUE CACHE BOOL
        "Auto detect backward's stack details dependencies")
@@ -50,16 +52,47 @@
 ###############################################################################
 # CONFIGS
 ###############################################################################
-if (${STACK_DETAILS_AUTO_DETECT})
-       include(FindPackageHandleStandardArgs)
+include(FindPackageHandleStandardArgs)
+
+if (STACK_WALKING_LIBUNWIND)
+       # libunwind works on the macOS without having to add special include
+       # paths or libraries
+       if (NOT APPLE)
+               find_path(LIBUNWIND_INCLUDE_DIR NAMES "libunwind.h")
+               find_library(LIBUNWIND_LIBRARY unwind)
+
+               if (LIBUNWIND_LIBRARY)
+                       include(CheckSymbolExists)
+                       check_symbol_exists(UNW_INIT_SIGNAL_FRAME libunwind.h 
HAVE_UNW_INIT_SIGNAL_FRAME)
+                       if (NOT HAVE_UNW_INIT_SIGNAL_FRAME)
+                               message(STATUS "libunwind does not support 
unwinding from signal handler frames")
+                       endif()
+               endif()
+
+               set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR})
+               set(LIBDWARF_LIBRARIES ${LIBUNWIND_LIBRARY})
+               find_package_handle_standard_args(libunwind DEFAULT_MSG
+                       LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR)
+               mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY)
+               list(APPEND _BACKWARD_LIBRARIES ${LIBUNWIND_LIBRARY})
+       endif()
+
+       # Disable other unwinders if libunwind is found
+       set(STACK_WALKING_UNWIND FALSE)
+       set(STACK_WALKING_BACKTRACE FALSE)      
+endif()
 
+if (${STACK_DETAILS_AUTO_DETECT})
+       if(NOT CMAKE_VERSION VERSION_LESS 3.17)
+               set(_name_mismatched_arg NAME_MISMATCHED)
+       endif()
        # find libdw
        find_path(LIBDW_INCLUDE_DIR NAMES "elfutils/libdw.h" 
"elfutils/libdwfl.h")
        find_library(LIBDW_LIBRARY dw)
        set(LIBDW_INCLUDE_DIRS ${LIBDW_INCLUDE_DIR} )
        set(LIBDW_LIBRARIES ${LIBDW_LIBRARY} )
-       find_package_handle_standard_args(libdw DEFAULT_MSG
-               LIBDW_LIBRARY LIBDW_INCLUDE_DIR)
+       find_package_handle_standard_args(libdw ${_name_mismatched_arg}
+               REQUIRED_VARS LIBDW_LIBRARY LIBDW_INCLUDE_DIR)
        mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY)
 
        # find libbfd
@@ -69,8 +102,8 @@
        find_library(LIBDL_LIBRARY dl)
        set(LIBBFD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
        set(LIBBFD_LIBRARIES ${LIBBFD_LIBRARY} ${LIBDL_LIBRARY})
-       find_package_handle_standard_args(libbfd DEFAULT_MSG
-               LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR
+       find_package_handle_standard_args(libbfd ${_name_mismatched_arg}
+               REQUIRED_VARS LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR
                LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
        mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY
                LIBDL_INCLUDE_DIR LIBDL_LIBRARY)
@@ -84,8 +117,8 @@
        find_library(LIBDL_LIBRARY dl)
        set(LIBDWARF_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} 
${LIBDL_INCLUDE_DIR})
        set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARY} ${LIBELF_LIBRARY} 
${LIBDL_LIBRARY})
-       find_package_handle_standard_args(libdwarf DEFAULT_MSG
-               LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR
+       find_package_handle_standard_args(libdwarf ${_name_mismatched_arg}
+               REQUIRED_VARS LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR
                LIBELF_LIBRARY LIBELF_INCLUDE_DIR
                LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
        mark_as_advanced(LIBDWARF_INCLUDE_DIR LIBDWARF_LIBRARY
@@ -152,10 +185,18 @@
 endmacro()
 
 if (NOT _BACKWARD_DEFINITIONS)
-       map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND BACKTRACE)
+       map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND LIBUNWIND 
BACKTRACE)
        map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW 
BFD DWARF)
 endif()
 
+if(WIN32)
+    list(APPEND _BACKWARD_LIBRARIES dbghelp psapi)
+       if(MINGW)
+           set(MINGW_MSVCR_LIBRARY "msvcr90$<$<CONFIG:DEBUG>:d>" CACHE STRING 
"Mingw MSVC runtime import library")
+           list(APPEND _BACKWARD_LIBRARIES ${MINGW_MSVCR_LIBRARY})
+       endif()
+endif()
+
 set(BACKWARD_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")
 
 set(BACKWARD_HAS_EXTERNAL_LIBRARIES FALSE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backward-cpp-1.5/README.md 
new/backward-cpp-1.6/README.md
--- old/backward-cpp-1.5/README.md      2020-04-14 04:24:48.000000000 +0200
+++ new/backward-cpp-1.6/README.md      2021-08-13 00:49:08.000000000 +0200
@@ -1,4 +1,4 @@
-Backward-cpp 
[![badge](https://img.shields.io/badge/conan.io-backward%2F1.3.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](http://www.conan.io/source/backward/1.3.0/Manu343726/testing)
 [![Build 
Status](https://travis-ci.org/bombela/backward-cpp.svg?branch=master)](https://travis-ci.org/bombela/backward-cpp)
+Backward-cpp 
[![badge](https://img.shields.io/badge/conan.io-backward%2F1.3.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](http://www.conan.io/source/backward/1.3.0/Manu343726/testing)
 ============
 
 Backward is a beautiful stack trace pretty printer for C++.
@@ -37,7 +37,9 @@
 `backward.cpp` to your project, and don't forget to tell your build system.
 
 The code in `backward.cpp` is trivial anyway, you can simply copy what it's
-doing at your convenience.
+doing at your convenience. 
+
+Note for [folly](https://github.com/facebook/folly) library users: must define 
`backward::SignalHandling sh;` after `folly::init(&argc, &argv);`.
 
 ## Configuration & Dependencies
 
@@ -93,6 +95,35 @@
 # through an IMPORTED target.
 target_link_libraries(mytarget PUBLIC Backward::Backward)
 ```
+### Libraries to unwind the stack
+
+On Linux and macOS, backtrace can back-trace or "walk" the stack using the
+following libraries:
+
+#### unwind
+
+Unwind comes from libgcc, but there is an equivalent inside clang itself. With
+unwind, the stacktrace is as accurate as it can possibly be, since this is
+used by the C++ runtine in gcc/clang for stack unwinding on exception.
+
+Normally libgcc is already linked to your program by default.
+
+#### libunwind from the [libunwind 
project](https://github.com/libunwind/libunwind)
+
+       apt-get install binutils-dev (or equivalent)
+
+Libunwind provides, in some cases, a more accurate stacktrace as it knows
+to decode signal handler frames and lets us edit the context registers when
+unwinding, allowing stack traces over bad function references.
+
+For best results make sure you are using libunwind 1.3 or later, which added
+`unw_init_local2` and support for handling signal frames.
+
+CMake will warn you when configuring if your libunwind version doesn't support
+signal frames.
+
+On macOS clang provides a libunwind API compatible library as part of its
+environment, so no third party libraries are necessary.
 
 ### Compile with debug info
 
@@ -110,17 +141,17 @@
 
 ### Libraries to read the debug info
 
-Backward support pretty printed stack traces on GNU/Linux only, it will compile
-fine under other platforms but will not do anything.  **Pull requests are
-welcome :)**
+Backward supports pretty printed stack traces on GNU/Linux, macOS and Windows,
+it will compile fine under other platforms but will not do anything. **Pull
+requests are welcome :)**
 
 Also, by default you will get a really basic stack trace, based on the
 `backtrace_symbols` API:
 
 ![default trace](doc/nice.png)
 
-You will need to install some dependencies to get the ultimate stack trace. Two
-libraries are currently supported, the only difference is which one is the
+You will need to install some dependencies to get the ultimate stack trace.
+Three libraries are currently supported, the only difference is which one is 
the
 easiest for you to install, so pick your poison:
 
 #### libbfd from the [GNU/binutils](http://www.gnu.org/software/binutils/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backward-cpp-1.5/backward.cpp 
new/backward-cpp-1.6/backward.cpp
--- old/backward-cpp-1.5/backward.cpp   2020-04-14 04:24:48.000000000 +0200
+++ new/backward-cpp-1.6/backward.cpp   2021-08-13 00:49:08.000000000 +0200
@@ -11,7 +11,7 @@
 //     - line and column numbers
 //     - source code snippet (assuming the file is accessible)
 
-// Install one of the following library then uncomment one of the macro (or
+// Install one of the following libraries then uncomment one of the macro (or
 // better, add the detection of the lib and the macro definition in your build
 // system)
 
@@ -23,6 +23,16 @@
 // - g++/clang++ -lbfd ...
 // #define BACKWARD_HAS_BFD 1
 
+// - apt-get install libdwarf-dev ...
+// - g++/clang++ -ldwarf ...
+// #define BACKWARD_HAS_DWARF 1
+
+// Regardless of the library you choose to read the debug information,
+// for potentially more detailed stack traces you can use libunwind
+// - apt-get install libunwind-dev
+// - g++/clang++ -lunwind
+// #define BACKWARD_HAS_LIBUNWIND 1
+
 #include "backward.hpp"
 
 namespace backward {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backward-cpp-1.5/backward.hpp 
new/backward-cpp-1.6/backward.hpp
--- old/backward-cpp-1.5/backward.hpp   2020-04-14 04:24:48.000000000 +0200
+++ new/backward-cpp-1.6/backward.hpp   2021-08-13 00:49:08.000000000 +0200
@@ -35,6 +35,9 @@
 #define BACKWARD_CXX11
 #define BACKWARD_ATLEAST_CXX11
 #define BACKWARD_ATLEAST_CXX98
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+#define BACKWARD_ATLEAST_CXX17
+#endif
 #else
 #define BACKWARD_CXX98
 #define BACKWARD_ATLEAST_CXX98
@@ -49,6 +52,9 @@
 // #define BACKWARD_SYSTEM_DARWIN
 //     - specialization for Mac OS X 10.5 and later.
 //
+// #define BACKWARD_SYSTEM_WINDOWS
+//  - specialization for Windows (Clang 9 and MSVC2017)
+//
 // #define BACKWARD_SYSTEM_UNKNOWN
 //     - placebo implementation, does nothing.
 //
@@ -84,6 +90,8 @@
 #include <streambuf>
 #include <string>
 #include <vector>
+#include <exception>
+#include <iterator>
 
 #if defined(BACKWARD_SYSTEM_LINUX)
 
@@ -97,6 +105,11 @@
 //  exception.
 //  - normally libgcc is already linked to your program by default.
 //
+// #define BACKWARD_HAS_LIBUNWIND 1
+//  - libunwind provides, in some cases, a more accurate stacktrace as it knows
+//  to decode signal handler frames and lets us edit the context registers when
+//  unwinding, allowing stack traces over bad function references.
+//
 // #define BACKWARD_HAS_BACKTRACE == 1
 //  - backtrace seems to be a little bit more portable than libunwind, but on
 //  linux, it uses unwind anyway, but abstract away a tiny information that is
@@ -109,10 +122,13 @@
 // Note that only one of the define should be set to 1 at a time.
 //
 #if BACKWARD_HAS_UNWIND == 1
+#elif BACKWARD_HAS_LIBUNWIND == 1
 #elif BACKWARD_HAS_BACKTRACE == 1
 #else
 #undef BACKWARD_HAS_UNWIND
 #define BACKWARD_HAS_UNWIND 1
+#undef BACKWARD_HAS_LIBUNWIND
+#define BACKWARD_HAS_LIBUNWIND 0
 #undef BACKWARD_HAS_BACKTRACE
 #define BACKWARD_HAS_BACKTRACE 0
 #endif
@@ -125,9 +141,10 @@
 //    - object filename
 //    - function name
 //    - source filename
-//       - line and column numbers
-//       - source code snippet (assuming the file is accessible)
-//       - variables name and values (if not optimized out)
+//    - line and column numbers
+//    - source code snippet (assuming the file is accessible)
+//    - variable names (if not optimized out)
+//    - variable values (not supported by backward-cpp)
 //  - You need to link with the lib "dw":
 //    - apt-get install libdw-dev
 //    - g++/clang++ -ldw ...
@@ -137,8 +154,8 @@
 //    - object filename
 //    - function name
 //    - source filename
-//       - line numbers
-//       - source code snippet (assuming the file is accessible)
+//    - line numbers
+//    - source code snippet (assuming the file is accessible)
 //  - You need to link with the lib "bfd":
 //    - apt-get install binutils-dev
 //    - g++/clang++ -lbfd ...
@@ -150,7 +167,8 @@
 //    - source filename
 //    - line and column numbers
 //    - source code snippet (assuming the file is accessible)
-//    - variables name and values (if not optimized out)
+//    - variable names (if not optimized out)
+//    - variable values (not supported by backward-cpp)
 //  - You need to link with the lib "dwarf":
 //    - apt-get install libdwarf-dev
 //    - g++/clang++ -ldwarf ...
@@ -257,6 +275,12 @@
 //  exception.
 //  - normally libgcc is already linked to your program by default.
 //
+// #define BACKWARD_HAS_LIBUNWIND 1
+//  - libunwind comes from clang, which implements an API compatible version.
+//  - libunwind provides, in some cases, a more accurate stacktrace as it knows
+//  to decode signal handler frames and lets us edit the context registers when
+//  unwinding, allowing stack traces over bad function references.
+//
 // #define BACKWARD_HAS_BACKTRACE == 1
 //  - backtrace is available by default, though it does not produce as much
 //  information as another library might.
@@ -268,11 +292,14 @@
 //
 #if BACKWARD_HAS_UNWIND == 1
 #elif BACKWARD_HAS_BACKTRACE == 1
+#elif BACKWARD_HAS_LIBUNWIND == 1
 #else
 #undef BACKWARD_HAS_UNWIND
 #define BACKWARD_HAS_UNWIND 1
 #undef BACKWARD_HAS_BACKTRACE
 #define BACKWARD_HAS_BACKTRACE 0
+#undef BACKWARD_HAS_LIBUNWIND
+#define BACKWARD_HAS_LIBUNWIND 0
 #endif
 
 // On Darwin, backward can extract detailed information about a stack trace
@@ -310,14 +337,16 @@
 #include <mutex>
 #include <thread>
 
-#include <BaseTsd.h>
+#include <basetsd.h>
 typedef SSIZE_T ssize_t;
 
+#ifndef NOMINMAX
 #define NOMINMAX
-#include <Windows.h>
+#endif
+#include <windows.h>
 #include <winnt.h>
 
-#include <Psapi.h>
+#include <psapi.h>
 #include <signal.h>
 
 #ifndef __clang__
@@ -325,8 +354,10 @@
 #define NOINLINE __declspec(noinline)
 #endif
 
+#ifdef _MSC_VER
 #pragma comment(lib, "psapi.lib")
 #pragma comment(lib, "dbghelp.lib")
+#endif
 
 // Comment / packing is from stackoverflow:
 // 
https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app/28276227#28276227
@@ -371,6 +402,11 @@
 
 #endif // BACKWARD_HAS_UNWIND == 1
 
+#if BACKWARD_HAS_LIBUNWIND == 1
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#endif // BACKWARD_HAS_LIBUNWIND == 1
+
 #ifdef BACKWARD_ATLEAST_CXX11
 #include <unordered_map>
 #include <utility> // for std::swap
@@ -530,7 +566,7 @@
 
   void update(T new_val) {
     _val = new_val;
-    _empty = static_cast<bool>(new_val);
+    _empty = !static_cast<bool>(new_val);
   }
 
   operator const dummy *() const {
@@ -609,9 +645,9 @@
   std::vector<std::string> out;
   size_t last = 0;
   size_t next = 0;
-  size_t delimiter_size = sizeof(kBackwardPathDelimiter)-1;
+  size_t delimiter_size = sizeof(kBackwardPathDelimiter) - 1;
   while ((next = s.find(kBackwardPathDelimiter, last)) != std::string::npos) {
-    out.push_back(s.substr(last, next-last));
+    out.push_back(s.substr(last, next - last));
     last = next + delimiter_size;
   }
   if (last <= s.length()) {
@@ -682,14 +718,17 @@
   size_t size() const { return 0; }
   Trace operator[](size_t) const { return Trace(); }
   size_t load_here(size_t = 0) { return 0; }
-  size_t load_from(void *, size_t = 0) { return 0; }
+  size_t load_from(void *, size_t = 0, void * = nullptr, void * = nullptr) {
+    return 0;
+  }
   size_t thread_id() const { return 0; }
   void skip_n_firsts(size_t) {}
 };
 
 class StackTraceImplBase {
 public:
-  StackTraceImplBase() : _thread_id(0), _skip(0) {}
+  StackTraceImplBase()
+      : _thread_id(0), _skip(0), _context(nullptr), _error_addr(nullptr) {}
 
   size_t thread_id() const { return _thread_id; }
 
@@ -717,17 +756,27 @@
 #endif
   }
 
+  void set_context(void *context) { _context = context; }
+  void *context() const { return _context; }
+
+  void set_error_addr(void *error_addr) { _error_addr = error_addr; }
+  void *error_addr() const { return _error_addr; }
+
   size_t skip_n_firsts() const { return _skip; }
 
 private:
   size_t _thread_id;
   size_t _skip;
+  void *_context;
+  void *_error_addr;
 };
 
 class StackTraceImplHolder : public StackTraceImplBase {
 public:
   size_t size() const {
-    return _stacktrace.size() ? _stacktrace.size() - skip_n_firsts() : 0;
+    return (_stacktrace.size() >= skip_n_firsts())
+               ? _stacktrace.size() - skip_n_firsts()
+               : 0;
   }
   Trace operator[](size_t idx) const {
     if (idx >= size()) {
@@ -808,8 +857,11 @@
 class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
 public:
   NOINLINE
-  size_t load_here(size_t depth = 32) {
+  size_t load_here(size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
     load_thread_info();
+    set_context(context);
+    set_error_addr(error_addr);
     if (depth == 0) {
       return 0;
     }
@@ -819,8 +871,9 @@
     skip_n_firsts(0);
     return size();
   }
-  size_t load_from(void *addr, size_t depth = 32) {
-    load_here(depth + 8);
+  size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
+    load_here(depth + 8, context, error_addr);
 
     for (size_t i = 0; i < _stacktrace.size(); ++i) {
       if (_stacktrace[i] == addr) {
@@ -842,13 +895,193 @@
   };
 };
 
+#elif BACKWARD_HAS_LIBUNWIND == 1
+
+template <>
+class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
+public:
+  __attribute__((noinline)) size_t load_here(size_t depth = 32,
+                                             void *_context = nullptr,
+                                             void *_error_addr = nullptr) {
+    set_context(_context);
+    set_error_addr(_error_addr);
+    load_thread_info();
+    if (depth == 0) {
+      return 0;
+    }
+    _stacktrace.resize(depth + 1);
+
+    int result = 0;
+
+    unw_context_t ctx;
+    size_t index = 0;
+
+    // Add the tail call. If the Instruction Pointer is the crash address it
+    // means we got a bad function pointer dereference, so we "unwind" the
+    // bad pointer manually by using the return address pointed to by the
+    // Stack Pointer as the Instruction Pointer and letting libunwind do
+    // the rest
+
+    if (context()) {
+      ucontext_t *uctx = reinterpret_cast<ucontext_t *>(context());
+#ifdef REG_RIP         // x86_64
+      if (uctx->uc_mcontext.gregs[REG_RIP] ==
+          reinterpret_cast<greg_t>(error_addr())) {
+        uctx->uc_mcontext.gregs[REG_RIP] =
+            *reinterpret_cast<size_t *>(uctx->uc_mcontext.gregs[REG_RSP]);
+      }
+      _stacktrace[index] =
+          reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_RIP]);
+      ++index;
+      ctx = *reinterpret_cast<unw_context_t *>(uctx);
+#elif defined(REG_EIP) // x86_32
+      if (uctx->uc_mcontext.gregs[REG_EIP] ==
+          reinterpret_cast<greg_t>(error_addr())) {
+        uctx->uc_mcontext.gregs[REG_EIP] =
+            *reinterpret_cast<size_t *>(uctx->uc_mcontext.gregs[REG_ESP]);
+      }
+      _stacktrace[index] =
+          reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_EIP]);
+      ++index;
+      ctx = *reinterpret_cast<unw_context_t *>(uctx);
+#elif defined(__arm__)
+      // libunwind uses its own context type for ARM unwinding.
+      // Copy the registers from the signal handler's context so we can
+      // unwind
+      unw_getcontext(&ctx);
+      ctx.regs[UNW_ARM_R0] = uctx->uc_mcontext.arm_r0;
+      ctx.regs[UNW_ARM_R1] = uctx->uc_mcontext.arm_r1;
+      ctx.regs[UNW_ARM_R2] = uctx->uc_mcontext.arm_r2;
+      ctx.regs[UNW_ARM_R3] = uctx->uc_mcontext.arm_r3;
+      ctx.regs[UNW_ARM_R4] = uctx->uc_mcontext.arm_r4;
+      ctx.regs[UNW_ARM_R5] = uctx->uc_mcontext.arm_r5;
+      ctx.regs[UNW_ARM_R6] = uctx->uc_mcontext.arm_r6;
+      ctx.regs[UNW_ARM_R7] = uctx->uc_mcontext.arm_r7;
+      ctx.regs[UNW_ARM_R8] = uctx->uc_mcontext.arm_r8;
+      ctx.regs[UNW_ARM_R9] = uctx->uc_mcontext.arm_r9;
+      ctx.regs[UNW_ARM_R10] = uctx->uc_mcontext.arm_r10;
+      ctx.regs[UNW_ARM_R11] = uctx->uc_mcontext.arm_fp;
+      ctx.regs[UNW_ARM_R12] = uctx->uc_mcontext.arm_ip;
+      ctx.regs[UNW_ARM_R13] = uctx->uc_mcontext.arm_sp;
+      ctx.regs[UNW_ARM_R14] = uctx->uc_mcontext.arm_lr;
+      ctx.regs[UNW_ARM_R15] = uctx->uc_mcontext.arm_pc;
+
+      // If we have crashed in the PC use the LR instead, as this was
+      // a bad function dereference
+      if (reinterpret_cast<unsigned long>(error_addr()) ==
+          uctx->uc_mcontext.arm_pc) {
+        ctx.regs[UNW_ARM_R15] =
+            uctx->uc_mcontext.arm_lr - sizeof(unsigned long);
+      }
+      _stacktrace[index] = reinterpret_cast<void *>(ctx.regs[UNW_ARM_R15]);
+      ++index;
+#elif defined(__APPLE__) && defined(__x86_64__)
+      unw_getcontext(&ctx);
+      // OS X's implementation of libunwind uses its own context object
+      // so we need to convert the passed context to libunwind's format
+      // (information about the data layout taken from unw_getcontext.s
+      // in Apple's libunwind source
+      ctx.data[0] = uctx->uc_mcontext->__ss.__rax;
+      ctx.data[1] = uctx->uc_mcontext->__ss.__rbx;
+      ctx.data[2] = uctx->uc_mcontext->__ss.__rcx;
+      ctx.data[3] = uctx->uc_mcontext->__ss.__rdx;
+      ctx.data[4] = uctx->uc_mcontext->__ss.__rdi;
+      ctx.data[5] = uctx->uc_mcontext->__ss.__rsi;
+      ctx.data[6] = uctx->uc_mcontext->__ss.__rbp;
+      ctx.data[7] = uctx->uc_mcontext->__ss.__rsp;
+      ctx.data[8] = uctx->uc_mcontext->__ss.__r8;
+      ctx.data[9] = uctx->uc_mcontext->__ss.__r9;
+      ctx.data[10] = uctx->uc_mcontext->__ss.__r10;
+      ctx.data[11] = uctx->uc_mcontext->__ss.__r11;
+      ctx.data[12] = uctx->uc_mcontext->__ss.__r12;
+      ctx.data[13] = uctx->uc_mcontext->__ss.__r13;
+      ctx.data[14] = uctx->uc_mcontext->__ss.__r14;
+      ctx.data[15] = uctx->uc_mcontext->__ss.__r15;
+      ctx.data[16] = uctx->uc_mcontext->__ss.__rip;
+
+      // If the IP is the same as the crash address we have a bad function
+      // dereference The caller's address is pointed to by %rsp, so we
+      // dereference that value and set it to be the next frame's IP.
+      if (uctx->uc_mcontext->__ss.__rip ==
+          reinterpret_cast<__uint64_t>(error_addr())) {
+        ctx.data[16] =
+            *reinterpret_cast<__uint64_t *>(uctx->uc_mcontext->__ss.__rsp);
+      }
+      _stacktrace[index] = reinterpret_cast<void *>(ctx.data[16]);
+      ++index;
+#elif defined(__APPLE__)
+      unw_getcontext(&ctx)
+          // TODO: Convert the ucontext_t to libunwind's unw_context_t like
+          // we do in 64 bits
+          if (ctx.uc_mcontext->__ss.__eip ==
+              reinterpret_cast<greg_t>(error_addr())) {
+        ctx.uc_mcontext->__ss.__eip = ctx.uc_mcontext->__ss.__esp;
+      }
+      _stacktrace[index] =
+          reinterpret_cast<void *>(ctx.uc_mcontext->__ss.__eip);
+      ++index;
+#endif
+    }
+
+    unw_cursor_t cursor;
+    if (context()) {
+#if defined(UNW_INIT_SIGNAL_FRAME)
+      result = unw_init_local2(&cursor, &ctx, UNW_INIT_SIGNAL_FRAME);
+#else
+      result = unw_init_local(&cursor, &ctx);
+#endif
+    } else {
+      unw_getcontext(&ctx);
+      ;
+      result = unw_init_local(&cursor, &ctx);
+    }
+
+    if (result != 0)
+      return 1;
+
+    unw_word_t ip = 0;
+
+    while (index <= depth && unw_step(&cursor) > 0) {
+      result = unw_get_reg(&cursor, UNW_REG_IP, &ip);
+      if (result == 0) {
+        _stacktrace[index] = reinterpret_cast<void *>(--ip);
+        ++index;
+      }
+    }
+    --index;
+
+    _stacktrace.resize(index + 1);
+    skip_n_firsts(0);
+    return size();
+  }
+
+  size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
+    load_here(depth + 8, context, error_addr);
+
+    for (size_t i = 0; i < _stacktrace.size(); ++i) {
+      if (_stacktrace[i] == addr) {
+        skip_n_firsts(i);
+        _stacktrace[i] = (void *)((uintptr_t)_stacktrace[i]);
+        break;
+      }
+    }
+
+    _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth));
+    return size();
+  }
+};
+
 #elif defined(BACKWARD_HAS_BACKTRACE)
 
 template <>
 class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
 public:
   NOINLINE
-  size_t load_here(size_t depth = 32) {
+  size_t load_here(size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
+    set_context(context);
+    set_error_addr(error_addr);
     load_thread_info();
     if (depth == 0) {
       return 0;
@@ -860,8 +1093,9 @@
     return size();
   }
 
-  size_t load_from(void *addr, size_t depth = 32) {
-    load_here(depth + 8);
+  size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
+    load_here(depth + 8, context, error_addr);
 
     for (size_t i = 0; i < _stacktrace.size(); ++i) {
       if (_stacktrace[i] == addr) {
@@ -888,8 +1122,10 @@
   void set_thread_handle(HANDLE handle) { thd_ = handle; }
 
   NOINLINE
-  size_t load_here(size_t depth = 32) {
-
+  size_t load_here(size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
+    set_context(static_cast<CONTEXT*>(context));
+    set_error_addr(error_addr);
     CONTEXT localCtx; // used when no context is provided
 
     if (depth == 0) {
@@ -951,8 +1187,9 @@
     return size();
   }
 
-  size_t load_from(void *addr, size_t depth = 32) {
-    load_here(depth + 8);
+  size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
+                   void *error_addr = nullptr) {
+    load_here(depth + 8, context, error_addr);
 
     for (size_t i = 0; i < _stacktrace.size(); ++i) {
       if (_stacktrace[i] == addr) {
@@ -977,19 +1214,21 @@
 
 /*************** TRACE RESOLVER ***************/
 
-template <typename TAG> class TraceResolverImpl;
+class TraceResolverImplBase {
+public:
+  virtual ~TraceResolverImplBase() {}
 
-#ifdef BACKWARD_SYSTEM_UNKNOWN
+  virtual void load_addresses(void *const*addresses, int address_count) {
+    (void)addresses;
+    (void)address_count;
+  }
 
-template <> class TraceResolverImpl<system_tag::unknown_tag> {
-public:
-  template <class ST> void load_stacktrace(ST &) {}
-  ResolvedTrace resolve(ResolvedTrace t) { return t; }
-};
+  template <class ST> void load_stacktrace(ST &st) {
+    load_addresses(st.begin(), (int)st.size());
+  }
 
-#endif
+  virtual ResolvedTrace resolve(ResolvedTrace t) { return t; }
 
-class TraceResolverImplBase {
 protected:
   std::string demangle(const char *funcname) {
     return _demangler.demangle(funcname);
@@ -999,29 +1238,44 @@
   details::demangler _demangler;
 };
 
+template <typename TAG> class TraceResolverImpl;
+
+#ifdef BACKWARD_SYSTEM_UNKNOWN
+
+template <> class TraceResolverImpl<system_tag::unknown_tag>
+    : public TraceResolverImplBase {};
+
+#endif
+
 #ifdef BACKWARD_SYSTEM_LINUX
 
-class TraceResolverLinuxBase
-    : public TraceResolverImplBase {
+class TraceResolverLinuxBase : public TraceResolverImplBase {
 public:
   TraceResolverLinuxBase()
-    : argv0_(get_argv0()), exec_path_(read_symlink("/proc/self/exe")) {
-  }
+      : argv0_(get_argv0()), exec_path_(read_symlink("/proc/self/exe")) {}
   std::string resolve_exec_path(Dl_info &symbol_info) const {
-    // mutates symbol_info.dli_fname to be filename to open and returns 
filename to display
-    if(symbol_info.dli_fname == argv0_) {
+    // mutates symbol_info.dli_fname to be filename to open and returns 
filename
+    // to display
+    if (symbol_info.dli_fname == argv0_) {
       // dladdr returns argv[0] in dli_fname for symbols contained in
       // the main executable, which is not a valid path if the
       // executable was found by a search of the PATH environment
       // variable; In that case, we actually open /proc/self/exe, which
       // is always the actual executable (even if it was deleted/replaced!)
       // but display the path that /proc/self/exe links to.
+      // However, this right away reduces probability of successful symbol
+      // resolution, because libbfd may try to find *.debug files in the
+      // same dir, in case symbols are stripped. As a result, it may try
+      // to find a file /proc/self/<exe_name>.debug, which obviously does
+      // not exist. /proc/self/exe is a last resort. First load attempt
+      // should go for the original executable file path.
       symbol_info.dli_fname = "/proc/self/exe";
       return exec_path_;
     } else {
       return symbol_info.dli_fname;
     }
   }
+
 private:
   std::string argv0_;
   std::string exec_path_;
@@ -1063,15 +1317,14 @@
 class TraceResolverLinuxImpl<trace_resolver_tag::backtrace_symbol>
     : public TraceResolverLinuxBase {
 public:
-  template <class ST> void load_stacktrace(ST &st) {
-    using namespace details;
-    if (st.size() == 0) {
+  void load_addresses(void *const*addresses, int address_count) override {
+    if (address_count == 0) {
       return;
     }
-    _symbols.reset(backtrace_symbols(st.begin(), (int)st.size()));
+    _symbols.reset(backtrace_symbols(addresses, address_count));
   }
 
-  ResolvedTrace resolve(ResolvedTrace trace) {
+  ResolvedTrace resolve(ResolvedTrace trace) override {
     char *filename = _symbols[trace.idx];
     char *funcname = filename;
     while (*funcname && *funcname != '(') {
@@ -1108,9 +1361,7 @@
 public:
   TraceResolverLinuxImpl() : _bfd_loaded(false) {}
 
-  template <class ST> void load_stacktrace(ST &) {}
-
-  ResolvedTrace resolve(ResolvedTrace trace) {
+  ResolvedTrace resolve(ResolvedTrace trace) override {
     Dl_info symbol_info;
 
     // trace.addr is a virtual address in memory pointing to some code.
@@ -1140,9 +1391,45 @@
     }
 
     trace.object_filename = resolve_exec_path(symbol_info);
-    bfd_fileobject &fobj = load_object_with_bfd(symbol_info.dli_fname);
-    if (!fobj.handle) {
-      return trace; // sad, we couldn't load the object :(
+    bfd_fileobject *fobj;
+    // Before rushing to resolution need to ensure the executable
+    // file still can be used. For that compare inode numbers of
+    // what is stored by the executable's file path, and in the
+    // dli_fname, which not necessarily equals to the executable.
+    // It can be a shared library, or /proc/self/exe, and in the
+    // latter case has drawbacks. See the exec path resolution for
+    // details. In short - the dli object should be used only as
+    // the last resort.
+    // If inode numbers are equal, it is known dli_fname and the
+    // executable file are the same. This is guaranteed by Linux,
+    // because if the executable file is changed/deleted, it will
+    // be done in a new inode. The old file will be preserved in
+    // /proc/self/exe, and may even have inode 0. The latter can
+    // happen if the inode was actually reused, and the file was
+    // kept only in the main memory.
+    //
+    struct stat obj_stat;
+    struct stat dli_stat;
+    if (stat(trace.object_filename.c_str(), &obj_stat) == 0 &&
+        stat(symbol_info.dli_fname, &dli_stat) == 0 &&
+        obj_stat.st_ino == dli_stat.st_ino) {
+      // The executable file, and the shared object containing the
+      // address are the same file. Safe to use the original path.
+      // this is preferable. Libbfd will search for stripped debug
+      // symbols in the same directory.
+      fobj = load_object_with_bfd(trace.object_filename);
+    } else{
+      // The original object file was *deleted*! The only hope is
+      // that the debug symbols are either inside the shared
+      // object file, or are in the same directory, and this is
+      // not /proc/self/exe.
+      fobj = nullptr;
+    }
+    if (fobj == nullptr || !fobj->handle) {
+      fobj = load_object_with_bfd(symbol_info.dli_fname);
+      if (!fobj->handle) {
+        return trace;
+      }
     }
 
     find_sym_result *details_selected; // to be filled.
@@ -1277,7 +1564,7 @@
   typedef details::hashtable<std::string, bfd_fileobject>::type fobj_bfd_map_t;
   fobj_bfd_map_t _fobj_bfd_map;
 
-  bfd_fileobject &load_object_with_bfd(const std::string &filename_object) {
+  bfd_fileobject *load_object_with_bfd(const std::string &filename_object) {
     using namespace details;
 
     if (!_bfd_loaded) {
@@ -1288,11 +1575,11 @@
 
     fobj_bfd_map_t::iterator it = _fobj_bfd_map.find(filename_object);
     if (it != _fobj_bfd_map.end()) {
-      return it->second;
+      return &it->second;
     }
 
     // this new object is empty for now.
-    bfd_fileobject &r = _fobj_bfd_map[filename_object];
+    bfd_fileobject *r = &_fobj_bfd_map[filename_object];
 
     // we do the work temporary in this one;
     bfd_handle_t bfd_handle;
@@ -1341,9 +1628,9 @@
       return r; // damned, that's a stripped file that you got there!
     }
 
-    r.handle = move(bfd_handle);
-    r.symtab = move(symtab);
-    r.dynamic_symtab = move(dynamic_symtab);
+    r->handle = move(bfd_handle);
+    r->symtab = move(symtab);
+    r->dynamic_symtab = move(dynamic_symtab);
     return r;
   }
 
@@ -1362,15 +1649,15 @@
     find_sym_result result;
   };
 
-  find_sym_result find_symbol_details(bfd_fileobject &fobj, void *addr,
+  find_sym_result find_symbol_details(bfd_fileobject *fobj, void *addr,
                                       void *base_addr) {
     find_sym_context context;
     context.self = this;
-    context.fobj = &fobj;
+    context.fobj = fobj;
     context.addr = addr;
     context.base_addr = base_addr;
     context.result.found = false;
-    bfd_map_over_sections(fobj.handle.get(), &find_in_section_trampoline,
+    bfd_map_over_sections(fobj->handle.get(), &find_in_section_trampoline,
                           static_cast<void *>(&context));
     return context.result;
   }
@@ -1379,24 +1666,24 @@
     find_sym_context *context = static_cast<find_sym_context *>(data);
     context->self->find_in_section(
         reinterpret_cast<bfd_vma>(context->addr),
-        reinterpret_cast<bfd_vma>(context->base_addr), *context->fobj, section,
+        reinterpret_cast<bfd_vma>(context->base_addr), context->fobj, section,
         context->result);
   }
 
-  void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject &fobj,
+  void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject *fobj,
                        asection *section, find_sym_result &result) {
     if (result.found)
       return;
 
 #ifdef bfd_get_section_flags
-    if ((bfd_get_section_flags(fobj.handle.get(), section) & SEC_ALLOC) == 0)
+    if ((bfd_get_section_flags(fobj->handle.get(), section) & SEC_ALLOC) == 0)
 #else
     if ((bfd_section_flags(section) & SEC_ALLOC) == 0)
 #endif
       return; // a debug section is never loaded automatically.
 
 #ifdef bfd_get_section_vma
-    bfd_vma sec_addr = bfd_get_section_vma(fobj.handle.get(), section);
+    bfd_vma sec_addr = bfd_get_section_vma(fobj->handle.get(), section);
 #else
     bfd_vma sec_addr = bfd_section_vma(section);
 #endif
@@ -1418,15 +1705,15 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
 #endif
-    if (!result.found && fobj.symtab) {
+    if (!result.found && fobj->symtab) {
       result.found = bfd_find_nearest_line(
-          fobj.handle.get(), section, fobj.symtab.get(), addr - sec_addr,
+          fobj->handle.get(), section, fobj->symtab.get(), addr - sec_addr,
           &result.filename, &result.funcname, &result.line);
     }
 
-    if (!result.found && fobj.dynamic_symtab) {
+    if (!result.found && fobj->dynamic_symtab) {
       result.found = bfd_find_nearest_line(
-          fobj.handle.get(), section, fobj.dynamic_symtab.get(),
+          fobj->handle.get(), section, fobj->dynamic_symtab.get(),
           addr - sec_addr, &result.filename, &result.funcname, &result.line);
     }
 #if defined(__clang__)
@@ -1435,13 +1722,13 @@
   }
 
   ResolvedTrace::source_locs_t
-  backtrace_inliners(bfd_fileobject &fobj, find_sym_result previous_result) {
+  backtrace_inliners(bfd_fileobject *fobj, find_sym_result previous_result) {
     // This function can be called ONLY after a SUCCESSFUL call to
     // find_symbol_details. The state is global to the bfd_handle.
     ResolvedTrace::source_locs_t results;
     while (previous_result.found) {
       find_sym_result result;
-      result.found = bfd_find_inliner_info(fobj.handle.get(), &result.filename,
+      result.found = bfd_find_inliner_info(fobj->handle.get(), 
&result.filename,
                                            &result.funcname, &result.line);
 
       if (result
@@ -1484,9 +1771,7 @@
 public:
   TraceResolverLinuxImpl() : _dwfl_handle_initialized(false) {}
 
-  template <class ST> void load_stacktrace(ST &) {}
-
-  ResolvedTrace resolve(ResolvedTrace trace) {
+  ResolvedTrace resolve(ResolvedTrace trace) override {
     using namespace details;
 
     Dwarf_Addr trace_addr = (Dwarf_Addr)trace.addr;
@@ -1779,9 +2064,9 @@
 
   static const char *die_call_file(Dwarf_Die *die) {
     Dwarf_Attribute attr_mem;
-    Dwarf_Sword file_idx = 0;
+    Dwarf_Word file_idx = 0;
 
-    dwarf_formsdata(dwarf_attr(die, DW_AT_call_file, &attr_mem), &file_idx);
+    dwarf_formudata(dwarf_attr(die, DW_AT_call_file, &attr_mem), &file_idx);
 
     if (file_idx == 0) {
       return 0;
@@ -1813,9 +2098,7 @@
 public:
   TraceResolverLinuxImpl() : _dwarf_loaded(false) {}
 
-  template <class ST> void load_stacktrace(ST &) {}
-
-  ResolvedTrace resolve(ResolvedTrace trace) {
+  ResolvedTrace resolve(ResolvedTrace trace) override {
     // trace.addr is a virtual address in memory pointing to some code.
     // Let's try to find from which loaded object it comes from.
     // The loaded object can be yourself btw.
@@ -2831,7 +3114,7 @@
             trace.object_function = demangler.demangle(linkage);
             dwarf_dealloc(dwarf, linkage, DW_DLA_STRING);
           }
-          dwarf_dealloc(dwarf, name, DW_DLA_ATTR);
+          dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
         }
         break;
 
@@ -3039,12 +3322,12 @@
                                    Dwarf_Die cu_die) {
     Dwarf_Attribute attr_mem;
     Dwarf_Error error = DW_DLE_NE;
-    Dwarf_Signed file_index;
+    Dwarf_Unsigned file_index;
 
     std::string file;
 
     if (dwarf_attr(die, DW_AT_call_file, &attr_mem, &error) == DW_DLV_OK) {
-      if (dwarf_formsdata(attr_mem, &file_index, &error) != DW_DLV_OK) {
+      if (dwarf_formudata(attr_mem, &file_index, &error) != DW_DLV_OK) {
         file_index = 0;
       }
       dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
@@ -3056,8 +3339,9 @@
       char **srcfiles = 0;
       Dwarf_Signed file_count = 0;
       if (dwarf_srcfiles(cu_die, &srcfiles, &file_count, &error) == DW_DLV_OK) 
{
-        if (file_index <= file_count)
+        if (file_count > 0 && file_index <= 
static_cast<Dwarf_Unsigned>(file_count)) {
           file = std::string(srcfiles[file_index - 1]);
+       }
 
         // Deallocate all strings!
         for (int i = 0; i < file_count; ++i) {
@@ -3194,15 +3478,14 @@
 class TraceResolverDarwinImpl<trace_resolver_tag::backtrace_symbol>
     : public TraceResolverImplBase {
 public:
-  template <class ST> void load_stacktrace(ST &st) {
-    using namespace details;
-    if (st.size() == 0) {
+  void load_addresses(void *const*addresses, int address_count) override {
+    if (address_count == 0) {
       return;
     }
-    _symbols.reset(backtrace_symbols(st.begin(), st.size()));
+    _symbols.reset(backtrace_symbols(addresses, address_count));
   }
 
-  ResolvedTrace resolve(ResolvedTrace trace) {
+  ResolvedTrace resolve(ResolvedTrace trace) override {
     // parse:
     // <n>  <file>  <addr>  <mangled-name> + <offset>
     char *filename = _symbols[trace.idx];
@@ -3300,9 +3583,9 @@
     ret.base_address = mi.lpBaseOfDll;
     ret.load_size = mi.SizeOfImage;
 
-    GetModuleFileNameEx(process, module, temp, sizeof(temp));
+    GetModuleFileNameExA(process, module, temp, sizeof(temp));
     ret.image_name = temp;
-    GetModuleBaseName(process, module, temp, sizeof(temp));
+    GetModuleBaseNameA(process, module, temp, sizeof(temp));
     ret.module_name = temp;
     std::vector<char> img(ret.image_name.begin(), ret.image_name.end());
     std::vector<char> mod(ret.module_name.begin(), ret.module_name.end());
@@ -3312,7 +3595,8 @@
   }
 };
 
-template <> class TraceResolverImpl<system_tag::windows_tag> {
+template <> class TraceResolverImpl<system_tag::windows_tag>
+    : public TraceResolverImplBase {
 public:
   TraceResolverImpl() {
 
@@ -3337,8 +3621,6 @@
     image_type = h->FileHeader.Machine;
   }
 
-  template <class ST> void load_stacktrace(ST &) {}
-
   static const int max_sym_len = 255;
   struct symbol_t {
     SYMBOL_INFO sym;
@@ -3347,27 +3629,28 @@
 
   DWORD64 displacement;
 
-  ResolvedTrace resolve(ResolvedTrace t) {
+  ResolvedTrace resolve(ResolvedTrace t) override {
     HANDLE process = GetCurrentProcess();
 
     char name[256];
 
-    memset(&sym, sizeof(sym), 0);
+    memset(&sym, 0, sizeof(sym));
     sym.sym.SizeOfStruct = sizeof(SYMBOL_INFO);
     sym.sym.MaxNameLen = max_sym_len;
 
     if (!SymFromAddr(process, (ULONG64)t.addr, &displacement, &sym.sym)) {
       // TODO:  error handling everywhere
-      LPTSTR lpMsgBuf;
+      char* lpMsgBuf;
       DWORD dw = GetLastError();
 
-      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                        FORMAT_MESSAGE_FROM_SYSTEM |
-                        FORMAT_MESSAGE_IGNORE_INSERTS,
-                    NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                    (LPTSTR)&lpMsgBuf, 0, NULL);
-
-      printf(lpMsgBuf);
+      if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                             FORMAT_MESSAGE_FROM_SYSTEM |
+                             FORMAT_MESSAGE_IGNORE_INSERTS,
+                         NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                         (char*)&lpMsgBuf, 0, NULL)) {
+        std::fprintf(stderr, "%s\n", lpMsgBuf);
+        LocalFree(lpMsgBuf);
+      }
 
       // abort();
     }
@@ -3410,12 +3693,13 @@
     // 1. If BACKWARD_CXX_SOURCE_PREFIXES is set then assume it contains
     //    a colon-separated list of path prefixes.  Try prepending each
     //    to the given path until a valid file is found.
-    const std::vector<std::string>& prefixes = get_paths_from_env_variable();
+    const std::vector<std::string> &prefixes = get_paths_from_env_variable();
     for (size_t i = 0; i < prefixes.size(); ++i) {
       // Double slashes (//) should not be a problem.
       std::string new_path = prefixes[i] + '/' + path;
       _file.reset(new std::ifstream(new_path.c_str()));
-      if (is_open()) break;
+      if (is_open())
+        break;
     }
     // 2. If no valid file found then fallback to opening the path as-is.
     if (!_file || !is_open()) {
@@ -3519,14 +3803,14 @@
 
   std::vector<std::string> get_paths_from_env_variable_impl() {
     std::vector<std::string> paths;
-    const char* prefixes_str = std::getenv("BACKWARD_CXX_SOURCE_PREFIXES");
+    const char *prefixes_str = std::getenv("BACKWARD_CXX_SOURCE_PREFIXES");
     if (prefixes_str && prefixes_str[0]) {
       paths = details::split_source_prefixes(prefixes_str);
     }
     return paths;
   }
 
-  const std::vector<std::string>& get_paths_from_env_variable() {
+  const std::vector<std::string> &get_paths_from_env_variable() {
     static std::vector<std::string> paths = get_paths_from_env_variable_impl();
     return paths;
   }
@@ -3605,7 +3889,7 @@
   cfile_streambuf(FILE *_sink) : sink(_sink) {}
   int_type underflow() override { return traits_type::eof(); }
   int_type overflow(int_type ch) override {
-    if (traits_type::not_eof(ch) && fwrite(&ch, sizeof ch, 1, sink) == 1) {
+    if (traits_type::not_eof(ch) && fputc(ch, sink) != EOF) {
       return ch;
     }
     return traits_type::eof();
@@ -3928,12 +4212,19 @@
 #elif defined(__arm__)
     error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.arm_pc);
 #elif defined(__aarch64__)
-    error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.pc);
+    #if defined(__APPLE__)
+      error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__pc);
+    #else
+      error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.pc);
+    #endif
 #elif defined(__mips__)
-    error_addr = reinterpret_cast<void *>(reinterpret_cast<struct 
sigcontext*>(&uctx->uc_mcontext)->sc_pc);
+    error_addr = reinterpret_cast<void *>(
+        reinterpret_cast<struct sigcontext *>(&uctx->uc_mcontext)->sc_pc);
 #elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) ||        
\
     defined(__POWERPC__)
     error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.regs->nip);
+#elif defined(__riscv)
+    error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.__gregs[REG_PC]);
 #elif defined(__s390x__)
     error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.psw.addr);
 #elif defined(__APPLE__) && defined(__x86_64__)
@@ -3944,9 +4235,10 @@
 #warning ":/ sorry, ain't know no nothing none not of your architecture!"
 #endif
     if (error_addr) {
-      st.load_from(error_addr, 32);
+      st.load_from(error_addr, 32, reinterpret_cast<void *>(uctx),
+                   info->si_addr);
     } else {
-      st.load_here(32);
+      st.load_here(32, reinterpret_cast<void *>(uctx), info->si_addr);
     }
 
     Printer printer;
@@ -4014,8 +4306,10 @@
     signal(SIGABRT, signal_handler);
     _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
 
-    set_terminate(&terminator);
-    set_unexpected(&terminator);
+    std::set_terminate(&terminator);
+#ifndef BACKWARD_ATLEAST_CXX17
+    std::set_unexpected(&terminator);
+#endif
     _set_purecall_handler(&terminator);
     _set_invalid_parameter_handler(&invalid_parameter_handler);
   }
@@ -4143,9 +4437,8 @@
 
     StackTrace st;
     st.set_machine_type(printer.resolver().machine_type());
-    st.set_context(ctx());
     st.set_thread_handle(thread_handle());
-    st.load_here(32 + skip_frames);
+    st.load_here(32 + skip_frames, ctx());
     st.skip_n_firsts(skip_frames);
 
     printer.address = true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/backward-cpp-1.5/test/_test_main.cpp 
new/backward-cpp-1.6/test/_test_main.cpp
--- old/backward-cpp-1.5/test/_test_main.cpp    2020-04-14 04:24:48.000000000 
+0200
+++ new/backward-cpp-1.6/test/_test_main.cpp    2021-08-13 00:49:08.000000000 
+0200
@@ -26,7 +26,7 @@
 #include <cstdlib>
 
 #ifdef _WIN32
-#include <Windows.h>
+#include <windows.h>
 #define strcasecmp _stricmp
 #else
 #include <sys/wait.h>

Reply via email to