debug:win和linux都通过,linx下Release暂时没有有效内容
This commit is contained in:
commit
b4de9d6c1c
17
.clang-format
Normal file
17
.clang-format
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
PointerAlignment: Left
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterFunction: true
|
||||||
|
AfterClass: true
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
ReflowComments: true
|
||||||
|
SpacesBeforeTrailingComments: 3
|
||||||
|
TabWidth: 4
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ColumnLimit: 120
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
45
.gitignore
vendored
Normal file
45
.gitignore
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
.idea
|
||||||
|
cmake-build-*
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
!lebo_motor.lib
|
||||||
|
!lebo_motor.dll
|
||||||
|
!liblebo_motor.so
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
build
|
||||||
|
*.user
|
||||||
|
compile_commands.json
|
||||||
|
.vs
|
||||||
|
out
|
||||||
|
.cache
|
||||||
|
CMakeLists.txt.*
|
103
.vscode/settings.json
vendored
Normal file
103
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"files.autoSave": "onFocusChange",
|
||||||
|
"editor.fontSize": 14,
|
||||||
|
"editor.fontFamily": "'Monaspace Krypton Light', 'Monaspace Krypton Light', 'Monaspace Krypton Light'",
|
||||||
|
"terminal.integrated.fontFamily": "Monaspace Krypton Light",
|
||||||
|
"cmake.configureOnOpen": true,
|
||||||
|
"cmake.debugConfig": {
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "-gdb-set charset utf-8",
|
||||||
|
"text": "-gdb-set charset UTF-8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enable gdb pretty-printing",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
//"visualizerFile": "${workspaceRoot}/.vscode/qt6.natvis",
|
||||||
|
"args": [
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// "cmake.configureSettings": {
|
||||||
|
// "CMAKE_TOOLCHAIN_FILE": "${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
|
||||||
|
// },
|
||||||
|
"cmake.options.statusBarVisibility": "visible",
|
||||||
|
"cmake.generator": "Ninja",
|
||||||
|
"C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json",
|
||||||
|
"C_Cpp.default.cppStandard": "c++17",
|
||||||
|
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||||
|
"editor.inlayHints.enabled": "off",
|
||||||
|
"editor.unicodeHighlight.allowedLocales": {
|
||||||
|
"ja": true,
|
||||||
|
"zh-hant": true,
|
||||||
|
"zh-hans": true
|
||||||
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"ostream": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"ios": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"xfacet": "cpp",
|
||||||
|
"xhash": "cpp",
|
||||||
|
"xiosbase": "cpp",
|
||||||
|
"xlocale": "cpp",
|
||||||
|
"xlocinfo": "cpp",
|
||||||
|
"xlocmon": "cpp",
|
||||||
|
"xlocnum": "cpp",
|
||||||
|
"xloctime": "cpp",
|
||||||
|
"xmemory": "cpp",
|
||||||
|
"xmemory0": "cpp",
|
||||||
|
"xstddef": "cpp",
|
||||||
|
"xstring": "cpp",
|
||||||
|
"xtr1common": "cpp",
|
||||||
|
"xtree": "cpp",
|
||||||
|
"xutility": "cpp",
|
||||||
|
"filesystem": "cpp",
|
||||||
|
"locale": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"xthread": "cpp",
|
||||||
|
"xlocbuf": "cpp",
|
||||||
|
"xlocmes": "cpp"
|
||||||
|
}
|
||||||
|
}
|
19
CMakeLists.txt
Normal file
19
CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(crashelper LANGUAGES CXX)
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
add_compile_options(/source-charset:utf-8)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_DEBUG_POSTFIX "d")
|
||||||
|
message(STATUS "System: ${CMAKE_SYSTEM_NAME}")
|
||||||
|
message(STATUS "Compiler CXX ID: ${CMAKE_CXX_COMPILER_ID}")
|
||||||
|
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/)
|
||||||
|
|
||||||
|
add_subdirectory(crashelper)
|
||||||
|
add_subdirectory(test)
|
50
README.md
Normal file
50
README.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# crashelper
|
||||||
|
|
||||||
|
## 1. 介绍
|
||||||
|
|
||||||
|
crashelper是一个用于帮助开发人员快速定位crash的辅助工具,`Windows`下暂时仅支持`MSVC`编译器。
|
||||||
|
|
||||||
|
用到了仅头文件项目 `=>` [backward-cpp](https://github.com/bombela/backward-cpp),`crashelper`已包含`backward-cpp`项目中的头文件。
|
||||||
|
|
||||||
|
`crashelper`对`backward-cpp`源码加了部分接口用于配置具体的日志保存路径,不能直接拿原项目头文件`backward.hpp`进行更新替换。
|
||||||
|
|
||||||
|
# 2. 设计思路
|
||||||
|
|
||||||
|
## 2.1. Debug模式
|
||||||
|
|
||||||
|
### 2.1.1 Windows
|
||||||
|
|
||||||
|
在Windows下的此模式,`crashelper`会仅保存崩溃时的调用栈信息,并将日志信息保存到设定的目录下。
|
||||||
|
|
||||||
|
### 2.1.2 Linux
|
||||||
|
|
||||||
|
在Linux下的此模式,`crashelper`会仅保存崩溃时的调用栈信息,并将日志信息保存到设定的目录下。
|
||||||
|
|
||||||
|
`Linux`下依赖`binutils`库。
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install binutils-dev
|
||||||
|
# REHL/CentOS/Fedora
|
||||||
|
sudo yum install binutils-devel
|
||||||
|
# openSUSE/SUSE
|
||||||
|
sudo zypper install binutils-devel
|
||||||
|
# Arch Linux/Manjaro
|
||||||
|
sudo pacman -S binutils-devel/binutils-libs
|
||||||
|
# Alpine
|
||||||
|
sudo apk add binutils-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
二进制的下载链接:[pkgs.org](https://pkgs.org/)
|
||||||
|
|
||||||
|
其中`binutils`部分:
|
||||||
|
|
||||||
|
### 2.1.3 MacOS
|
||||||
|
|
||||||
|
待补充。
|
||||||
|
|
||||||
|
## 2.2. Release模式
|
||||||
|
|
||||||
|
### 2.2.1 Windows
|
||||||
|
|
||||||
|
在Windows下的此模式,程序编译结果会额外产生`pdb`调试符号文件(此为额外的产生,不影响可执行程序的`Release`性,即不会影响代码优化和运行时性能),请妥善保存好此`pdb`文件,用于后续配合`dump`文件分析异常。程序运行时,`crashelper`会保存崩溃时的`dump`文件到设定的目录下。
|
27
crashelper/CMakeLists.txt
Normal file
27
crashelper/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(crashelper LANGUAGES CXX)
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
|
message(FATAL_ERROR "Unsupported MinGW Currently.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CRASHELPER_SOURCES
|
||||||
|
src/crashelper.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(include)
|
||||||
|
add_library(crashelper STATIC ${CRASHELPER_SOURCES})
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
target_link_libraries(crashelper PUBLIC pthread dl bfd)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
target_link_libraries(crashelper PRIVATE DbgHelp)
|
||||||
|
target_compile_options(crashelper PUBLIC $<$<OR:$<STREQUAL:$<CXX_COMPILER_ID>,MSVC>,$<STREQUAL:$<C_COMPILER_ID>,MSVC>>:/Zi>)
|
||||||
|
target_link_options(crashelper PUBLIC $<$<OR:$<STREQUAL:$<CXX_COMPILER_ID>,MSVC>,$<STREQUAL:$<C_COMPILER_ID>,MSVC>>:/DEBUG>)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported OS: ${CMAKE_SYSTEM_NAME}. This project only supports Linux, macOS, and Windows.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(crashelper PUBLIC include)
|
4710
crashelper/include/backward.hpp
Normal file
4710
crashelper/include/backward.hpp
Normal file
File diff suppressed because it is too large
Load Diff
61
crashelper/include/crashelper.h
Normal file
61
crashelper/include/crashelper.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef CRASHELPER_H
|
||||||
|
#define CRASHELPER_H
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#define WIN_OS
|
||||||
|
#include <windows.h>
|
||||||
|
#if defined(min)
|
||||||
|
#undef min
|
||||||
|
#endif
|
||||||
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#define MAC_OS
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#define LINUX_OS
|
||||||
|
#define BACKWARD_HAS_BFD 1
|
||||||
|
#else
|
||||||
|
#error "Unsupported OS"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "backward.hpp"
|
||||||
|
#include <string>
|
||||||
|
#ifdef USE_BOOST
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
#else
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace backward {
|
||||||
|
///
|
||||||
|
/// @brief 设置dump文件的保存目录,不设置默认当前目录。
|
||||||
|
/// @param path 若不存在则创建,创建失败返回false
|
||||||
|
///
|
||||||
|
bool SetDumpFileSavePath(const std::string& path);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief 设置dump日志文件的保存目录,不设置默认当前目录。
|
||||||
|
/// @param path 若不存在则创建,创建失败返回false
|
||||||
|
///
|
||||||
|
bool SetDumpLogSavePath(const std::string& path);
|
||||||
|
|
||||||
|
std::string GetCurFullLogPath();
|
||||||
|
#if defined(WIN_OS)
|
||||||
|
void UseExceptionHandler(EXCEPTION_POINTERS* exception);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace backward
|
||||||
|
|
||||||
|
#ifdef WIN_OS
|
||||||
|
#define CRASHELPER_MARK_ENTRY() \
|
||||||
|
backward::SignalHandling sh; \
|
||||||
|
sh.register_crash_use_handler([](EXCEPTION_POINTERS* exception) { UseExceptionHandler(exception); }); \
|
||||||
|
sh.register_crash_path([]() -> std::string { return GetCurFullLogPath(); })
|
||||||
|
#elif defined(MAC_OS)
|
||||||
|
#elif defined(LINUX_OS)
|
||||||
|
#define CRASHELPER_MARK_ENTRY() \
|
||||||
|
backward::SignalHandling sh; \
|
||||||
|
sh.register_crash_path([]() -> std::string { return GetCurFullLogPath(); })
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CRASHELPER_H
|
178
crashelper/src/crashelper.cxx
Normal file
178
crashelper/src/crashelper.cxx
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
#include "crashelper.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace backward {
|
||||||
|
|
||||||
|
class crashHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static crashHelper& getInstance()
|
||||||
|
{
|
||||||
|
static crashHelper instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool createDir(const std::string& path);
|
||||||
|
static std::string getCurrentTime();
|
||||||
|
static std::string getBinName();
|
||||||
|
static std::string toFull(const std::string& path);
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string dumpSavePath_;
|
||||||
|
std::string dumpLogSavePath_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
crashHelper() = default;
|
||||||
|
~crashHelper() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool crashHelper::createDir(const std::string& path)
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
fs::path dir(path);
|
||||||
|
|
||||||
|
if (fs::exists(dir, ec)) {
|
||||||
|
if (!fs::is_directory(dir, ec)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool created = fs::create_directories(dir, ec);
|
||||||
|
if (ec || !created) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string crashHelper::getCurrentTime()
|
||||||
|
{
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
auto now_time_t = std::chrono::system_clock::to_time_t(now);
|
||||||
|
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||||
|
|
||||||
|
// 转换为本地时间(或 UTC 时间)
|
||||||
|
std::tm now_tm = *std::localtime(&now_time_t); // 本地时间
|
||||||
|
// std::tm now_tm = *std::gmtime(&now_time_t); // UTC 时间
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::put_time(&now_tm, "%Y%m%d-%H%M%S") << "-" << std::setfill('0') << std::setw(3) << now_ms.count();
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string crashHelper::getBinName()
|
||||||
|
{
|
||||||
|
fs::path exe_path;
|
||||||
|
#ifdef WIN_OS
|
||||||
|
char path[MAX_PATH] = {0};
|
||||||
|
GetModuleFileName(nullptr, path, MAX_PATH);
|
||||||
|
exe_path = fs::path(path);
|
||||||
|
#elif defined(MAC_OS)
|
||||||
|
char path[4096];
|
||||||
|
uint32_t size = sizeof(path);
|
||||||
|
if (_NSGetExecutablePath(path, &size) == 0) {
|
||||||
|
exe_path = fs::canonical(fs::path(path));
|
||||||
|
}
|
||||||
|
#elif defined(LINUX_OS)
|
||||||
|
char path[4096];
|
||||||
|
ssize_t count = readlink("/proc/self/exe", path, sizeof(path));
|
||||||
|
if (count != -1) {
|
||||||
|
path[count] = '\0';
|
||||||
|
exe_path = fs::path(path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!exe_path.empty()) {
|
||||||
|
return exe_path.stem().string(); // stem() 移除扩展名
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string crashHelper::toFull(const std::string& path)
|
||||||
|
{
|
||||||
|
fs::path base;
|
||||||
|
if (fs::path(path).is_relative()) {
|
||||||
|
base = fs::current_path();
|
||||||
|
base.append(path);
|
||||||
|
} else {
|
||||||
|
base = fs::path(path);
|
||||||
|
}
|
||||||
|
auto r = fs::absolute(base);
|
||||||
|
return r.string();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetDumpFileSavePath(const std::string& path)
|
||||||
|
{
|
||||||
|
auto& h = crashHelper::getInstance();
|
||||||
|
if (!h.createDir(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
h.dumpSavePath_ = path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetDumpLogSavePath(const std::string& path)
|
||||||
|
{
|
||||||
|
auto& h = crashHelper::getInstance();
|
||||||
|
if (!h.createDir(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
h.dumpLogSavePath_ = path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetCurFullLogPath()
|
||||||
|
{
|
||||||
|
auto gf = []() {
|
||||||
|
auto& h = crashHelper::getInstance();
|
||||||
|
auto dumpName = h.getCurrentTime() + "-" + h.getBinName() + ".log";
|
||||||
|
auto lp = crashHelper::toFull(h.dumpLogSavePath_);
|
||||||
|
auto full = fs::path(lp).append(dumpName).string();
|
||||||
|
return full;
|
||||||
|
};
|
||||||
|
#if defined(WIN_OS)
|
||||||
|
#if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
|
||||||
|
return gf();
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
return gf();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WIN_OS)
|
||||||
|
void UseExceptionHandler(EXCEPTION_POINTERS* exception)
|
||||||
|
{
|
||||||
|
auto& h = crashHelper::getInstance();
|
||||||
|
#if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
|
||||||
|
#else
|
||||||
|
// Release 模式, 输出 dump 结果到文件
|
||||||
|
auto dumpBase = h.getCurrentTime() + "-" + h.getBinName();
|
||||||
|
auto dumpName = h.getCurrentTime() + "-" + h.getBinName() + ".windump";
|
||||||
|
auto dumpFailedLog = h.getCurrentTime() + "-" + h.getBinName() + ".dumpfailed.log";
|
||||||
|
auto lp = crashHelper::toFull(h.dumpSavePath_);
|
||||||
|
auto full = fs::path(lp).append(dumpName).string();
|
||||||
|
auto full_failed = fs::path(lp).append(dumpFailedLog).string();
|
||||||
|
HANDLE hFile = CreateFile(full.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
|
std::ofstream fs(full_failed);
|
||||||
|
fs << "Create dump file failed.\n";
|
||||||
|
fs << "File: " << full << "\n";
|
||||||
|
fs << "Error code: " << GetLastError() << "\n";
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
MINIDUMP_EXCEPTION_INFORMATION info;
|
||||||
|
info.ThreadId = GetCurrentThreadId();
|
||||||
|
info.ExceptionPointers = exception;
|
||||||
|
info.ClientPointers = TRUE;
|
||||||
|
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &info, NULL, NULL);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // namespace backward
|
5
test/CMakeLists.txt
Normal file
5
test/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(crashelper-test LANGUAGES CXX)
|
||||||
|
add_executable(crashelper-test main.cxx)
|
||||||
|
target_link_libraries(crashelper-test crashelper)
|
31
test/main.cxx
Normal file
31
test/main.cxx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include <crashelper.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
using namespace backward;
|
||||||
|
|
||||||
|
void th_sim()
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
// throw "Erro Auto";
|
||||||
|
int* p = nullptr;
|
||||||
|
*p = 33;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetDumpFileSavePath("D:\\dump");
|
||||||
|
SetDumpLogSavePath("D:\\dump");
|
||||||
|
#else
|
||||||
|
SetDumpFileSavePath("~/dump");
|
||||||
|
SetDumpLogSavePath("~/dump");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CRASHELPER_MARK_ENTRY();
|
||||||
|
|
||||||
|
std::thread t(th_sim);
|
||||||
|
std::cout << "Done" << std::endl;
|
||||||
|
t.join();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user