久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

      <bdo id='RcwRH'></bdo><ul id='RcwRH'></ul>

    1. <small id='RcwRH'></small><noframes id='RcwRH'>

      <tfoot id='RcwRH'></tfoot>
    2. <i id='RcwRH'><tr id='RcwRH'><dt id='RcwRH'><q id='RcwRH'><span id='RcwRH'><b id='RcwRH'><form id='RcwRH'><ins id='RcwRH'></ins><ul id='RcwRH'></ul><sub id='RcwRH'></sub></form><legend id='RcwRH'></legend><bdo id='RcwRH'><pre id='RcwRH'><center id='RcwRH'></center></pre></bdo></b><th id='RcwRH'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='RcwRH'><tfoot id='RcwRH'></tfoot><dl id='RcwRH'><fieldset id='RcwRH'></fieldset></dl></div>
    3. <legend id='RcwRH'><style id='RcwRH'><dir id='RcwRH'><q id='RcwRH'></q></dir></style></legend>

        如何找到在 C++ 中拋出異常的位置?

        How do I find where an exception was thrown in C++?(如何找到在 C++ 中拋出異常的位置?)

          <tfoot id='jYDdb'></tfoot>
            <bdo id='jYDdb'></bdo><ul id='jYDdb'></ul>
            <legend id='jYDdb'><style id='jYDdb'><dir id='jYDdb'><q id='jYDdb'></q></dir></style></legend>
              <tbody id='jYDdb'></tbody>

              <small id='jYDdb'></small><noframes id='jYDdb'>

                • <i id='jYDdb'><tr id='jYDdb'><dt id='jYDdb'><q id='jYDdb'><span id='jYDdb'><b id='jYDdb'><form id='jYDdb'><ins id='jYDdb'></ins><ul id='jYDdb'></ul><sub id='jYDdb'></sub></form><legend id='jYDdb'></legend><bdo id='jYDdb'><pre id='jYDdb'><center id='jYDdb'></center></pre></bdo></b><th id='jYDdb'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='jYDdb'><tfoot id='jYDdb'></tfoot><dl id='jYDdb'><fieldset id='jYDdb'></fieldset></dl></div>
                • 本文介紹了如何找到在 C++ 中拋出異常的位置?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                  問題描述

                  限時送ChatGPT賬號..

                  我有一個程序會在某處拋出未捕獲的異常.我得到的只是拋出異常的報告,沒有關于它在哪里拋出的信息.編譯為包含調(diào)試符號的程序不通知我在我的代碼中生成異常的位置似乎是不合邏輯的.

                  如果沒有在 gdb 中設置catch throw"并為每個拋出的異常調(diào)用回溯,有什么方法可以判斷我的異常來自哪里?

                  解決方案

                  這里的一些信息可能對調(diào)試您的問題有用

                  如果異常未被捕獲,特殊庫函數(shù)std::terminate() 被自動調(diào)用.Terminate 實際上是一個指向函數(shù)的指針,默認值是標準 C 庫函數(shù) std::abort().如果未對未捕獲的異常進行清理?,它可能實際上有助于調(diào)試此問題,因為沒有調(diào)用析構函數(shù).
                  ???在調(diào)用 std::terminate() 之前是否解開堆棧由實現(xiàn)定義.


                  abort() 的調(diào)用通常可用于生成可分析的核心轉儲以確定異常的原因.確保通過 ulimit -c unlimited (Linux) 啟用核心轉儲.


                  您可以使用terminate()函數(shù)noreferrer">std::set_terminate().您應該能夠在 gdb 中的終止函數(shù)上設置斷點.您可能能夠從您的 terminate() 函數(shù)生成一個堆棧回溯,這個回溯可能有助于識別異常的位置.

                  未捕獲的異常有一個簡短的討論在Bruce Eckel's Thinking in C++,第二版,可能也有幫助.


                  由于 terminate() 默認調(diào)用 abort()(默認情況下會導致 SIGABRT 信號),您可能 能夠設置一個 SIGABRT 處理程序,然后 從信號處理程序中打印堆棧回溯.此回溯可能有助于識別異常的位置.


                  注意:我說可能是因為C++通過使用語言構造將錯誤處理和報告代碼與普通代碼分開來支持非本地錯誤處理.catch 塊可以并且經(jīng)常位于與拋出點不同的函數(shù)/方法中.在評論中也向我指出(感謝 Dan)無論堆棧是否由實現(xiàn)定義在調(diào)用 terminate() 之前展開.

                  更新:我將一個名為的 Linux 測試程序放在一起,該程序通過 set_terminate()terminate() 函數(shù)集中生成回溯,并且SIGABRT 的信號處理程序中的另一個.兩個回溯都正確顯示了未處理異常的位置.

                  更新 2:感謝 在終止內(nèi)捕獲未捕獲的異常,我學到了一些新技巧;包括在終止處理程序中重新拋出未捕獲的異常.請務必注意,自定義終止處理程序中的空 throw 語句適用于 GCC,并且不是可移植的解決方案.

                  代碼:

                  #ifndef _GNU_SOURCE#define _GNU_SOURCE#萬一#ifndef __USE_GNU#define __USE_GNU#萬一#include #include #include #include #include #include void my_terminate(void);命名空間{//調(diào)用 set_terminate 作為全局常量初始化的一部分static const bool SET_TERMINATE = std::set_terminate(my_terminate);}//此結構反映了在/usr/include/asm/ucontext.h 中找到的結構typedef struct _sig_ucontext {無符號長 uc_flags;結構 ucontext *uc_link;stack_t uc_stack;結構 sigcontext uc_mcontext;sigset_t uc_sigmask;} sig_ucontext_t;void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext) {sig_ucontext_t * uc = (sig_ucontext_t *)ucontext;//獲取從 EIP (x86) 發(fā)出信號時的地址void * caller_address = (void *) uc->uc_mcontext.eip;std::cerr <<信號"<<信號編號<<"("<<strsignal(sig_num)<<"),地址是"<<信息->si_addr<<"來自"<<呼叫者地址<

                  輸出:

                  <前>my_terminate 捕獲未處理的異常.what(): 運行時錯誤!my_terminate 回溯返回 10 幀[bt]: (0) ./test(my_terminate__Fv+0x1a) [0x8048e52][bt]: (1)/usr/lib/libstdc++-libc6.2-2.so.3 [0x40045baa][bt]: (2)/usr/lib/libstdc++-libc6.2-2.so.3 [0x400468e5][bt]: (3)/usr/lib/libstdc++-libc6.2-2.so.3(__rethrow+0xaf) [0x40046bdf][bt]: (4) ./test(throw_exception__Fv+0x68) [0x8049008][bt]: (5) ./test(foo2__Fv+0xb) [0x8049043][bt]: (6) ./test(foo1__Fv+0xb) [0x8049057][bt]: (7) ./test(main+0xc1) [0x8049121][bt]: (8) ./test(__libc_start_main+0x95) [0x42017589][bt]: (9) ./test(__eh_alloc+0x3d) [0x8048b21]信號 6(中止),地址是 0x1239 從 0x42029331crit_err_hdlr 回溯返回 13 幀[bt]: (1) ./test(kill+0x11) [0x42029331][bt]: (2) ./test(abort+0x16e) [0x4202a8c2][bt]: (3) ./test [0x8048f9f][bt]: (4)/usr/lib/libstdc++-libc6.2-2.so.3 [0x40045baa][bt]: (5)/usr/lib/libstdc++-libc6.2-2.so.3 [0x400468e5][bt]: (6)/usr/lib/libstdc++-libc6.2-2.so.3(__rethrow+0xaf) [0x40046bdf][bt]: (7) ./test(throw_exception__Fv+0x68) [0x8049008][bt]: (8) ./test(foo2__Fv+0xb) [0x8049043][bt]: (9) ./test(foo1__Fv+0xb) [0x8049057][bt]: (10) ./test(main+0xc1) [0x8049121][bt]: (11) ./test(__libc_start_main+0x95) [0x42017589][bt]: (12) ./test(__eh_alloc+0x3d) [0x8048b21]

                  I have a program that throws an uncaught exception somewhere. All I get is a report of an exception being thrown, and no information as to where it was thrown. It seems illogical for a program compiled to contain debug symbols not to notify me of where in my code an exception was generated.

                  Is there any way to tell where my exceptions are coming from short of setting 'catch throw' in gdb and calling a backtrace for every single thrown exception?

                  解決方案

                  Here's some info that may be of use in debugging your problem

                  If an exception is uncaught, the special library function std::terminate() is automatically called. Terminate is actually a pointer to a function and default value is the Standard C library function std::abort(). If no cleanups occur for an uncaught exception?, it may actually be helpful in debugging this problem as no destructors are called.
                  ?It is implementation-defined whether or not the stack is unwound before std::terminate() is called.


                  A call to abort() is often useful in generating a core dump that can be analyzed to determine the cause of the exception. Make sure that you enable core dumps via ulimit -c unlimited (Linux).


                  You can install your own terminate() function by using std::set_terminate(). You should be able to set a breakpoint on your terminate function in gdb. You may be able to generate a stack backtrace from your terminate() function and this backtrace may help in identifying the location of the exception.

                  There is a brief discussion on uncaught exceptions in Bruce Eckel's Thinking in C++, 2nd Ed that may be helpful as well.


                  Since terminate() calls abort() by default (which will cause a SIGABRT signal by default), you may be able to set a SIGABRT handler and then print a stack backtrace from within the signal handler. This backtrace may help in identifying the location of the exception.


                  Note: I say may because C++ supports non-local error handling through the use of language constructs to separate error handling and reporting code from ordinary code. The catch block can be, and often is, located in a different function/method than the point of throwing. It has also been pointed out to me in the comments (thanks Dan) that it is implementation-defined whether or not the stack is unwound before terminate() is called.

                  Update: I threw together a Linux test program called that generates a backtrace in a terminate() function set via set_terminate() and another in a signal handler for SIGABRT. Both backtraces correctly show the location of the unhandled exception.

                  Update 2: Thanks to a blog post on Catching uncaught exceptions within terminate, I learned a few new tricks; including the re-throwing of the uncaught exception within the terminate handler. It is important to note that the empty throw statement within the custom terminate handler works with GCC and is not a portable solution.

                  Code:

                  #ifndef _GNU_SOURCE
                  #define _GNU_SOURCE
                  #endif
                  #ifndef __USE_GNU
                  #define __USE_GNU
                  #endif
                  
                  #include <execinfo.h>
                  #include <signal.h>
                  #include <string.h>
                  
                  #include <iostream>
                  #include <cstdlib>
                  #include <stdexcept>
                  
                  void my_terminate(void);
                  
                  namespace {
                      // invoke set_terminate as part of global constant initialization
                      static const bool SET_TERMINATE = std::set_terminate(my_terminate);
                  }
                  
                  // This structure mirrors the one found in /usr/include/asm/ucontext.h
                  typedef struct _sig_ucontext {
                     unsigned long     uc_flags;
                     struct ucontext   *uc_link;
                     stack_t           uc_stack;
                     struct sigcontext uc_mcontext;
                     sigset_t          uc_sigmask;
                  } sig_ucontext_t;
                  
                  void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext) {
                      sig_ucontext_t * uc = (sig_ucontext_t *)ucontext;
                  
                      // Get the address at the time the signal was raised from the EIP (x86)
                      void * caller_address = (void *) uc->uc_mcontext.eip;
                      
                      std::cerr << "signal " << sig_num 
                                << " (" << strsignal(sig_num) << "), address is " 
                                << info->si_addr << " from " 
                                << caller_address << std::endl;
                  
                      void * array[50];
                      int size = backtrace(array, 50);
                  
                      std::cerr << __FUNCTION__ << " backtrace returned " 
                                << size << " frames
                  
                  ";
                  
                      // overwrite sigaction with caller's address
                      array[1] = caller_address;
                  
                      char ** messages = backtrace_symbols(array, size);
                  
                      // skip first stack frame (points here)
                      for (int i = 1; i < size && messages != NULL; ++i) {
                          std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl;
                      }
                      std::cerr << std::endl;
                  
                      free(messages);
                  
                      exit(EXIT_FAILURE);
                  }
                  
                  void my_terminate() {
                      static bool tried_throw = false;
                  
                      try {
                          // try once to re-throw currently active exception
                          if (!tried_throw++) throw;
                      }
                      catch (const std::exception &e) {
                          std::cerr << __FUNCTION__ << " caught unhandled exception. what(): "
                                    << e.what() << std::endl;
                      }
                      catch (...) {
                          std::cerr << __FUNCTION__ << " caught unknown/unhandled exception." 
                                    << std::endl;
                      }
                  
                      void * array[50];
                      int size = backtrace(array, 50);    
                  
                      std::cerr << __FUNCTION__ << " backtrace returned " 
                                << size << " frames
                  
                  ";
                  
                      char ** messages = backtrace_symbols(array, size);
                  
                      for (int i = 0; i < size && messages != NULL; ++i) {
                          std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl;
                      }
                      std::cerr << std::endl;
                  
                      free(messages);
                  
                      abort();
                  }
                  
                  int throw_exception() {
                      // throw an unhandled runtime error
                      throw std::runtime_error("RUNTIME ERROR!");
                      return 0;
                  }
                  
                  int foo2() {
                      throw_exception();
                      return 0;
                  }
                  
                  int foo1() {
                      foo2();
                      return 0;
                  }
                  
                  int main(int argc, char ** argv) {
                      struct sigaction sigact;
                  
                      sigact.sa_sigaction = crit_err_hdlr;
                      sigact.sa_flags = SA_RESTART | SA_SIGINFO;
                  
                      if (sigaction(SIGABRT, &sigact, (struct sigaction *)NULL) != 0) {
                          std::cerr << "error setting handler for signal " << SIGABRT 
                                    << " (" << strsignal(SIGABRT) << ")
                  ";
                          exit(EXIT_FAILURE);
                      }
                  
                      foo1();
                  
                      exit(EXIT_SUCCESS);
                  }
                  

                  Output:

                  my_terminate caught unhanded exception. what(): RUNTIME ERROR!
                  my_terminate backtrace returned 10 frames
                  
                  [bt]: (0) ./test(my_terminate__Fv+0x1a) [0x8048e52]
                  [bt]: (1) /usr/lib/libstdc++-libc6.2-2.so.3 [0x40045baa]
                  [bt]: (2) /usr/lib/libstdc++-libc6.2-2.so.3 [0x400468e5]
                  [bt]: (3) /usr/lib/libstdc++-libc6.2-2.so.3(__rethrow+0xaf) [0x40046bdf]
                  [bt]: (4) ./test(throw_exception__Fv+0x68) [0x8049008]
                  [bt]: (5) ./test(foo2__Fv+0xb) [0x8049043]
                  [bt]: (6) ./test(foo1__Fv+0xb) [0x8049057]
                  [bt]: (7) ./test(main+0xc1) [0x8049121]
                  [bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
                  [bt]: (9) ./test(__eh_alloc+0x3d) [0x8048b21]
                  
                  signal 6 (Aborted), address is 0x1239 from 0x42029331
                  crit_err_hdlr backtrace returned 13 frames
                  
                  [bt]: (1) ./test(kill+0x11) [0x42029331]
                  [bt]: (2) ./test(abort+0x16e) [0x4202a8c2]
                  [bt]: (3) ./test [0x8048f9f]
                  [bt]: (4) /usr/lib/libstdc++-libc6.2-2.so.3 [0x40045baa]
                  [bt]: (5) /usr/lib/libstdc++-libc6.2-2.so.3 [0x400468e5]
                  [bt]: (6) /usr/lib/libstdc++-libc6.2-2.so.3(__rethrow+0xaf) [0x40046bdf]
                  [bt]: (7) ./test(throw_exception__Fv+0x68) [0x8049008]
                  [bt]: (8) ./test(foo2__Fv+0xb) [0x8049043]
                  [bt]: (9) ./test(foo1__Fv+0xb) [0x8049057]
                  [bt]: (10) ./test(main+0xc1) [0x8049121]
                  [bt]: (11) ./test(__libc_start_main+0x95) [0x42017589]
                  [bt]: (12) ./test(__eh_alloc+0x3d) [0x8048b21]
                  
                  

                  這篇關于如何找到在 C++ 中拋出異常的位置?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

                  【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權益,請聯(lián)系我們刪除處理,感謝您的支持!

                  相關文檔推薦

                  Why do two functions have the same address?(為什么兩個函數(shù)的地址相同?)
                  Why the initializer of std::function has to be CopyConstructible?(為什么 std::function 的初始化程序必須是可復制構造的?)
                  mixing templates with polymorphism(混合模板與多態(tài)性)
                  When should I use the keyword quot;typenamequot; when using templates(我什么時候應該使用關鍵字“typename?使用模板時)
                  Dependent name resolution amp; namespace std / Standard Library(依賴名稱解析命名空間 std/標準庫)
                  gcc can compile a variadic template while clang cannot(gcc 可以編譯可變參數(shù)模板,而 clang 不能)
                  <tfoot id='WANUE'></tfoot>

                  <i id='WANUE'><tr id='WANUE'><dt id='WANUE'><q id='WANUE'><span id='WANUE'><b id='WANUE'><form id='WANUE'><ins id='WANUE'></ins><ul id='WANUE'></ul><sub id='WANUE'></sub></form><legend id='WANUE'></legend><bdo id='WANUE'><pre id='WANUE'><center id='WANUE'></center></pre></bdo></b><th id='WANUE'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='WANUE'><tfoot id='WANUE'></tfoot><dl id='WANUE'><fieldset id='WANUE'></fieldset></dl></div>
                  <legend id='WANUE'><style id='WANUE'><dir id='WANUE'><q id='WANUE'></q></dir></style></legend>
                • <small id='WANUE'></small><noframes id='WANUE'>

                          <tbody id='WANUE'></tbody>
                            <bdo id='WANUE'></bdo><ul id='WANUE'></ul>
                            主站蜘蛛池模板: 国产精品久久久久久久久久三级 | 黄色毛片在线看 | 国产精品久久久久久婷婷天堂 | 欧美综合视频在线 | 国产精品久久久久久福利一牛影视 | 精品欧美色视频网站在线观看 | 久久久久一区二区 | 欧美一级欧美三级在线观看 | 日韩在线视频免费观看 | 毛片在线视频 | 日屁视频 | 欧洲视频一区二区 | 亚洲一区二区中文字幕 | 999精品在线 | 国产免费av在线 | av中文字幕在线观看 | 蜜月va乱码一区二区三区 | 国产精品福利在线观看 | 欧美午夜精品久久久久久浪潮 | 成人免费在线播放 | 97精品超碰一区二区三区 | 91麻豆精品国产91久久久久久 | 欧美一级黄带 | 91精品国产色综合久久 | 久久综合九色综合欧美狠狠 | 久久亚洲精品久久国产一区二区 | 亚洲手机视频在线 | 欧美日韩免费 | 国产精品美女久久久久aⅴ国产馆 | 99久久婷婷国产综合精品首页 | 综合久久久久久久 | 中文字幕 在线观看 | 亚洲福利av | 国产在线视频一区二区 | 久久久久国产一区二区三区 | 99久久免费精品国产免费高清 | 中文字幕精品一区久久久久 | 久久久青草婷婷精品综合日韩 | 日韩三级在线 | 久久视频一区 | 亚洲国产一区二区三区 |