<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      跨平臺coredump生成器——breakpad

      跨平臺coredump生成器——breakpad

      介紹

      google/breakpad: Mirror of Google Breakpad project

      breakpad是google開發(fā)的一個跨平臺C/C++ dump捕獲開源庫,崩潰文件使用微軟的minidump格式存儲,也支持發(fā)送這個dump文件到服務(wù)器,breakpad可以在程序崩潰時觸發(fā)dump寫入操作,也可以在沒有觸發(fā)dump時主動寫dump文件。breakpad支持windows、linux、macos、android、ios等。目前已有Google Chrome, Firefox, Google Picasa, Camino, Google Earth等項目使用。

      工作原理

      集成breakpad的工程會有額外鏈接一個 Breakpad Client 靜態(tài)庫(libbreakpad_client.a)。在Build System編譯生成產(chǎn)物時strip剝離符號前,使用 Breadpad symbol dumperdump_syms)生成出調(diào)試包 Debugging Infomation (google自己的格式,不是gnu的調(diào)試信息)并自行留存,然后可以發(fā)布程序(當(dāng)然還會先strip剝離符號信息)。

      等到崩潰發(fā)生時,觸發(fā) Breakpad Client 回調(diào),生成 minidump 文件(微軟的格式)到指定目錄并發(fā)送到遠(yuǎn)端服務(wù)器。然后再服務(wù)器上就可以與構(gòu)建時留存的 Debugging Infomation 結(jié)合傳遞給 Breakpad minidump processorminidump_stackwalk)來得到人類可讀的崩潰堆棧。

      這個生成minidump的回調(diào), 在 Windows 上,是通過 SetUnhandledExceptionFilter() 實現(xiàn)的;在 OS X 上,是通過創(chuàng)建一個在 Mach 異常端口上等待的線程實現(xiàn)的;在 Linux 上,是通過為各種異常(如 SIGILL, SIGSEGV 等)安裝信號處理程序?qū)崿F(xiàn)的。

      image

      主要組件

      breakpad有三個主要的組件:

      • breakpad client:breakpad的客戶端靜態(tài)庫(libbreakpad_client.a)。它的主要作用是在程序崩潰后,接管程序的異常處理,具體來說,它主要做了兩方面的事情。
        • 響應(yīng)程序崩潰時接收到的signal,包括:SIGSEGVSIGABRTSIGFPESIGILLSIGBUS。 (另外兩個SIGSTOPSIGKILL無法處理)
        • 獲取程序崩潰那一刻的運行時信息,保存為一個minidump格式的文件。
      • symbol dumper:調(diào)試信息文件生成程序(dump_syms)。主要是用來從可執(zhí)行程序中提取與符號相關(guān)的信息,并保存為一種特定格式的文件。
      • processor module:minidump 處理程序(minidump_stackwalk),它的作用就是根據(jù)coredump及symbol file,構(gòu)建出可讀的call stack。

      Minidump格式

      Minidump是微軟開發(fā)的一種用于崩潰時記錄的小存儲器轉(zhuǎn)儲文件,它類似與linux下的core fileminidump中包含以下信息:

      • 進(jìn)程裝載的驅(qū)動程序和共享庫列表,這個列表中包含了指定的名稱和版本號
      • 進(jìn)程中存在的線程列表。對于每個線程,小型轉(zhuǎn)儲包括處理器寄存器的狀態(tài)和線程堆棧內(nèi)存的內(nèi)容。這些數(shù)據(jù)是未解釋的字節(jié)流,因為 Breakpad 客戶端通常沒有可用于生成函數(shù)名稱或行號,甚至標(biāo)識堆棧幀邊界的調(diào)試信息。
      • 已停止的處理器的上下文 (PRCB)
      • 已停止的進(jìn)程的信息和內(nèi)核上下文 (EPROCESS)
      • 有關(guān)收集轉(zhuǎn)儲的系統(tǒng)的其他信息:處理器和操作系統(tǒng)版本、轉(zhuǎn)儲的原因等。

      Breakpad 在所有平臺上使用 Windows 小型轉(zhuǎn)儲文件,而不是傳統(tǒng)核心文件,原因如下:

      • 核心文件可能非常大,因此無法通過網(wǎng)絡(luò)將其發(fā)送到收集器進(jìn)行處理。小型轉(zhuǎn)儲更小,因為它們被設(shè)計為這樣使用。
      • 核心文件格式記錄得很差。例如,Linux 標(biāo)準(zhǔn)基礎(chǔ)不描述寄存器如何存儲在段中。
      • 說服 Windows 計算機(jī)生成核心轉(zhuǎn)儲文件比說服其他計算機(jī)編寫小型轉(zhuǎn)儲文件更難。
      • 它簡化了 Breakpad 處理器,僅支持一種文件格式。

      集成

      客戶端的典型示例是:受監(jiān)控的應(yīng)用程序鏈接到Breakpad客戶端庫,在其主函數(shù)中安裝一個 Breakpad 處理程序,并提供一個回調(diào)來啟動一個小型崩潰報告程序。崩潰報告程序?qū)㈡溄拥桨l(fā)送程序庫,并在啟動時發(fā)送崩潰轉(zhuǎn)儲。由于從崩潰的進(jìn)程中執(zhí)行任何大量工作都存在固有的不可靠性,因此建議為該功能使用單獨的進(jìn)程。

      編譯

      目前只在Linux上和WSL中成功編譯。在Powershell和mingw的shell下執(zhí)行均出錯。

      breakpad由于是chromium的子項目,使用devopt_tools工具管理源碼。但是這個工具在外網(wǎng),所以這里采用手動下載依賴的方法。

      1. 下載breakpad源碼:

        git clone https://github.com/google/breakpad.git
        
      2. 下載并集成依賴:

        git clone https://github.com/adelshokhy112/linux-syscall-support.git
        

        然后將 LSS 中的linux_syscall_support.h文件放至breakpad/src/third_party/lss/目錄下。

      3. 編譯breakpad:

        ./configure
        bear -- make
        

        中途可能說 linux_syscall_support.h 中使用了標(biāo)記為 deprecated 的做法,所以需要使用 -Wno-deprecated 來避免將警告視為錯誤。

        # 在項目生成的makefile中修改
        -WARN_CXXFLAGS =  -Wmissing-braces -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-compare -Wunused-local-typedefs -Wunused-variable -Wvla -Werror
        +WARN_CXXFLAGS =  -Wmissing-braces -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-compare -Wunused-local-typedefs -Wunused-variable -Wvla -Werror -Wno-deprecated
        
      4. 收集編譯產(chǎn)物:

        #!/bin/sh
        
        set -e
        
        os=$(uname -s)
        artifacts_dir=artifacts_$(date +%Y%m%d%H%M%S)
        
        mkdir -p $artifacts_dir
        
        cp src/client/$os/libbreakpad_client.a $artifacts_dir
        cp src/tools/$os/dump_syms/dump_syms $artifacts_dir
        cp src/processor/minidump_stackwalk $artifacts_dir
        cp src/tools/$os/symupload/sym_upload $artifacts_dir
        cp src/tools/$os/md2core/minidump-2-core $artifacts_dir
        

      提供一個CMake腳本:

      # FindBreakpad.cmake
      if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
          set(BREAKPAD_LIBRARY ${PROJECT_SOURCE_DIR}/breakpad/libbreakpad_client.a)
          # set(BREAKPAD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/../src/client/linux)
      elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
          set(BREAKPAD_LIBRARY ${PROJECT_SOURCE_DIR}/breakpad/breakpad_client.lib)
          # set(BREAKPAD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/../src/client/windows)
      else()
          message(FATAL_ERROR "Unsupported platform")
      endif()
      set(BREAKPAD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/../src)
      
      if(BREAKPAD_LIBRARY AND BREAKPAD_INCLUDE_DIR)
          add_library(Breakpad STATIC IMPORTED GLOBAL)
          set_target_properties(Breakpad PROPERTIES IMPORTED_LOCATION ${BREAKPAD_LIBRARY})
          target_include_directories(Breakpad INTERFACE ${BREAKPAD_INCLUDE_DIR})
      else()
          message(FATAL_ERROR "Breakpad library not found, skip creating Breakpad target")
      endif()
      

      生成Minidump

      #include "client/linux/handler/exception_handler.h"
      
      static bool DumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, void *context, bool succeeded) {
          std::cout << "Dump path: " << descriptor.path() << std::endl;
          return succeeded;
      }
      void crash() { volatile int* a = (int*)(NULL); *a = 1; }
      
      int main() {
          std::cout.setf(std::ios::unitbuf);
      
          google_breakpad::MinidumpDescriptor descriptor("/tmp");
          // 在 ExceptionHandler 對象的整個生命周期內(nèi),異常處理都是啟用的,因此應(yīng)盡可能早地實例化它,并在盡可能保持其存活。
          google_breakpad::ExceptionHandler eh(descriptor, nullptr, DumpCallback, nullptr, true, -1);
      
          crash();
          return 0;
      }
      

      注意:回調(diào)函數(shù)中應(yīng)該盡可能少的做工作。因為當(dāng)該函數(shù)回調(diào)時,程序處于不安全狀態(tài)。從其他函數(shù)庫分配內(nèi)存或調(diào)用函數(shù)可能并不安全。如果你必須要在回調(diào)函數(shù)中實現(xiàn)一些功能,最安全的操作是forkexec一個新的進(jìn)程來執(zhí)行你需要做的功能。Breakpad源碼中包含libc函數(shù)(用的是musl)的一些簡單重新實現(xiàn),同樣,在src/third_party/lss中包含一些用于進(jìn)行Linux系統(tǒng)調(diào)用的函數(shù),應(yīng)該避免直接調(diào)用libc和一些其他的動態(tài)庫。

      上傳Minidump

      可以使用編譯得到的 sym_upload 程序,這個程序是用 curl 實現(xiàn)的。

      生成調(diào)試符號并得到崩潰堆棧

      要生成有用的堆棧,就得讓breakpad看到程序二進(jìn)制對應(yīng)的調(diào)試符號。

      1. 編譯時使用 -g 來生成調(diào)試符號

      2. 使用 dump_syms 來生成breakpad所需的符號文件(是文本格式的)

        dump_syms ./test > test.sym
        
      3. 然后需要將這個符號文件放置在特定的目錄中,才能被 minidump_stackwalk 解析。這個符號文件的第一行說明了要放在哪個目錄,例如:

        head -n1 test.sym MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 test
        mkdir -p ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830 # 創(chuàng)建目錄
        mv test.sym ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830
        
      4. 使用 minidump_stackwalk 生成堆棧:

        minidump_stackwalk minidump.dmp ./symbols 2>/dev/null # 會在stderr中打日志,在stdout中輸出堆棧
        

      如果沒有把符號文件放在指定目目錄,也能得到輸出,但是信息不全!

      image

      其他

      異常安全

      Once an application encounters an exception, it is in an indeterminate and possibly hazardous state. Consequently, any code that runs after an exception occurs must take extreme care to avoid performing operations that might fail, hang, or cause additional exceptions. This task is not at all straightforward, and the Breakpad handler library seeks to do it properly, accounting for all of the minute details while allowing other application developers, even those with little systems programming experience, to reap the benefits. All of the Breakpad handler code that executes after an exception occurs has been written according to the following guidelines for safety at exception time:一旦應(yīng)用程序遇到異常,它就會處于不確定且可能危險的狀態(tài)。因此,在異常發(fā)生后運行的任何代碼都必須極其小心,避免執(zhí)行可能會失敗、掛起或引發(fā)其他異常的操作。這項任務(wù)絕非易事,而 Breakpad 處理程序庫旨在妥善處理,考慮到所有細(xì)微之處,同時讓其他應(yīng)用程序開發(fā)人員,甚至是那些幾乎沒有系統(tǒng)編程經(jīng)驗的人,也能從中受益。所有在異常發(fā)生后執(zhí)行的 Breakpad 處理程序代碼都遵循以下異常處理時的安全準(zhǔn)則:

      • Use of the application heap is forbidden. The heap may be corrupt or otherwise unusable, and allocators may not function.應(yīng)用程序堆的使用被禁止。堆可能已損壞或無法使用,分配器可能無法運行。
      • Resource allocation must be severely limited. The handler may create a new file to contain the dump, and it may attempt to launch a process to continue handling the crash.資源分配必須嚴(yán)格限制。處理程序可以創(chuàng)建一個新文件來保存轉(zhuǎn)儲,并且可以嘗試啟動一個進(jìn)程來繼續(xù)處理崩潰。
      • Execution on the thread that caused the exception is significantly limited. The only code permitted to execute on this thread is the code necessary to transition handling to a dedicated preallocated handler thread, and the code to return from the exception handler.引發(fā)異常的線程的執(zhí)行受到顯著限制。 此線程上唯一允許執(zhí)行的代碼是將處理轉(zhuǎn)移到專用的預(yù)分配處理線程所需的代碼,以及從異常處理程序返回的代碼。
      • Handlers shouldn’t handle crashes by attempting to walk stacks themselves, as stacks may be in inconsistent states. Dump generation should be performed by interfacing with the operating system’s memory manager and code module manager.處理程序不應(yīng)通過自行遍歷堆棧來處理崩潰,因為堆棧可能處于不一致的狀態(tài)。應(yīng)通過與操作系統(tǒng)的內(nèi)存管理器和代碼模塊管理器進(jìn)行交互來生成轉(zhuǎn)儲。
      • Library code, including runtime library code, must be avoided unless it provably meets the above guidelines. For example, this means that the STL string class may not be used, because it performs operations that attempt to allocate and use heap memory. It also means that many C runtime functions must be avoided, particularly on Windows, because of heap operations that they may perform.除非能證明符合上述準(zhǔn)則,否則必須避免使用庫代碼,包括運行時庫代碼。例如,這意味著不能使用 STL 字符串類,因為它會嘗試分配和使用堆內(nèi)存。這也意味著必須避免使用許多 C 運行時函數(shù),尤其是在 Windows 系統(tǒng)上,因為它們可能會執(zhí)行堆操作。

      A dedicated handler thread is used to preserve the state of the exception thread when an exception occurs: during dump generation, it is difficult if not impossible for a thread to accurately capture its own state. Performing all exception-handling functions on a separate thread is also critical when handling stack-limit-exceeded exceptions. It would be hazardous to run out of stack space while attempting to handle an exception. Because of the rule against allocating resources at exception time, the Breakpad handler library creates its handler thread when it installs its exception handler. On Mac OS X, this handler thread is created during the normal setup of the exception handler, and the handler thread will be signaled directly in the event of an exception. On Windows and Linux, the handler thread is signaled by a small amount of code that executes on the exception thread. Because the code that executes on the exception thread in this case is small and safe, this does not pose a problem. Even when an exception is caused by exceeding stack size limits, this code is sufficiently compact to execute entirely within the stack’s guard page without causing an exception.當(dāng)發(fā)生異常時,會使用一個專用的處理線程來保存異常線程的狀態(tài):在生成轉(zhuǎn)儲期間,線程很難甚至不可能準(zhǔn)確捕獲自身狀態(tài)。在處理超出堆棧限制的異常時,在單獨的線程上執(zhí)行所有異常處理功能也至關(guān)重要。在嘗試處理異常時耗盡堆棧空間會很危險。由于在異常時分配資源是被禁止的,所以 Breakpad 處理程序庫在安裝其異常處理程序時就創(chuàng)建了其處理線程。在 Mac OS X 上,此處理線程是在正常設(shè)置異常處理程序期間創(chuàng)建的,并且在發(fā)生異常時會直接向該處理線程發(fā)送信號。在 Windows 和 Linux 上,異常線程上執(zhí)行的一小段代碼會向處理線程發(fā)送信號。由于在這種情況下在異常線程上執(zhí)行的代碼很小且安全,所以這不會造成問題。即使異常是由超出堆棧大小限制引起的,此代碼也足夠緊湊,可以在堆棧的保護(hù)頁內(nèi)完全執(zhí)行而不會引發(fā)異常。

      The handler thread may also be triggered directly by a user call, even when no exception occurs, to allow dumps to be generated at any point deemed interesting.即使未發(fā)生異常,處理程序線程也可能由用戶調(diào)用直接觸發(fā),以便在任何被認(rèn)為有趣的時刻生成轉(zhuǎn)儲。

      進(jìn)程的兩種異常處理模式

      breakpad/docs/exception_handling.md at main · google/breakpad

      進(jìn)程的異常處理分為In-processOut-process異常處理兩種模式。因為從已經(jīng)要崩潰的進(jìn)程中生成dump文件是不安全的(進(jìn)程的一些資源和狀態(tài)已經(jīng)不正常了,內(nèi)存和堆棧可能破壞了,不應(yīng)該執(zhí)行太復(fù)雜、申請資源的操作),所以所有的OS都提供了Out-process模式fork額外的進(jìn)程來處理異常。

      Breakpad使用的是Out-process異常處理模式,dump文件的生成和寫入在崩潰進(jìn)程外進(jìn)行,linux中進(jìn)程間采用socketpair通信。

      posted @ 2025-09-19 17:56  3的4次方  閱讀(76)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 成人午夜免费无码视频在线观看| 亚洲老熟女一区二区三区| 国产精品福利自产拍在线观看| 亚洲 日本 欧洲 欧美 视频| 精品一区二区av天堂| 精品精品亚洲高清a毛片| 日韩免费美熟女中文av| 无卡无码无免费毛片| 国产欧美综合在线观看第十页| 亚欧美闷骚院| 精品亚洲欧美无人区乱码| 根河市| 国产在线精品一区二区三区不卡| 国产精品第一区亚洲精品| 青青草无码免费一二三区| 精品熟女少妇av免费久久| 成av人片一区二区久久| 精品 日韩 国产 欧美 视频| 日韩老熟女av搜索结果| 亚洲成人高清av在线| 国产95在线 | 亚洲| 成人欧美日韩一区二区三区| 国产精品午夜福利精品| 西西午夜无码大胆啪啪国模| 日韩人妻无码精品久久久不卡 | 与子敌伦刺激对白播放| 国产成人精品一区二区三区免费| 国模一区二区三区私拍视频| 亚洲天堂伊人久久a成人| 宅男噜噜噜66在线观看| 久热这里只国产精品视频| 老司机精品成人无码av| 国产成人av电影在线观看第一页| 国产一区二区三区怡红院| 色婷婷综合久久久久中文字幕| 中文字幕人妻不卡精品| 精品人妻免费看一区二区三区| 亚洲精品视频免费| 另类专区一区二区三区| 色综合色综合久久综合频道| 久久久精品人妻一区二区三区|