安装addr2line后才能有更详细的信息
直接复制过去用。注意编译选项。
- #pragma once
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- namespace AdsonLib {
- class PrintCoreStack{
- public:
- static void RegisterCoreHandler() {
- struct sigaction sig;
- memset(&sig, 0, sizeof(sig));
- sig.sa_handler = &PrintCoreStack::CoreHandler;
- sig.sa_flags |= SA_RESETHAND; //one-time only
- sigaction(SIGSEGV, &sig, NULL);
- std::set_terminate([](){
- PrintStack();
- std::abort();
- });
- }
- private:
- static std::string RunCmd(const std::string &cmd) {
- FILE* fd = popen(cmd.c_str(), "r");
- if(fd == NULL) return "";
- char buf[2048]={'\0'};
- std::string line;
- while(fgets(buf, 2048, fd)){
- line += buf;
- }
- while(line.size() > 0 && line.back() == '\n'){
- line.pop_back();
- }
- return line;
- }
- static std::string Int2Hex(size_t d){
- char tmp[128];
- snprintf(tmp, 128, "%p", d);
- return tmp;
- }
-
- static std::string DetailInfo(const std::string &binary_file, size_t vma_addr){
- return RunCmd("addr2line -f -C -p -e " + binary_file + " " + Int2Hex(vma_addr));
- }
- static size_t AddrToVMA(size_t addr){
- Dl_info dinfo;
- link_map* lm;
- dladdr1((void*)addr, &dinfo,(void**)&lm, RTLD_DL_LINKMAP);
- return addr - lm->l_addr;
- }
- static void PrintStack() {
- char *full_stack[100] = {0};
- int depth = backtrace(reinterpret_cast<void**>(full_stack), sizeof(full_stack)/sizeof(full_stack[0]));
- if (depth){
- char** syms = backtrace_symbols(reinterpret_cast<void**>(full_stack), depth);
- if (syms){
- for(size_t i = 0; i < depth; i++){
- int j = 0;
- while(syms[i][j] != '(') j++;
- std::string f(syms[i], j);
- size_t vma_addr = AddrToVMA((size_t)full_stack[i]);
- printf("=== [%lu]:%s [vma: %p] [%s]\n", (i+1), syms[i], vma_addr, DetailInfo(f, vma_addr).c_str());
- }
- }
- free(syms);
- };
- }
- static void CoreHandler(int signo){
- PrintStack();
- raise(SIGSEGV);
- }
- };
- } //namespace AdsonLib
trans_acc.cpp
使用起来非常简单,在main函数里调用RegisterCoreHandler即可
- #include "stacktrace.h"
- int main(int argc, char *argv[]) {
- PrintCoreStack::RegisterCoreHandler();
- throw 333;
- }
注意链接要加 "-ldl"和"-rdynamic"
- cc_library(
- name = "common",
- srcs = glob(["common/*.cpp"]),
- hdrs = glob(["common/*.h"]),
- )
- cc_binary(
- name = "trans_acc",
- srcs = ["trans_acc.cpp"],
- deps = [
- ":common",
- ],
- linkopts = [
- "-lpthread", "-ldl", "-rdynamic",
- ]
- )
注意编译要加-g选项
build --cxxopt="-std=c++17" --cxxopt="-g" -c dbg
bazel build :trans_acc
可以看出,前边打出来的是backtrace返回 symbold.最后一个中括号里返回的是addr2line的详细信息。都打出来是因为防止addr2line转换失败。
- # bazel-bin/trans_acc
- === [1]:bazel-bin/trans_acc(_ZN8AdsonLib14PrintCoreStack10PrintStackEv+0x46) [0x40b90a] [vma: 0x40b90a] [AdsonLib::PrintCoreStack::PrintStack() at /proc/self/cwd/common/stacktrace.h:54]
- === [2]:bazel-bin/trans_acc(_ZZN8AdsonLib14PrintCoreStack19RegisterCoreHandlerEvENKUlvE_clEv+0x11) [0x40b41d] [vma: 0x40b41d] [AdsonLib::PrintCoreStack::RegisterCoreHandler()::{lambda()#1}::operator()() const at /proc/self/cwd/common/stacktrace.h:20]
- === [3]:bazel-bin/trans_acc(_ZZN8AdsonLib14PrintCoreStack19RegisterCoreHandlerEvENUlvE_4_FUNEv+0xe) [0x40b430] [vma: 0x40b430] [AdsonLib::PrintCoreStack::RegisterCoreHandler()::{lambda()#1}::_FUN() at /proc/self/cwd/common/stacktrace.h:21]
- === [4]:/lib64/libstdc++.so.6(+0x91e26) [0x7f0e2bd69e26] [vma: 0x91e26] [__cxxabiv1::__terminate(void (*)()) at /opt/gcc-gcc-8_3_0-release/x86_64-pc-linux-gnu/libstdc++-v3/libsupc++/../../.././libstdc++-v3/libsupc++/eh_terminate.cc:47]
- === [5]:/lib64/libstdc++.so.6(+0x91e61) [0x7f0e2bd69e61] [vma: 0x91e61] [std::terminate() at ??:?]
- === [6]:/lib64/libstdc++.so.6(+0x92094) [0x7f0e2bd6a094] [vma: 0x92094] [__cxa_throw at ??:?]
- === [7]:bazel-bin/trans_acc(_Z7TestLogv+0x428) [0x40a67b] [vma: 0x40a67b] [TestLog() at /proc/self/cwd/trans_acc.cpp:48 (discriminator 10)]
- === [8]:bazel-bin/trans_acc(main+0x19) [0x40a783] [vma: 0x40a783] [main at /proc/self/cwd/trans_acc.cpp:53]
- === [9]:/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f0e2b412555] [vma: 0x22555] [__libc_start_main at ??:?]
- === [10]:bazel-bin/trans_acc() [0x409bd9] [vma: 0x409bd9] [_start at ??:?]
- Aborted (core dumped)