bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

在C++代碼中怎么獲取函數(shù)調(diào)用棧信息

這篇文章主要介紹“在C++ 代碼中怎么獲取函數(shù)調(diào)用棧信息”,在日常操作中,相信很多人在在C++ 代碼中怎么獲取函數(shù)調(diào)用棧信息問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”在C++ 代碼中怎么獲取函數(shù)調(diào)用棧信息”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)是一家專業(yè)提供貴德企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、成都做網(wǎng)站H5建站、小程序制作等業(yè)務(wù)。10年已為貴德眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。

一、前言

程序在執(zhí)行過程中 crash 是非常嚴(yán)重的問題,一般都應(yīng)該在測試階段排除掉這些問題,但是總會有漏網(wǎng)之魚被帶到 release 階段。

因此,程序的日志系統(tǒng)需要偵測這種情況,在代碼崩潰的時候獲取函數(shù)調(diào)用棧信息,為 debug 提供有效的信息。

二、Linux 平臺

1. 注冊異常信號的處理函數(shù)

需要處理哪些異常信號

#include <execinfo.h> #include <cxxabi.h> #include <signal.h>  const std::map<int, std::string> Signals = {     {SIGINT, "SIGINT"},         {SIGABRT, "SIGABRT"},      {SIGFPE, "SIGFPE"},        {SIGILL, "SIGILL"},       {SIGSEGV, "SIGSEGV"}     // 可以添加其他信號 };

注冊信號處理函數(shù)

struct sigaction action; sigemptyset(&action.sa_mask); action.sa_sigaction = &sigHandler; action.sa_flags = SA_SIGINFO;    for (const auto &sigPair : Signals)  {     if (sigaction(sigPair.first, &action, NULL) < 0)         fprintf(stderr, "Error: sigaction failed! \n");  }

2. 捕獲異常,獲取函數(shù)調(diào)用棧信息

void sigHandler(int signum, siginfo_t *info, void *ctx) {     const size_t dump_size = 50;     void *array[dump_size];     int size = backtrace(array, dump_size);     char **symbols = backtrace_symbols(array, size);     std::ostringstream oss;      for (int i = 0; i < size; ++i)     {         char *mangleName = 0;         char *offsetBegin = 0;         char *offsetEnd = 0;          for (char *p = symbols[i]; *p; ++p)         {             if ('(' == *p)             {                     mangleName = p;             }                else if ('+' == *p)             {                 offsetBegin = p;             }             else if (')' == *p)             {                 offsetEnd = p;                 break;             }         }          if (mangleName && offsetBegin && offsetEnd && mangleName < offsetBegin)         {             *mangleName++ = '\0';             *offsetBegin++ = '\0';             *offsetEnd++ = '\0';                          int status;             char *realName = abi::__cxa_demangle(mangleName, 0, 0, &status);             if (0 == status)                 oss << "\tstack dump [" << i << "]  " << symbols[i] << " : " << realName << "+";             else                 oss << "\tstack dump [" << i << "]  " << symbols[i] << mangleName << "+";             oss << offsetBegin << offsetEnd << std::endl;             free(realName);         }         else         {             oss << "\tstack dump [" << i << "]  " << symbols[i] << std::endl;         }     }     free(symbols);     oss << std::endl;     std::cout << oss.str(); // 打印函數(shù)調(diào)用棧信息 }

三、Windwos 平臺

在 Windows 平臺下的代碼實現(xiàn),參考了國外某個老兄的代碼,如下:

1. 設(shè)置異常處理函數(shù)

#include <windows.h> #include <dbghelp.h>  SetUnhandledExceptionFilter(exceptionHandler);

2. 捕獲異常,獲取函數(shù)調(diào)用棧信息

void exceptionHandler(LPEXCEPTION_POINTERS info) {     CONTEXT *context = info->ContextRecord;     std::shared_ptr<void> RaiiSysCleaner(nullptr, [&](void *) {       SymCleanup(GetCurrentProcess());     });    const size_t dumpSize = 64;   std::vector<uint64_t> frameVector(dumpSize);    DWORD machine_type = 0;   STACKFRAME64 frame = {};   frame.AddrPC.Mode = AddrModeFlat;   frame.AddrFrame.Mode = AddrModeFlat;   frame.AddrStack.Mode = AddrModeFlat;  #ifdef _M_IX86   frame.AddrPC.Offset = context->Eip;   frame.AddrFrame.Offset = context->Ebp;   frame.AddrStack.Offset = context->Esp;   machine_type = IMAGE_FILE_MACHINE_I386; #elif _M_X64   frame.AddrPC.Offset = context->Rip;   frame.AddrFrame.Offset = context->Rbp;   frame.AddrStack.Offset = context->Rsp;   machine_type = IMAGE_FILE_MACHINE_AMD64; #elif _M_IA64   frame.AddrPC.Offset = context->StIIP;   frame.AddrFrame.Offset = context->IntSp;   frame.AddrStack.Offset = context->IntSp;   machine_type = IMAGE_FILE_MACHINE_IA64;   frame.AddrBStore.Offset = context.RsBSP;   frame.AddrBStore.Mode = AddrModeFlat; #else   frame.AddrPC.Offset = context->Eip;   frame.AddrFrame.Offset = context->Ebp;   frame.AddrStack.Offset = context->Esp;   machine_type = IMAGE_FILE_MACHINE_I386; #endif    for (size_t index = 0; index < frameVector.size(); ++index)   {     if (StackWalk64(machine_type,            GetCurrentProcess(),            GetCurrentThread(),            &frame,            context,            NULL,            SymFunctionTableAccess64,            SymGetModuleBase64,            NULL)) {       frameVector[index] = frame.AddrPC.Offset;     } else {       break;     }   }    std::string dump;   const size_t kSize = frameVector.size();   for (size_t index = 0; index < kSize && frameVector[index]; ++index) {     dump += getSymbolInfo(index, frameVector);     dump += "\n";   }  std::cout << dump;  }

主要是利用了 StackWalk64 這個函數(shù),從地址轉(zhuǎn)換為函數(shù)名稱。

到此,關(guān)于“在C++ 代碼中怎么獲取函數(shù)調(diào)用棧信息”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

本文題目:在C++代碼中怎么獲取函數(shù)調(diào)用棧信息
本文網(wǎng)址:http://vcdvsql.cn/article30/pdcpso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站自適應(yīng)網(wǎng)站域名注冊網(wǎng)站導(dǎo)航網(wǎng)站制作品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站