C程序集成Backward-cpp使用示例
原文地址:https://www.cnblogs.com/liqinglucky/p/backward-in-C.html
在文章Backward-cpp: Segmentation fault时打印backtrace中已经介绍了backward-cpp的编译安装。不过项目示例都是C++程序。本文使用C程序做为演示打印Segmentation fault的功能。
一 程序
目录结构
backward# ls
backward-cpp
CMakeLists.txt
main.c
1 main.c
#include<stdio.h>
#include <assert.h>
int func3(void) {
assert(0); //构造Segmentation fault
return 0;
}
int func2(void) { return func3(); }
int func1(void) { return func2(); }
int main(void)
{
func1();
return 0;
}
2 CMakeLists.txt
参考backward-cpp
的README
将backward-cpp
库集成进自己的工程方法有很多,可以选取一种方便集成的方式。列举如下:
方法1: 将backward-cpp
库的cpp和hpp文件拷贝到自己工程中编译
Install backward.cpp
simply add a copy of
backward.cpp
to your project, and don't forget to tell your build system.
project( myapp )
cmake_minimum_required( VERSION 3.1 )
set(CMAKE_CXX_FLAGS "-O0 -g -Wall -ggdb")
# 1 指定源代码
set ( HDR_LIST backward.hpp )
set ( SRC_LIST backward.cpp main.cpp )
# 2 指定执行编译的源代码
add_executable ( ${PROJECT_NAME} ${SRC_LIST} )
# 打印调试
message("project name:" ${PROJECT_NAME})
方法2: 编译时自动去网上下载backward-cpp
库
With
FetchContent()
:If you are using a recent version of CMake, you can integrate
backward
viaFetchContent
project( myapp )
cmake_minimum_required( VERSION 3.1 )
include(FetchContent)
FetchContent_Declare(backward
GIT_REPOSITORY https://github.com/bombela/backward-cpp
GIT_TAG v1.6)
FetchContent_MakeAvailable(backward)
set(CMAKE_CXX_FLAGS " -g -Wall ")
# 1 指定源代码
set ( SRC_LIST main.c )
# 2 指定执行编译的源代码
add_executable ( ${PROJECT_NAME} ${SRC_LIST} ${BACKWARD_ENABLE})
add_backward(${PROJECT_NAME})
# 打印调试
message("project name:" ${PROJECT_NAME})
这种做法不需要自己手动clone backward-cpp
源码。
方法3: 将backward-cpp
库以子目录的方式添加进自己的工程
As a subdirectory:
In this case you have a subdirectory containing the whole repository of Backward
# 项目名称
project( myapp )
cmake_minimum_required( VERSION 3.1 )
# 指定backward-cpp的路径为子目录
add_subdirectory(./backward-cpp)
# define BACKWARD_HAS_DW 1
add_definitions(-DBACKWARD_HAS_DW=1)
# 添加-g参数,显示函数名
set(CMAKE_CXX_FLAGS "-g -Wall")
# 1 指定源代码
set ( SRC_LIST main.c )
# 2 指定执行编译的源代码
add_executable ( ${PROJECT_NAME} ${SRC_LIST} ${BACKWARD_ENABLE})
add_backward(${PROJECT_NAME})
target_link_libraries ( ${PROJECT_NAME} dw )
3 clone backward-cpp
git clone backward-cpp,backward-cpp目录与CMakeLists.txt同级目录。
如果还想对backward-cpp项目中不需要的文件做简化,可以把test文件删除也并不影响。我只保留了以下一个文件。
backward/backward-cpp# ls
BackwardConfig.cmake backward.cpp backward.hpp CMakeLists.txt
二 编译
编译源码
//cmake编译
backward# mkdir build
backward/build# cmake ..
backward/build# make
编译生成
build# ls
myapp <<< 可执行文件
三 运行
作为对比,通常没有添加backward-cpp
时程序异常退出的情况为:
build# ./myapp
myapp: /backward/main.c:5: func3: Assertion `0' failed.
Aborted
编译完成后可以运行可执行文件,看下演示效果:
build# ./myapp
myapp: /backward/main.c:5: func3: Assertion `0' failed.
Stack trace (most recent call last):
#10 Object "", at 0xffffffffffffffff, in
#9 Object "/backward/build/myapp", at 0x56554c12becd, in _start
#8 Source "../csu/libc-start.c", line 308, in __libc_start_main [0x7f1abaf8d082]
#7 Object "/backward/build/myapp", at 0x56554c12bfda, in main
#6 Object "/backward/build/myapp", at 0x56554c12bfcb, in func1
#5 Object "/backward/build/myapp", at 0x56554c12bfbc, in func2
#4 Object "/backward/build/myapp", at 0x56554c12bfaf, in func3
#3 Source "/build/glibc-SzIz7B/glibc-2.31/assert/assert.c", line 101, in __assert_fail [0x7f1abaf9cfd5]
#2 Source "/build/glibc-SzIz7B/glibc-2.31/assert/assert.c", line 92, in __assert_fail_base [0x7f1abaf8b728]
#1 Source "/build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c", line 79, in abort [0x7f1abaf8b858]
#0 Source "../sysdeps/unix/sysv/linux/raise.c", line 51, in raise [0x7f1abafac00b]
Aborted (Signal sent by tkill() 904343 0)
Aborted
这里已经打印出了栈的backtrace。
不过backtrace中没有显示出代码段,我使用c++的main文件就可以直接显示代码段和行号。
总结:将backward-cpp集成进自己的工程,可以方便程序的调试。