Import backtrace-cpp and integrate it into our main executable
Upstream release https://github.com/bombela/backward-cpp/archive/v1.3.tar.gz
This commit is contained in:
parent
5a1728c8d4
commit
e6a0821cfc
25 changed files with 3606 additions and 1 deletions
1
external/CMakeLists.txt
vendored
1
external/CMakeLists.txt
vendored
|
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(process-cpp-minimal)
|
||||
add_subdirectory(android-emugl)
|
||||
add_subdirectory(xdg)
|
||||
add_subdirectory(backtrace-cpp)
|
||||
|
|
|
|||
2
external/backtrace-cpp/.gitignore
vendored
Normal file
2
external/backtrace-cpp/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
build*/
|
||||
*.pyc
|
||||
25
external/backtrace-cpp/.travis.yml
vendored
Normal file
25
external/backtrace-cpp/.travis.yml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- valgrind
|
||||
|
||||
install:
|
||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||
- mkdir ${DEPS_DIR} && cd ${DEPS_DIR}
|
||||
- CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
|
||||
- mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
||||
- export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||
- pip install --user conan && export PATH=$PATH:$HOME/.local/bin
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- mkdir build && cd build
|
||||
- cmake .. -DBACKWARD_TESTS=ON
|
||||
- cmake --build .
|
||||
|
||||
script:
|
||||
- valgrind ctest .. --verbose
|
||||
- cd ${TRAVIS_BUILD_DIR} && conan test_package --build=outdated
|
||||
143
external/backtrace-cpp/BackwardConfig.cmake
vendored
Normal file
143
external/backtrace-cpp/BackwardConfig.cmake
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#
|
||||
# BackwardMacros.cmake
|
||||
# Copyright 2013 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
###############################################################################
|
||||
# OPTIONS
|
||||
###############################################################################
|
||||
|
||||
set(STACK_WALKING_UNWIND TRUE CACHE BOOL
|
||||
"Use compiler's unwind API")
|
||||
set(STACK_WALKING_BACKTRACE FALSE CACHE BOOL
|
||||
"Use backtrace from (e)glibc for stack walking")
|
||||
|
||||
set(STACK_DETAILS_AUTO_DETECT TRUE CACHE BOOL
|
||||
"Auto detect backward's stack details dependencies")
|
||||
|
||||
set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE CACHE BOOL
|
||||
"Use backtrace from (e)glibc for symbols resolution")
|
||||
set(STACK_DETAILS_DW FALSE CACHE BOOL
|
||||
"Use libdw to read debug info")
|
||||
set(STACK_DETAILS_BFD FALSE CACHE BOOL
|
||||
"Use libbfd to read debug info")
|
||||
|
||||
###############################################################################
|
||||
# CONFIGS
|
||||
###############################################################################
|
||||
if (${STACK_DETAILS_AUTO_DETECT})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
# 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)
|
||||
mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY)
|
||||
|
||||
# find libbfd
|
||||
find_path(LIBBFD_INCLUDE_DIR NAMES "bfd.h")
|
||||
find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
|
||||
find_library(LIBBFD_LIBRARY bfd)
|
||||
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
|
||||
LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
|
||||
mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY
|
||||
LIBDL_INCLUDE_DIR LIBDL_LIBRARY)
|
||||
|
||||
if (LIBDW_FOUND)
|
||||
LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDW_INCLUDE_DIRS})
|
||||
LIST(APPEND BACKWARD_LIBRARIES ${LIBDW_LIBRARIES})
|
||||
set(STACK_DETAILS_DW TRUE)
|
||||
set(STACK_DETAILS_BFD FALSE)
|
||||
set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
|
||||
elseif(LIBBFD_FOUND)
|
||||
LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIRS})
|
||||
LIST(APPEND BACKWARD_LIBRARIES ${LIBBFD_LIBRARIES})
|
||||
set(STACK_DETAILS_DW FALSE)
|
||||
set(STACK_DETAILS_BFD TRUE)
|
||||
set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
|
||||
else()
|
||||
set(STACK_DETAILS_DW FALSE)
|
||||
set(STACK_DETAILS_BFD FALSE)
|
||||
set(STACK_DETAILS_BACKTRACE_SYMBOL TRUE)
|
||||
endif()
|
||||
else()
|
||||
if (STACK_DETAILS_DW)
|
||||
LIST(APPEND BACKWARD_LIBRARIES dw)
|
||||
endif()
|
||||
|
||||
if (STACK_DETAILS_BFD)
|
||||
LIST(APPEND BACKWARD_LIBRARIES bfd dl)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(map_definitions var_prefix define_prefix)
|
||||
foreach(def ${ARGN})
|
||||
if (${${var_prefix}${def}})
|
||||
LIST(APPEND BACKWARD_DEFINITIONS "${define_prefix}${def}=1")
|
||||
else()
|
||||
LIST(APPEND BACKWARD_DEFINITIONS "${define_prefix}${def}=0")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
if (NOT BACKWARD_DEFINITIONS)
|
||||
map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND BACKTRACE)
|
||||
map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW BFD)
|
||||
endif()
|
||||
|
||||
foreach(def ${BACKWARD_DEFINITIONS})
|
||||
message(STATUS "${def}")
|
||||
endforeach()
|
||||
|
||||
find_path(BACKWARD_INCLUDE_DIR backward.hpp PATHS ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Backward
|
||||
REQUIRED_VARS
|
||||
BACKWARD_INCLUDE_DIR
|
||||
BACKWARD_LIBRARIES
|
||||
)
|
||||
list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR})
|
||||
|
||||
macro(add_backward target)
|
||||
target_include_directories(${target} PRIVATE ${_BACKWARD_INCLUDE_DIRS})
|
||||
set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS ${BACKWARD_DEFINITIONS})
|
||||
set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES ${BACKWARD_LIBRARIES})
|
||||
endmacro()
|
||||
set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "_BACKWARD_INCLUDE_DIRS")
|
||||
set(BACKWARD_DEFINITIONS ${BACKWARD_DEFINITIONS} CACHE INTERNAL "BACKWARD_DEFINITIONS")
|
||||
set(BACKWARD_LIBRARIES ${BACKWARD_LIBRARIES} CACHE INTERNAL "BACKWARD_LIBRARIES")
|
||||
mark_as_advanced(_BACKWARD_INCLUDE_DIRS BACKWARD_DEFINITIONS BACKWARD_LIBRARIES)
|
||||
|
||||
if (NOT TARGET Backward::Backward)
|
||||
add_library(Backward::Backward INTERFACE IMPORTED)
|
||||
set_target_properties(Backward::Backward PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_BACKWARD_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${BACKWARD_LIBRARIES}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "${BACKWARD_DEFINITIONS}"
|
||||
)
|
||||
endif()
|
||||
112
external/backtrace-cpp/CMakeLists.txt
vendored
Normal file
112
external/backtrace-cpp/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#
|
||||
# CMakeLists.txt
|
||||
# Copyright 2013 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(backward CXX)
|
||||
|
||||
include(BackwardConfig.cmake)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
###############################################################################
|
||||
# COMPILER FLAGS
|
||||
###############################################################################
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic-errors")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
|
||||
endif()
|
||||
|
||||
###############################################################################
|
||||
# BACKWARD OBJECT
|
||||
###############################################################################
|
||||
|
||||
add_library(backward_object OBJECT backward.cpp)
|
||||
target_compile_definitions(backward_object PRIVATE ${BACKWARD_DEFINITIONS})
|
||||
target_include_directories(backward_object PRIVATE ${BACKWARD_INCLUDE_DIRS})
|
||||
set(BACKWARD_ENABLE $<TARGET_OBJECTS:backward_object> CACHE STRING
|
||||
"Link with this object to setup backward automatically")
|
||||
|
||||
|
||||
###############################################################################
|
||||
# BACKWARD LIBRARY (Includes backward.cpp)
|
||||
###############################################################################
|
||||
option(BACKWARD_SHARED "Build dynamic backward-cpp shared lib" OFF)
|
||||
|
||||
if(BACKWARD_SHARED)
|
||||
set(libtype SHARED)
|
||||
endif()
|
||||
add_library(backward ${libtype} backward.cpp)
|
||||
target_compile_definitions(backward PUBLIC ${BACKWARD_DEFINITIONS})
|
||||
target_include_directories(backward PUBLIC ${BACKWARD_INCLUDE_DIRS})
|
||||
|
||||
###############################################################################
|
||||
# TESTS
|
||||
###############################################################################
|
||||
|
||||
if(BACKWARD_TESTS)
|
||||
enable_testing()
|
||||
|
||||
add_library(test_main SHARED test/_test_main.cpp)
|
||||
|
||||
macro(backward_add_test src)
|
||||
get_filename_component(name ${src} NAME_WE)
|
||||
set(test_name "test_${name}")
|
||||
|
||||
add_executable(${test_name} ${src} ${ARGN})
|
||||
|
||||
target_link_libraries(${test_name} PRIVATE Backward::Backward test_main)
|
||||
|
||||
add_test(NAME ${name} COMMAND ${test_name})
|
||||
endmacro()
|
||||
|
||||
# Tests without backward.cpp
|
||||
set(TESTS
|
||||
test
|
||||
stacktrace
|
||||
rectrace
|
||||
select_signals
|
||||
)
|
||||
|
||||
foreach(test ${TESTS})
|
||||
backward_add_test(test/${test}.cpp)
|
||||
endforeach()
|
||||
|
||||
# Tests with backward.cpp
|
||||
set(TESTS
|
||||
suicide
|
||||
)
|
||||
|
||||
foreach(test ${TESTS})
|
||||
backward_add_test(test/${test}.cpp ${BACKWARD_ENABLE})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES "backward.hpp"
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/include
|
||||
)
|
||||
install(
|
||||
FILES "BackwardConfig.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/backward
|
||||
)
|
||||
21
external/backtrace-cpp/LICENSE.txt
vendored
Normal file
21
external/backtrace-cpp/LICENSE.txt
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
378
external/backtrace-cpp/README.md
vendored
Normal file
378
external/backtrace-cpp/README.md
vendored
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
Backward-cpp [](http://www.conan.io/source/backward/0.0.0/Manu343726/testing) [](https://travis-ci.org/cwbombela/backward-cpp)
|
||||
============
|
||||
|
||||
Backward is a beautiful stack trace pretty printer for C++.
|
||||
|
||||
If you are bored to see this:
|
||||
|
||||

|
||||
|
||||
Backward will spice it up for you:
|
||||
|
||||

|
||||
|
||||
There is not much to say. Of course it will be able to display the code
|
||||
snippets only if the source files are accessible (else see trace #4 in the
|
||||
example).
|
||||
|
||||
All "Source" lines and code snippet prefixed by a pipe "|" are frames inline
|
||||
the next frame.
|
||||
You can see that for the trace #1 in the example, the function
|
||||
`you_shall_not_pass()` was inlined in the function `...read2::do_test()` by the
|
||||
compiler.
|
||||
|
||||
##Installation
|
||||
|
||||
#### Install backward.hpp
|
||||
|
||||
Backward is a header only library. So installing Backward is easy, simply drop
|
||||
a copy of `backward.hpp` along with your other source files in your C++ project.
|
||||
You can also use a git submodule or really any other way that best fits your
|
||||
environment, as long as you can include `backward.hpp`.
|
||||
|
||||
#### Install backward.cpp
|
||||
|
||||
If you want Backward to automatically print a stack trace on most common fatal
|
||||
errors (segfault, abort, un-handled exception...), simply add a copy of
|
||||
`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.
|
||||
|
||||
##Configuration & Dependencies
|
||||
|
||||
### Integration with CMake
|
||||
|
||||
If you are using CMake and want to use its configuration abilities to save
|
||||
you the trouble, you can easily integrate Backward, depending on how you obtained
|
||||
the library.
|
||||
|
||||
#### As a subdirectory:
|
||||
|
||||
In this case you have a subdirectory containing the whole repository of Backward
|
||||
(eg.: using git-submodules), in this case you can do:
|
||||
|
||||
```
|
||||
add_subdirectory(/path/to/backward-cpp)
|
||||
|
||||
# This will add backward.cpp to your target
|
||||
add_executable(mytarget mysource.cpp ${BACKWARD_ENABLE})
|
||||
|
||||
# This will add libraries, definitions and include directories needed by backward
|
||||
# by setting each property on the target.
|
||||
add_backward(mytarget)
|
||||
```
|
||||
|
||||
#### Modifying CMAKE_MODULE_PATH
|
||||
|
||||
In this case you can have Backward installed as a subdirectory:
|
||||
|
||||
```
|
||||
list(APPEND CMAKE_MODULE_PATH /path/to/backward-cpp)
|
||||
find_package(Backward)
|
||||
|
||||
# This will add libraries, definitions and include directories needed by backward
|
||||
# through an IMPORTED target.
|
||||
target_link_libraries(mytarget PUBLIC Backward::Backward)
|
||||
```
|
||||
|
||||
Notice that this is equivalent to using the the approach that uses `add_subdirectory()`,
|
||||
however it uses cmake's [imported target](https://cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets) mechanism.
|
||||
|
||||
#### Installation through a regular package manager
|
||||
|
||||
In this case you have obtained Backward through a package manager.
|
||||
|
||||
Packages currently available:
|
||||
- [conda-forge](https://anaconda.org/conda-forge/backward-cpp)
|
||||
|
||||
```
|
||||
find_package(Backward)
|
||||
|
||||
# This will add libraries, definitions and include directories needed by backward
|
||||
# through an IMPORTED target.
|
||||
target_link_libraries(mytarget PUBLIC Backward::Backward)
|
||||
```
|
||||
|
||||
### Compile with debug info
|
||||
|
||||
You need to compile your project with generation of debug symbols enabled,
|
||||
usually `-g` with clang++ and g++.
|
||||
|
||||
Note that you can use `-g` with any level of optimization, with modern debug
|
||||
information encoding like DWARF, it only takes space in the binary (it's not
|
||||
loaded in memory until your debugger or Backward makes use of it, don't worry),
|
||||
and it doesn't impact the code generation (at least on GNU/Linux x86\_64 for
|
||||
what I know).
|
||||
|
||||
If you are missing debug information, the stack trace will lack details about
|
||||
your sources.
|
||||
|
||||
### 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 :)**
|
||||
|
||||
Also, by default you will get a really basic stack trace, based on the
|
||||
`backtrace_symbols` API:
|
||||
|
||||

|
||||
|
||||
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
|
||||
easiest for you to install, so pick your poison:
|
||||
|
||||
#### libbfd from the [GNU/binutils](http://www.gnu.org/software/binutils/)
|
||||
|
||||
apt-get install binutils-dev (or equivalent)
|
||||
|
||||
And do not forget to link with the lib: `g++/clang++ -lbfd ...`
|
||||
|
||||
Then define the following before every inclusion of `backward.hpp` (don't
|
||||
forget to update `backward.cpp` as well):
|
||||
|
||||
#define BACKWARD_HAS_BFD 1
|
||||
|
||||
#### libdw from the [elfutils](https://fedorahosted.org/elfutils/)
|
||||
|
||||
apt-get install libdw-dev (or equivalent)
|
||||
|
||||
And do not forget to link with the lib and inform Backward to use it:
|
||||
|
||||
#define BACKWARD_HAS_DW 1
|
||||
|
||||
Of course you can simply add the define (`-DBACKWARD_HAS_...=1`) and the
|
||||
linkage details in your build system and even auto-detect which library is
|
||||
installed, it's up to you.
|
||||
|
||||
That'ss it, you are all set, you should be getting nice stack traces like the
|
||||
one at the beginning of this document.
|
||||
|
||||
## API
|
||||
|
||||
If you don't want to limit yourself to the defaults offered by `backward.cpp`,
|
||||
and you want to take some random stack traces for whatever reason and pretty
|
||||
print them the way you love or you decide to send them all to your buddies over
|
||||
the Internet, you will appreciate the simplicity of Backward's API.
|
||||
|
||||
### Stacktrace
|
||||
|
||||
The StackTrace class lets you take a "snapshot" of the current stack.
|
||||
You can use it like this:
|
||||
|
||||
```c++
|
||||
using namespace backward;
|
||||
StackTrace st; st.load_here(32);
|
||||
Printer p; p.print(st);
|
||||
```
|
||||
|
||||
The public methods are:
|
||||
|
||||
```c++
|
||||
class StackTrace { public:
|
||||
// Take a snapshot of the current stack, with at most "trace_cnt_max"
|
||||
// traces in it. The first trace is the most recent (ie the current
|
||||
// frame). You can also provide a trace address to load_from() assuming
|
||||
// the address is a valid stack frame (useful for signal handling traces).
|
||||
// Both function return size().
|
||||
size_t load_here(size_t trace_cnt_max)
|
||||
size_t load_from(void* address, size_t trace_cnt_max)
|
||||
|
||||
// The number of traces loaded. This can be less than "trace_cnt_max".
|
||||
size_t size() const
|
||||
|
||||
// A unique id for the thread in which the trace was taken. The value
|
||||
// 0 means the stack trace comes from the main thread.
|
||||
size_t thread_id() const
|
||||
|
||||
// Retrieve a trace by index. 0 is the most recent trace, size()-1 is
|
||||
// the oldest one.
|
||||
Trace operator[](size_t trace_idx)
|
||||
};
|
||||
```
|
||||
|
||||
### TraceResolver
|
||||
|
||||
The `TraceResolver` does the heavy lifting, and intends to transform a simple
|
||||
`Trace` from its address into a fully detailed `ResolvedTrace` with the
|
||||
filename of the source, line numbers, inlined functions and so on.
|
||||
|
||||
You can use it like this:
|
||||
|
||||
```c++
|
||||
using namespace backward;
|
||||
StackTrace st; st.load_here(32);
|
||||
|
||||
TraceResolver tr; tr.load_stacktrace(st);
|
||||
for (size_t i = 0; i < st.size(); ++i) {
|
||||
ResolvedTrace trace = tr.resolve(st[i]);
|
||||
std::cout << "#" << i
|
||||
<< " " << trace.object_filename
|
||||
<< " " << trace.object_function
|
||||
<< " [" << trace.addr << "]"
|
||||
<< std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
The public methods are:
|
||||
|
||||
```c++
|
||||
class TraceResolver { public:
|
||||
// Pre-load whatever is necessary from the stack trace.
|
||||
template <class ST>
|
||||
void load_stacktrace(ST&)
|
||||
|
||||
// Resolve a trace. It takes a ResolvedTrace, because a `Trace` is
|
||||
// implicitly convertible to it.
|
||||
ResolvedTrace resolve(ResolvedTrace t)
|
||||
};
|
||||
```
|
||||
|
||||
### SnippetFactory
|
||||
|
||||
The SnippetFactory is a simple helper class to automatically load and cache
|
||||
source files in order to extract code snippets.
|
||||
|
||||
```c++
|
||||
class SnippetFactory { public:
|
||||
// A snippet is a list of line numbers and line contents.
|
||||
typedef std::vector<std::pair<size_t, std::string> > lines_t;
|
||||
|
||||
// Return a snippet starting at line_start with up to context_size lines.
|
||||
lines_t get_snippet(const std::string& filename,
|
||||
size_t line_start, size_t context_size)
|
||||
|
||||
// Return a combined snippet from two different locations and combine them.
|
||||
// context_size / 2 lines will be extracted from each location.
|
||||
lines_t get_combined_snippet(
|
||||
const std::string& filename_a, size_t line_a,
|
||||
const std::string& filename_b, size_t line_b,
|
||||
size_t context_size)
|
||||
|
||||
// Tries to return a unified snippet if the two locations from the same
|
||||
// file are close enough to fit inside one context_size, else returns
|
||||
// the equivalent of get_combined_snippet().
|
||||
lines_t get_coalesced_snippet(const std::string& filename,
|
||||
size_t line_a, size_t line_b, size_t context_size)
|
||||
```
|
||||
|
||||
### Printer
|
||||
|
||||
A simpler way to pretty print a stack trace to the terminal. It will
|
||||
automatically resolve the traces for you:
|
||||
|
||||
```c++
|
||||
using namespace backward;
|
||||
StackTrace st; st.load_here(32);
|
||||
Printer p;
|
||||
p.object = true;
|
||||
p.color = false;
|
||||
p.address = true;
|
||||
p.print(st, stderr);
|
||||
```
|
||||
|
||||
You can set a few options:
|
||||
|
||||
```c++
|
||||
class Printer { public:
|
||||
// Print a little snippet of code if possible.
|
||||
bool snippet = true;
|
||||
|
||||
// Colorize the trace (only set a color when printing on a terminal)
|
||||
bool color = true;
|
||||
|
||||
// Add the addresses of every source location to the trace.
|
||||
bool address = false;
|
||||
|
||||
// Even if there is a source location, prints the object the trace comes
|
||||
// from as well.
|
||||
bool object = false;
|
||||
|
||||
// Resolve and print a stack trace. It takes a C FILE* object, only because
|
||||
// it is possible to access the underalying OS-level file descriptor, which
|
||||
// is then used to determine if the output is a terminal to print in color.
|
||||
template <typename StackTrace>
|
||||
FILE* print(StackTrace& st, FILE* os = stderr)
|
||||
```
|
||||
|
||||
|
||||
### SignalHandling
|
||||
|
||||
A simple helper class that registers for you the most common signals and other
|
||||
callbacks to segfault, hardware exception, un-handled exception etc.
|
||||
|
||||
`backward.cpp` simply uses it like that:
|
||||
|
||||
```c++
|
||||
backward::SignalHandling sh;
|
||||
```
|
||||
|
||||
Creating the object registers all the different signals and hooks. Destroying
|
||||
this object doesn't do anything. It exposes only one method:
|
||||
|
||||
```c++
|
||||
bool loaded() const // true if loaded with success
|
||||
```
|
||||
|
||||
### Trace object
|
||||
|
||||
To keep the memory footprint of a loaded `StackTrace` on the low-side, there a
|
||||
hierarchy of trace object, from a minimal `Trace `to a `ResolvedTrace`.
|
||||
|
||||
#### Simple trace
|
||||
|
||||
```c++
|
||||
struct Trace {
|
||||
void* addr; // address of the trace
|
||||
size_t idx; // its index (0 == most recent)
|
||||
};
|
||||
```
|
||||
|
||||
#### Resolved trace
|
||||
|
||||
A `ResolvedTrace` should contains a maximum of details about the location of
|
||||
the trace in the source code. Note that not all fields might be set.
|
||||
|
||||
```c++
|
||||
struct ResolvedTrace: public Trace {
|
||||
|
||||
struct SourceLoc {
|
||||
std::string function;
|
||||
std::string filename;
|
||||
size_t line;
|
||||
size_t col;
|
||||
};
|
||||
|
||||
// In which binary object this trace is located.
|
||||
std::string object_filename;
|
||||
|
||||
// The function in the object that contains the trace. This is not the same
|
||||
// as source.function which can be an function inlined in object_function.
|
||||
std::string object_function;
|
||||
|
||||
// The source location of this trace. It is possible for filename to be
|
||||
// empty and for line/col to be invalid (value 0) if this information
|
||||
// couldn't be deduced, for example if there is no debug information in the
|
||||
// binary object.
|
||||
SourceLoc source;
|
||||
|
||||
// An optional list of "inliners". All of these sources locations where
|
||||
// inlined in the source location of the trace (the attribute right above).
|
||||
// This is especially useful when you compile with optimizations turned on.
|
||||
typedef std::vector<SourceLoc> source_locs_t;
|
||||
source_locs_t inliners;
|
||||
};
|
||||
```
|
||||
|
||||
## Contact and copyright
|
||||
|
||||
François-Xavier Bourlet <bombela@gmail.com>
|
||||
|
||||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
MIT License.
|
||||
|
||||
### Disclaimer
|
||||
|
||||
Although this project is owned by Google Inc. this is not a Google supported or
|
||||
affiliated project.
|
||||
32
external/backtrace-cpp/backward.cpp
vendored
Normal file
32
external/backtrace-cpp/backward.cpp
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Pick your poison.
|
||||
//
|
||||
// On GNU/Linux, you have few choices to get the most out of your stack trace.
|
||||
//
|
||||
// By default you get:
|
||||
// - object filename
|
||||
// - function name
|
||||
//
|
||||
// In order to add:
|
||||
// - source filename
|
||||
// - 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
|
||||
// better, add the detection of the lib and the macro definition in your build
|
||||
// system)
|
||||
|
||||
// - apt-get install libdw-dev ...
|
||||
// - g++/clang++ -ldw ...
|
||||
// #define BACKWARD_HAS_DW 1
|
||||
|
||||
// - apt-get install binutils-dev ...
|
||||
// - g++/clang++ -lbfd ...
|
||||
// #define BACKWARD_HAS_BFD 1
|
||||
|
||||
#include "backward.hpp"
|
||||
|
||||
namespace backward {
|
||||
|
||||
backward::SignalHandling sh;
|
||||
|
||||
} // namespace backward
|
||||
1997
external/backtrace-cpp/backward.hpp
vendored
Normal file
1997
external/backtrace-cpp/backward.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
77
external/backtrace-cpp/builds.sh
vendored
Executable file
77
external/backtrace-cpp/builds.sh
vendored
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
|
||||
COMPILERS_CXX98=`cat<<EOF
|
||||
gcc-4.4
|
||||
gcc-4.6
|
||||
gcc-4.7
|
||||
gcc-4.8
|
||||
clang
|
||||
EOF`
|
||||
|
||||
COMPILERS_CXX11=`cat<<EOF
|
||||
gcc-4.7
|
||||
gcc-4.8
|
||||
clang
|
||||
EOF`
|
||||
|
||||
|
||||
function mkbuild() {
|
||||
local compiler=$1
|
||||
local lang=$2
|
||||
local buildtype=$3
|
||||
local builddir="$4"
|
||||
export CC=$compiler
|
||||
export CXX=`echo $compiler | sed -e 's/clang/clang++/' -e 's/gcc/g++/'`
|
||||
export CXXFLAGS="-std=$lang"
|
||||
echo "Creating $builddir"
|
||||
mkdir $builddir 2>/dev/null
|
||||
(
|
||||
cd "$builddir"
|
||||
cmake -DCMAKE_BUILD_TYPE=$buildtype ..
|
||||
)
|
||||
}
|
||||
|
||||
function build() {
|
||||
local builddir=$1
|
||||
shift
|
||||
make -C "$builddir" $@
|
||||
}
|
||||
|
||||
function dotest() {
|
||||
local builddir=$1
|
||||
shift
|
||||
make -C "$builddir" test $@
|
||||
return 0
|
||||
}
|
||||
|
||||
function do_action() {
|
||||
local lang=$1
|
||||
local action=$2
|
||||
shift 2
|
||||
|
||||
for compiler in $COMPILERS; do
|
||||
local builddir="build_${lang}_${compiler}"
|
||||
|
||||
if [[ $action == "cmake" ]]; then
|
||||
buildtype=$1
|
||||
mkbuild $compiler $lang "$buildtype" "$builddir"
|
||||
[[ $? != 0 ]] && exit
|
||||
elif [[ $action == "make" ]]; then
|
||||
build "$builddir" $@
|
||||
[[ $? != 0 ]] && exit
|
||||
elif [[ $action == "test" ]]; then
|
||||
dotest "$builddir" $@
|
||||
[[ $? != 0 ]] && exit
|
||||
elif [[ $action == "clean" ]]; then
|
||||
rm -r "$builddir"
|
||||
else
|
||||
echo "usage: $0 cmake [debug|release|relwithdbg]|make|test|clean"
|
||||
exit 255
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
COMPILERS=$COMPILERS_CXX98
|
||||
do_action c++98 $@
|
||||
COMPILERS=$COMPILERS_CXX11
|
||||
do_action c++11 $@
|
||||
57
external/backtrace-cpp/conanfile.py
vendored
Normal file
57
external/backtrace-cpp/conanfile.py
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from conans import ConanFile, CMake
|
||||
import os
|
||||
|
||||
class BackwardCpp(ConanFile):
|
||||
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||
name = 'backward'
|
||||
url = 'https:77github.com/Manu343726/backward-cpp'
|
||||
license = 'MIT'
|
||||
version = '0.0.0'
|
||||
options = {
|
||||
'stack_walking_unwind': [True, False],
|
||||
'stack_walking_backtrace': [True, False],
|
||||
'stack_details_auto_detect': [True, False],
|
||||
'stack_details_backtrace_symbol': [True, False],
|
||||
'stack_details_dw': [True, False],
|
||||
'stack_details_bfd': [True, False],
|
||||
'shared': [True, False]
|
||||
}
|
||||
default_options = (
|
||||
'stack_walking_unwind=True',
|
||||
'stack_walking_backtrace=False',
|
||||
'stack_details_auto_detect=True',
|
||||
'stack_details_backtrace_symbol=False',
|
||||
'stack_details_dw=False',
|
||||
'stack_details_bfd=False',
|
||||
'shared=False'
|
||||
)
|
||||
exports = 'backward.cpp', 'backward.hpp', 'test/*', 'CMakeLists.txt', 'BackwardConfig.cmake'
|
||||
generators = 'cmake'
|
||||
|
||||
def cmake_option(self, option, prefix = ''):
|
||||
return '-D{}{}={}'.format(prefix, option.upper(), self.options[option])
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self.settings)
|
||||
|
||||
options = ''
|
||||
options += self.cmake_option('stack_walking_unwind')
|
||||
options += self.cmake_option('stack_walking_backtrace')
|
||||
options += self.cmake_option('stack_details_auto_detect')
|
||||
options += self.cmake_option('stack_details_backtrace_symbol')
|
||||
options += self.cmake_option('stack_details_dw')
|
||||
options += self.cmake_option('stack_details_bfd')
|
||||
options += self.cmake_option('shared', prefix = 'BACKWARD_')
|
||||
|
||||
self.run('cmake {} {} {} -DBACKWARD_TESTS=OFF'.format(self.conanfile_directory, cmake.command_line, options))
|
||||
self.run('cmake --build . {}'.format(cmake.build_config))
|
||||
|
||||
def package(self):
|
||||
self.copy('backward.hpp', os.path.join('include', 'backward'))
|
||||
self.copy('*.a', dst='lib')
|
||||
self.copy('*.so', dst='lib')
|
||||
self.copy('*.lib', dst='lib')
|
||||
self.copy('*.dll', dst='lib')
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libs = ['backward']
|
||||
BIN
external/backtrace-cpp/doc/nice.png
vendored
Normal file
BIN
external/backtrace-cpp/doc/nice.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
BIN
external/backtrace-cpp/doc/pretty.png
vendored
Normal file
BIN
external/backtrace-cpp/doc/pretty.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
BIN
external/backtrace-cpp/doc/rude.png
vendored
Normal file
BIN
external/backtrace-cpp/doc/rude.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6 KiB |
121
external/backtrace-cpp/test/_test_main.cpp
vendored
Normal file
121
external/backtrace-cpp/test/_test_main.cpp
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* _test_main.cpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "test.hpp"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <error.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
test::test_registry_t test::test_registry;
|
||||
using namespace test;
|
||||
|
||||
bool run_test(TestBase& test) {
|
||||
printf("-- running test case: %s\n", test.name);
|
||||
|
||||
fflush(stdout);
|
||||
pid_t child_pid = fork();
|
||||
if (child_pid == 0) {
|
||||
exit(static_cast<int>(test.run()));
|
||||
}
|
||||
if (child_pid == -1) {
|
||||
error(EXIT_FAILURE, 0, "unable to fork");
|
||||
}
|
||||
|
||||
int child_status = 0;
|
||||
waitpid(child_pid, &child_status, 0);
|
||||
|
||||
test::TestStatus status;
|
||||
|
||||
if (WIFEXITED(child_status)) {
|
||||
int exit_status = WEXITSTATUS(child_status);
|
||||
if (exit_status & ~test::STATUS_MASK) {
|
||||
status = test::FAILED;
|
||||
} else {
|
||||
status = static_cast<test::TestStatus>(exit_status);
|
||||
}
|
||||
} else if (WIFSIGNALED(child_status)) {
|
||||
const int signum = WTERMSIG(child_status);
|
||||
printf("!! signal (%d) %s\n", signum, strsignal(signum));
|
||||
switch (signum) {
|
||||
case SIGABRT:
|
||||
status = test::SIGNAL_ABORT; break;
|
||||
case SIGSEGV:
|
||||
case SIGBUS:
|
||||
status = test::SIGNAL_SEGFAULT; break;
|
||||
case SIGFPE:
|
||||
status = test::SIGNAL_DIVZERO; break;
|
||||
default:
|
||||
status = test::SIGNAL_UNCAUGHT;
|
||||
}
|
||||
} else {
|
||||
status = test::SUCCESS;
|
||||
}
|
||||
|
||||
if (test.expected_status == test::FAILED) {
|
||||
return (status & test::FAILED);
|
||||
}
|
||||
|
||||
if (test.expected_status == test::SIGNAL_UNCAUGHT) {
|
||||
return (status & test::SIGNAL_UNCAUGHT);
|
||||
}
|
||||
|
||||
return status == test.expected_status;
|
||||
}
|
||||
|
||||
int main(int argc, const char* const argv[]) {
|
||||
|
||||
size_t success_cnt = 0;
|
||||
size_t total_cnt = 0;
|
||||
for (test_registry_t::iterator it = test_registry.begin();
|
||||
it != test_registry.end(); ++it) {
|
||||
TestBase& test = **it;
|
||||
|
||||
bool consider_test = (argc <= 1);
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (strcasecmp(argv[i], test.name) == 0) {
|
||||
consider_test = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not consider_test) {
|
||||
continue;
|
||||
}
|
||||
|
||||
total_cnt += 1;
|
||||
if (run_test(test)) {
|
||||
printf("-- test case success: %s\n", test.name);
|
||||
success_cnt += 1;
|
||||
} else {
|
||||
printf("** test case FAILED : %s\n", test.name);
|
||||
}
|
||||
}
|
||||
printf("-- tests passing: %lu/%lu", success_cnt, total_cnt);
|
||||
if (total_cnt) {
|
||||
printf(" (%lu%%)\n", success_cnt * 100 / total_cnt);
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
return (success_cnt == total_cnt) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
99
external/backtrace-cpp/test/rectrace.cpp
vendored
Normal file
99
external/backtrace-cpp/test/rectrace.cpp
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* test/rectrace.cpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "backward.hpp"
|
||||
#include <stdio.h>
|
||||
#include "test/test.hpp"
|
||||
|
||||
using namespace backward;
|
||||
|
||||
typedef StackTrace stacktrace_t;
|
||||
|
||||
void end_of_our_journey(stacktrace_t& st) {
|
||||
if (not st.size()) {
|
||||
st.load_here();
|
||||
}
|
||||
}
|
||||
|
||||
int rec(stacktrace_t& st, int level) {
|
||||
if (level <= 1) {
|
||||
end_of_our_journey(st);
|
||||
return 0;
|
||||
}
|
||||
return rec(st, level - 1);
|
||||
}
|
||||
|
||||
namespace toto {
|
||||
|
||||
namespace titi {
|
||||
|
||||
struct foo {
|
||||
|
||||
union bar {
|
||||
__attribute__((noinline))
|
||||
static int trampoline(stacktrace_t& st, int level) {
|
||||
return rec(st, level);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace titi
|
||||
|
||||
} // namespace toto
|
||||
|
||||
TEST (recursion) {
|
||||
{ // lexical scope.
|
||||
stacktrace_t st;
|
||||
const int input = 3;
|
||||
int r = toto::titi::foo::bar::trampoline(st, input);
|
||||
|
||||
std::cout << "rec(" << input << ") == " << r << std::endl;
|
||||
|
||||
Printer printer;
|
||||
// printer.address = true;
|
||||
printer.object = true;
|
||||
printer.print(st, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int fib(StackTrace& st, int level) {
|
||||
if (level == 2) {
|
||||
return 1;
|
||||
}
|
||||
if (level <= 1) {
|
||||
end_of_our_journey(st);
|
||||
return 0;
|
||||
}
|
||||
return fib(st, level - 1) + fib(st, level - 2);
|
||||
}
|
||||
|
||||
TEST (fibrecursive) {
|
||||
StackTrace st;
|
||||
const int input = 6;
|
||||
int r = fib(st, input);
|
||||
|
||||
std::cout << "fib(" << input << ") == " << r << std::endl;
|
||||
|
||||
Printer printer;
|
||||
printer.print(st, stdout);
|
||||
}
|
||||
50
external/backtrace-cpp/test/select_signals.cpp
vendored
Normal file
50
external/backtrace-cpp/test/select_signals.cpp
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* test/segfault.cpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "backward.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "test/test.hpp"
|
||||
|
||||
using namespace backward;
|
||||
|
||||
void badass_function() {
|
||||
char* ptr = (char*)42;
|
||||
*ptr = 42;
|
||||
}
|
||||
|
||||
TEST_SEGFAULT (pprint_sigsev) {
|
||||
std::vector<int> signals;
|
||||
signals.push_back(SIGSEGV);
|
||||
SignalHandling sh(signals);
|
||||
std::cout << std::boolalpha << "sh.loaded() == " << sh.loaded() << std::endl;
|
||||
badass_function();
|
||||
}
|
||||
|
||||
TEST_SEGFAULT (wont_pprint) {
|
||||
std::vector<int> signals;
|
||||
signals.push_back(SIGABRT);
|
||||
SignalHandling sh(signals);
|
||||
std::cout << std::boolalpha << "sh.loaded() == " << sh.loaded() << std::endl;
|
||||
badass_function();
|
||||
}
|
||||
65
external/backtrace-cpp/test/stacktrace.cpp
vendored
Normal file
65
external/backtrace-cpp/test/stacktrace.cpp
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* test/stacktrace.cpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "backward.hpp"
|
||||
#include <cstdio>
|
||||
#include "test/test.hpp"
|
||||
|
||||
using namespace backward;
|
||||
|
||||
void collect_trace(StackTrace& st) {
|
||||
st.load_here();
|
||||
}
|
||||
|
||||
TEST (minitrace) {
|
||||
StackTrace st;
|
||||
collect_trace(st);
|
||||
|
||||
Printer printer;
|
||||
printer.print(st, stdout);
|
||||
}
|
||||
|
||||
void d(StackTrace& st) {
|
||||
st.load_here();
|
||||
}
|
||||
|
||||
void c(StackTrace& st) {
|
||||
return d(st);
|
||||
}
|
||||
|
||||
void b(StackTrace& st) {
|
||||
return c(st);
|
||||
}
|
||||
|
||||
__attribute__ ((noinline))
|
||||
void a(StackTrace& st) {
|
||||
return b(st);
|
||||
}
|
||||
|
||||
TEST (smalltrace) {
|
||||
StackTrace st;
|
||||
a(st);
|
||||
|
||||
Printer printer;
|
||||
printer.print(st, stdout);
|
||||
}
|
||||
93
external/backtrace-cpp/test/suicide.cpp
vendored
Normal file
93
external/backtrace-cpp/test/suicide.cpp
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* test/suicide.cpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "backward.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <sys/resource.h>
|
||||
#include "test/test.hpp"
|
||||
|
||||
using namespace backward;
|
||||
|
||||
void badass_function()
|
||||
{
|
||||
char* ptr = (char*)42;
|
||||
*ptr = 42;
|
||||
}
|
||||
|
||||
TEST_SEGFAULT (invalid_write)
|
||||
{
|
||||
badass_function();
|
||||
}
|
||||
|
||||
int you_shall_not_pass()
|
||||
{
|
||||
char* ptr = (char*)42;
|
||||
int v = *ptr;
|
||||
return v;
|
||||
}
|
||||
|
||||
TEST_SEGFAULT(invalid_read)
|
||||
{
|
||||
int v = you_shall_not_pass();
|
||||
std::cout << "v=" << v << std::endl;
|
||||
}
|
||||
|
||||
void abort_abort_I_repeat_abort_abort()
|
||||
{
|
||||
std::cout << "Jumping off the boat!" << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
TEST_ABORT (calling_abort)
|
||||
{
|
||||
abort_abort_I_repeat_abort_abort();
|
||||
}
|
||||
|
||||
volatile int zero = 0;
|
||||
|
||||
int divide_by_zero()
|
||||
{
|
||||
std::cout << "And the wild black hole appears..." << std::endl;
|
||||
int v = 42 / zero;
|
||||
return v;
|
||||
}
|
||||
|
||||
TEST_DIVZERO (divide_by_zero)
|
||||
{
|
||||
int v = divide_by_zero();
|
||||
std::cout << "v=" << v << std::endl;
|
||||
}
|
||||
|
||||
int bye_bye_stack(int i) {
|
||||
return bye_bye_stack(i + 1) + bye_bye_stack(i * 2);
|
||||
}
|
||||
|
||||
TEST_SEGFAULT(stackoverflow)
|
||||
{
|
||||
struct rlimit limit;
|
||||
limit.rlim_max = 8096;
|
||||
setrlimit(RLIMIT_STACK, &limit);
|
||||
int r = bye_bye_stack(42);
|
||||
std::cout << "r=" << r << std::endl;
|
||||
}
|
||||
75
external/backtrace-cpp/test/test.cpp
vendored
Normal file
75
external/backtrace-cpp/test/test.cpp
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* test/test.cpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
#include "test/test.hpp"
|
||||
|
||||
TEST (empty_test) { }
|
||||
|
||||
TEST_FAIL_ASSERT (fail_assert) {
|
||||
ASSERT(1 == 2);
|
||||
}
|
||||
|
||||
TEST_FAIL_ASSERT (fail_assert_ge) {
|
||||
ASSERT_GE(4, 5);
|
||||
}
|
||||
|
||||
TEST_UNCAUGHT_EXCEPTION (uncaught_exception) {
|
||||
throw std::runtime_error("some random runtime error");
|
||||
}
|
||||
|
||||
TEST_UNCAUGHT_EXCEPTION (uncaught_exception_int) {
|
||||
throw 42;
|
||||
}
|
||||
|
||||
TEST_SEGFAULT (segfault) {
|
||||
char* a = 0;
|
||||
char b = a[42];
|
||||
std::cout << "result: " << b << std::endl;
|
||||
}
|
||||
|
||||
TEST_ABORT (abort) {
|
||||
abort();
|
||||
}
|
||||
|
||||
TEST (catch_int) {
|
||||
ASSERT_THROW({throw 42;}, int);
|
||||
}
|
||||
|
||||
TEST_FAIL_ASSERT (fail_catch_int) {
|
||||
ASSERT_THROW({}, int);
|
||||
}
|
||||
|
||||
TEST_FAIL_ASSERT (fail_no_throw) {
|
||||
ASSERT_NO_THROW({throw 42;});
|
||||
}
|
||||
|
||||
TEST (any_throw) {
|
||||
ASSERT_ANY_THROW({throw 42;});
|
||||
}
|
||||
|
||||
TEST_FAIL_ASSERT (fail_any_throw) {
|
||||
ASSERT_ANY_THROW({});
|
||||
}
|
||||
170
external/backtrace-cpp/test/test.hpp
vendored
Normal file
170
external/backtrace-cpp/test/test.hpp
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* test/test.hpp
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef H_54E531F7_9154_454B_BEB9_257408429470
|
||||
#define H_54E531F7_9154_454B_BEB9_257408429470
|
||||
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace test {
|
||||
|
||||
struct AssertFailedError: std::exception {
|
||||
~AssertFailedError() throw() {}
|
||||
|
||||
AssertFailedError(const char* filename, int line, const char* errmsg):
|
||||
basename(_basename(filename)), line(line), errmsg(errmsg) {}
|
||||
|
||||
const char* what() const throw() {
|
||||
if (not _what.size()) {
|
||||
std::ostringstream ss;
|
||||
ss << "assertion failed (" << basename << ":" << line;
|
||||
ss << ") " << errmsg;
|
||||
_what = ss.str();
|
||||
}
|
||||
return _what.c_str();
|
||||
}
|
||||
|
||||
const char* basename;
|
||||
int line;
|
||||
const char* errmsg;
|
||||
|
||||
mutable std::string _what;
|
||||
|
||||
static const char* _basename(const char* filename) {
|
||||
const char* basename = filename + strlen(filename);
|
||||
while (basename != filename && *basename != '/') {
|
||||
basename -= 1;
|
||||
}
|
||||
return basename + 1;
|
||||
}
|
||||
};
|
||||
|
||||
enum TestStatus {
|
||||
SUCCESS = 0<<0,
|
||||
FAILED = 1<<0,
|
||||
|
||||
ASSERT_FAIL = FAILED | 1<<1,
|
||||
EXCEPTION_UNCAUGHT = FAILED | 2<<1,
|
||||
SIGNAL_UNCAUGHT = FAILED | 3<<1,
|
||||
SIGNAL_SEGFAULT = SIGNAL_UNCAUGHT | 1<<3,
|
||||
SIGNAL_ABORT = SIGNAL_UNCAUGHT | 2<<3,
|
||||
SIGNAL_DIVZERO = SIGNAL_UNCAUGHT | 2<<3,
|
||||
|
||||
STATUS_MASK = 0x1F
|
||||
};
|
||||
|
||||
struct TestBase {
|
||||
const char* name;
|
||||
TestStatus expected_status;
|
||||
|
||||
virtual ~TestBase() {}
|
||||
TestBase(const char*, TestStatus);
|
||||
virtual void do_test() = 0;
|
||||
|
||||
TestStatus run() {
|
||||
try {
|
||||
do_test();
|
||||
return SUCCESS;
|
||||
} catch(const AssertFailedError& e) {
|
||||
printf("!! %s\n", e.what());
|
||||
return ASSERT_FAIL;
|
||||
} catch(const std::exception& e) {
|
||||
printf("!! exception: %s\n", e.what());
|
||||
return EXCEPTION_UNCAUGHT;
|
||||
} catch(...) {
|
||||
printf("!! unknown exception\n");
|
||||
return EXCEPTION_UNCAUGHT;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<TestBase*> test_registry_t;
|
||||
extern test_registry_t test_registry;
|
||||
|
||||
TestBase::TestBase(const char* n, TestStatus s): name(n), expected_status(s) {
|
||||
test_registry.push_back(this);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
#define _TEST_STATUS(name, status) \
|
||||
struct TEST_##name: ::test::TestBase { \
|
||||
TEST_##name(): TestBase(#name, status) {} \
|
||||
void do_test(); \
|
||||
} TEST_##name; \
|
||||
void TEST_##name::do_test()
|
||||
|
||||
#define TEST(name) _TEST_STATUS(name, ::test::SUCCESS)
|
||||
#define TEST_FAIL(name) _TEST_STATUS(name, ::test::FAILED)
|
||||
#define TEST_FAIL_ASSERT(name) _TEST_STATUS(name, ::test::ASSERT_FAIL)
|
||||
#define TEST_UNCAUGHT_EXCEPTION(name) _TEST_STATUS(name, ::test::EXCEPTION_UNCAUGHT)
|
||||
#define TEST_UNCAUGHT_SIGNAL(name) _TEST_STATUS(name, ::test::SIGNAL_UNCAUGHT)
|
||||
#define TEST_SEGFAULT(name) _TEST_STATUS(name, ::test::SIGNAL_SEGFAULT)
|
||||
#define TEST_ABORT(name) _TEST_STATUS(name, ::test::SIGNAL_ABORT)
|
||||
#define TEST_DIVZERO(name) _TEST_STATUS(name, ::test::SIGNAL_DIVZERO)
|
||||
|
||||
#define ASSERT(expr) \
|
||||
(expr) ? static_cast<void>(0) \
|
||||
: throw ::test::AssertFailedError( \
|
||||
__FILE__, __LINE__, #expr)
|
||||
|
||||
#define _ASSERT_BINOP(a, b, cmp) \
|
||||
(not (a cmp b)) ? static_cast<void>(0) \
|
||||
: throw ::test::AssertFailedError( \
|
||||
__FILE__, __LINE__, "because " #a " " #cmp " " #b)
|
||||
|
||||
#define ASSERT_EQ(a, b) _ASSERT_BINOP(a, b, !=)
|
||||
#define ASSERT_NE(a, b) _ASSERT_BINOP(a, b, ==)
|
||||
#define ASSERT_LT(a, b) _ASSERT_BINOP(a, b, >=)
|
||||
#define ASSERT_LE(a, b) _ASSERT_BINOP(a, b, >)
|
||||
#define ASSERT_GT(a, b) _ASSERT_BINOP(a, b, <=)
|
||||
#define ASSERT_GE(a, b) _ASSERT_BINOP(a, b, <)
|
||||
|
||||
#define ASSERT_THROW(expr, e_type) \
|
||||
do { try { expr } \
|
||||
catch (const e_type&) { break; } \
|
||||
throw ::test::AssertFailedError( \
|
||||
__FILE__, __LINE__, "expected exception " #e_type); \
|
||||
} while(0)
|
||||
|
||||
#define ASSERT_ANY_THROW(expr) \
|
||||
do { try { expr } \
|
||||
catch (...) { break; } \
|
||||
throw ::test::AssertFailedError( \
|
||||
__FILE__, __LINE__, "expected any exception"); \
|
||||
} while(0)
|
||||
|
||||
#define ASSERT_NO_THROW(expr) \
|
||||
try { expr } \
|
||||
catch (...) { \
|
||||
throw ::test::AssertFailedError( \
|
||||
__FILE__, __LINE__, "no exception expected"); \
|
||||
}
|
||||
|
||||
#endif /* H_GUARD */
|
||||
11
external/backtrace-cpp/test_package/CMakeLists.txt
vendored
Normal file
11
external/backtrace-cpp/test_package/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
project(backward-package-test)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||
include(${CONAN_CMAKE-UTILS_ROOT}/conan.cmake)
|
||||
conan_basic_setup()
|
||||
|
||||
add_conan_library(backward)
|
||||
|
||||
add_executable(example main.cpp)
|
||||
target_link_libraries(example PRIVATE backward-conan)
|
||||
15
external/backtrace-cpp/test_package/conanfile.py
vendored
Normal file
15
external/backtrace-cpp/test_package/conanfile.py
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from conans import ConanFile, CMake
|
||||
import os
|
||||
|
||||
class TestBackward(ConanFile):
|
||||
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||
requires = 'cmake-utils/0.0.0@Manu343726/testing', 'backward/0.0.0@Manu343726/testing'
|
||||
generators = 'cmake'
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self.settings)
|
||||
self.run('cmake {} {}'.format(self.conanfile_directory, cmake.command_line))
|
||||
self.run('cmake --build . {}'.format(cmake.build_config))
|
||||
|
||||
def test(self):
|
||||
self.run(os.path.join('.', 'bin', 'example'))
|
||||
60
external/backtrace-cpp/test_package/main.cpp
vendored
Normal file
60
external/backtrace-cpp/test_package/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#include <backward/backward.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
using namespace backward;
|
||||
|
||||
class TracedException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
TracedException() :
|
||||
std::runtime_error(_get_trace())
|
||||
{}
|
||||
|
||||
private:
|
||||
std::string _get_trace()
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
StackTrace stackTrace;
|
||||
TraceResolver resolver;
|
||||
stackTrace.load_here();
|
||||
resolver.load_stacktrace(stackTrace);
|
||||
|
||||
for(std::size_t i = 0; i < stackTrace.size(); ++i)
|
||||
{
|
||||
const ResolvedTrace trace = resolver.resolve(stackTrace[i]);
|
||||
|
||||
ss << "#" << i << " at " << trace.object_function << "\n";
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
void f(int i)
|
||||
{
|
||||
if(i >= 42)
|
||||
{
|
||||
throw TracedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "i=" << i << "\n";
|
||||
f(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
f(0);
|
||||
} catch (const TracedException& ex)
|
||||
{
|
||||
std::cout << ex.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -255,9 +255,10 @@ target_link_libraries(anbox-core
|
|||
anbox-protobuf
|
||||
xdg)
|
||||
|
||||
add_executable(anbox main.cpp)
|
||||
add_executable(anbox main.cpp ${BACKWARD_ENABLE})
|
||||
target_link_libraries(anbox
|
||||
anbox-core)
|
||||
add_backward(anbox)
|
||||
|
||||
install(
|
||||
TARGETS anbox
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue