äŸå€ãšé¢é£ããã¹ã¿ãã¯ããã¢ãŒã·ã§ã³ã¯ãC ++ã§æãåªããææ³ã®1ã€ã§ãã äŸå€åŠçã¯ãããã°ã©ã ã®ãããã¯æ§é ãšçŽæçã«äžè²«ããŠããŸãã å€éšçã«ã¯ãäŸå€åŠçã¯éåžžã«è«ççã§èªç¶ãªããã§ãã
ã¹ã¿ãã¯ãªããžã§ã¯ããæ£ç¢ºã«äœ¿çšãããšãéåžžã«å¹ççã§å®å šãªã³ãŒããäœæã§ããŸããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã䜿çšããã·ã¹ãã ãšã¯ç°ãªãããªã³ã¯ã®å±ææ§ãç¶æããããããã¡ã¢ãªã«å¯Ÿããã·ã¹ãã ã®åŒã³åºãåæ°ãæžãããæçåãæžãããã¡ã¢ãªãã£ãã·ã¥ãããå¹ççã«äœ¿çšã§ããŸãã
ãã ããC ++ã§ã¯ãäŸå€ã¯åŸæ¥ãæåéããšã©ãŒå埩ã«é¢é£ããäŸå€ãšèŠãªãããŸãã ããããã³ã³ãã€ã©ã«ããäŸå€åŠçã®å®è£ ãéåžžã«é«äŸ¡ã§ãããšããçç±ãŸãã¯çµæã§ãããã©ãããèšãã®ã¯å°é£ã§ãã çç±ãç解ããŠã¿ãŸãããã
ããã«ç¶ããŸã ã
ç¶æ³ã¯ã©ãã§ããã
äŸå€åŠçãå®è£ ããã«ã¯ã2ã€ã®ã¢ãããŒãããããŸãã
- 1ã€ç®ã¯ããæè ã«æ¯æãããããããšããèšèã§èª¬æã§ããŸãã ã³ã³ãã€ã©ãŒã¯ãäŸå€ãçºçããªãå Žåã®ã³ã¹ããæå°åããããšããŸãã çæ³çã«ã¯ãããã°ã©ã ã«ã¯è¿œå ã®è² è·ããããããå¿ èŠãªæ å ±ã¯ãã¹ãŠãããã¢ãŒã·ã§ã³ã«äŸ¿å©ãªåœ¢åŒã§ã³ãŒãããé¢ããå Žæã«é 眮ãããŸãã
- 2çªç®ã®æŠç¥ã¯ã誰ããå€ãåžžã«æ¯æããããšã§ããã€ãŸããããã»ã¹ã«ãããŠãããã°ã©ã ã¯ã¹ã¿ãã¯ã®æ£ããããã¢ãŒã·ã§ã³ã«å¿ èŠãªæ å ±ã®é¢é£æ§ãç¶æããããã«ç¹å®ã®ã³ã¹ããè² æ ããŸããããã«ãäŸå€ã®å Žåãã¹ã¿ãã¯ã®ããã¢ãŒã·ã§ã³ã¯å®äŸ¡ã§ãã
ããã€ãã®äŸïŒ
- GCC / SJLJ SJLJã¯setjmp / longjmpã®ç¥ã§ãã ããããæåã®ã¢ãããŒããæããŸãããã³ã³ãããŒã«è»¢éã¹ããŒã ã®ãããã§ã è©Šè¡ããšã«åºå®æéãããããŸãã æ¬è³ªçã«ããã®å®è£
ã«ã¯ãäž¡æ¹ã®ã¢ãããŒãã«åºæã®ãã¹ãŠã®ææªãçµã¿èŸŒãŸããŠããŸãã 4çªç®ã®ããŒãžã§ã³ãŸã§ãããã¯äž»èŠãªäŸå€åŠçãªãã·ã§ã³ã§ããã
ååã瀺ãããã«ãå¶åŸ¡ã®è»¢éã¯longjmpã®åŒã³åºããä»ããŠå®è¡ãããåè©Šè¡ã¯setjmpã®åŒã³åºããçæããŸãã 察å¿ãããããã¡ã¯ãåtryãããã¯ã®ã¹ã¿ãã¯ã«å²ãåœãŠãããŸãã
åé¢æ°ã®æåã«ãçŸåšã®ãã¬ãŒã ãã³ã³ããã¹ãã¹ã¿ãã¯ã«ç»é²ããããããŒã°ãäœæãããŸãã åæ§ã«ãçŸåšã®ã³ã³ããã¹ããã³ã³ããã¹ãã¹ã¿ãã¯ã®æäžéšããåé€ãããšãããŒã°ãäœæãããŸãã ãªãœãŒã¹ãã¯ãªã¢ããããã«ãåé¢æ°ã®é£ã«ãã«ããŒã³ãŒããäœæãããŸãã
ããæ£ç¢ºã«ã¯ãã³ã³ãã€ã©ãŒã¯ãäŸå€ãšããŠçµäºããå¯èœæ§ã®ããé¢æ°ããã®æ»ããããŒãšããŠããªãŒã«èšé²ããŸããå€ã¯ã¯ãªãŒãã³ã°ã³ãŒããžã®ãã€ã³ã¿ãŒã§ãããé¢æ°ã®ã³ã³ããã¹ããã¯ãªã¢ããã«ã¯ãã®å Žæã§ååŸããå¿ èŠããããŸãã ãªã³ã«ã¯ãåãªã³ã¯ã¢ãžã¥ãŒã«ã®ãããã®ããªãŒã®æçãåäžã®ãããžã§ã¯ãããªãŒã«åéããŸãïŒéåžžã«å€§éæã§ãïŒã ãã®å¥è·¡ã¯LSDAïŒèšèªåºæã®ããŒã¿é åïŒãšåŒã°ããããgcc_except_tableãã»ã¯ã·ã§ã³ã«ãããŸãã
ã¹ããŒãããäŸå€ã®type_infoã«åºã¥ããŠäŸå€ãçºçããå Žåããã®äŸå€ãåŠçã§ãããããã¯ãæ€çŽ¢ãããŸãã çŸåšã®ã³ã³ããã¹ããããã³ãã©ã³ã³ããã¹ããŸã§ïŒåŒã³åºããã¬ãŒã ã®ããã²ãŒã·ã§ã³ã䜿çšïŒãã³ãŒãã®ã¢ãã¬ã¹ãæœåºãããŠå®è¡ãããŸãïŒããŒã«ã«å€æ°ã®ã¹ã³ãŒãã«å¿ããŠïŒãã®å Žæã§å®è¡ããå¿ èŠããããŸãã 次ã«ãå¶åŸ¡ã転éãããŸãã
ãã®æ¹æ³ã¯éåžžã«é«äŸ¡ã§ãããšããå å ¥èŠ³ããããŸãã ãã§ã«ããã¹ãŠã®tryãããã¯ã«å¯ŸããŠsetjmpãåŒã³åºãããŠãããšããäºå®ã«ãããŸãããããã¯å®ãã¯ãããŸããã å®éãããã»ããµã®ç¶æ ãå®å šã«ç¶æããå¿ èŠããããŸãããã®å Žåãæ°ååã®ã¬ãžã¹ã¿ãååšããå¯èœæ§ããããŸãã äžæ¹ãäŸå€ã®æç¹ã§ã¯ããããã®ã¬ãžã¹ã¿ã®ã»ãšãã©ã®å 容ã¯ãã§ã«åœ¹ã«ç«ããªãã å®éã«ã¯ãã³ã³ãã€ã©ã¯éåžžã«åççã«æ©èœããŸãã 圌ã¯setjmpããããã€ããæçšãªã¬ãžã¹ã¿ãŒã®ã¿ãä¿åããŸãïŒãã§ã«ãã®æ å ±ãæã£ãŠããŸãïŒã èè ã¯ãsetjmpã®ã³ã¹ããéåžžã«é«ãããšãçã£ãŠããŸãã
ããããæ¬åœã«ç®ãåŒãã®ã¯ãç¹ã«éèŠãªå Žåã«ãèšå€§ãªè£å©ã³ãŒãã§ãã ã³ã³ãã€ã©ã¯ãYACCãšåæ§ã«ãã¹ã¿ãã¯ãã·ã³ã®ãã¹ãŠã®ç¶æ ããã€ã³ãããŸãã ãããŠãå¯èœã§ããã°ããªããã£ãã€ã¶ãŒã¯åé·æ§ãšç°¡åãªã³ãŒããã¯ãªãŒã³ã¢ããããŸãããæ®ã£ãŠããã®ã¯åå以äžã§ãã
- GCC / DW2 ããã¯ãäŸå€åŠçã®æåã®ã¢ãããŒãã®äŸã«ãããŸããã DW2ã¯ãDWARF2ïŒçŸåš3ã€æ¢ã«ïŒ-å®è¡å¯èœãã¡ã€ã«å
ã®ãããã°æ
å ±ãå«ããè£å©æ
å ±ãæ ŒçŽããããã®åœ¢åŒãæå³ããŸãã çµå±ããããã°æ
å ±ãå¿
èŠã§ããããã以åã®ïŒäžäœã®ïŒåŒã³åºãã®ãã¬ãŒã å
ãå«ããå€æ°ã®å€ããã€ã§ãèŠã€ããããšãã§ããŸãã ãããã£ãŠãã³ãŒãçæã®ããã»ã¹ã§ã¯ãã³ã³ãã€ã©ãŒã¯ãå€æ°ãæ ŒçŽãããšãã«ãå€æ°ãé
眮ããã¹ã¿ãã¯ã«å²ãåœãŠããã®ã«é¢ããæ
å ±ã延æããŸã...å®éããã®åœ¢åŒã¯DWARFãšéåžžã«äŒŒãŠããŸãããDWARFãšåäžã§ã¯ãããŸããã GCCã®4çªç®ã®ããŒãžã§ã³ã®æšæºã
æŠå¿µçã«ã¯ãåŒã³åºãã®äžäœãã¬ãŒã ã«å ¥ãæ¹æ³ã«é¢ããæ å ±ã¯ãããã°ã©ã ã³ãŒãã®åã¢ãã¬ã¹ã«æ ŒçŽãããŸãã å®éã«ã¯ããã®æ å ±ã®éãå€ããããå§çž®ãããŸããå®éããã€ãã³ãŒãã®è§£éã䜿çšããŠèšç®ãããŸãã ãã®ãã€ãã³ãŒãã¯ãäŸå€ãçºçãããšãã«å®è¡ãããŸãã ãããã¯ãã¹ãŠã.eh_frameãããã³ã.eh_frame_hdrãã»ã¯ã·ã§ã³ã«ãããŸãã
ã¯ãããšããããDWARFã€ã³ã¿ãŒããªã¿ãŒã¯åªããããã¯ãã¢ã§ããããã®å©ãã«ããããã€ãã³ãŒããå€æŽããããšã§ãäŸå€ããã£ããããã©ãã«ã§ãåŠçã®ããã«éä¿¡ã§ããŸãã
GCC / DW2ã¯ãGCC / SJLJãšã»ãŒåãLSDAã»ã¯ã·ã§ã³ã䜿çšããŸãã
ã芧ã®ãšãããã¹ã¿ãã¯ããã¢ãŒã·ã§ã³ã«é¢é£ããã³ã¹ãïŒäŸå€ããªãå ŽåïŒã¯å®è³ªçã«ãããŸããã ãã ããäŸå€ãçºçãããã³ã¹ãã¯é«ããªããŸãã ããã«ãã³ã³ãã€ã©ãŒã®ã¢ãŒããã¯ãã£ãŒäŸåéšåãšãã®ããªãé«ã¬ãã«ã®ã¬ã€ã€ãŒã®åŒ·åãªçµ±åã«æ³šæããããšã¯ééããããŸããã
- MS VC ++ ã ãã®ã³ã³ãã€ã©ã¯ã2çªç®ã®åŠçæŠç¥ãå®è£
ããŠããŸãã
- æœåšçã«äŸå€ãã¹ããŒããå¯èœæ§ã®ããåé¢æ°ã«å¯ŸããŠãã³ã³ãã€ã©ãŒã¯ãã¹ã¿ãã¯å€æ°ãšããŠã以åã®é¡äŒŒæ§é ãžã®ãã€ã³ã¿ãŒããã®æ§é ããã³ãã©ãŒé¢æ°ã®ã¢ãã¬ã¹ãããã³è£å©ããŒã¿ãäœæããŸãã ãã®æ§é ã®ã¢ãã¬ã¹ã¯FSã«å ¥åãããŸãïŒ[0]ããããã®æ§é ã®ã¹ã¿ãã¯ã®æäžéšã§ãã Win32ã®FSã¬ãžã¹ã¿ã¯ãã¹ã¬ããæ å ±ãããã¯ïŒ TIB ïŒïŒWin64ã®GSïŒãšããŠäœ¿çšãããŸãã ãŸãããã³ãã©ãŒé¢æ°ïŒç¬èªã®ããŒã¿ã»ããã䜿çšïŒãšãFSã埩å ãããšãããŒã°ãäœæããŸãïŒ[0]æåããå Žåã
- ã³ã³ãã€ã©ãŒã¯ãé¢æ°å ã®åtryãããã¯ã®èŠçŽ ããšã«æ§é ã®ããŒãã«ãäœæããŸãã åtryãããã¯ã«ã¯ãç¹å®ã®ç¶æ ã«å¯Ÿå¿ãããã®ããŒãã«ã®éå§ã€ã³ããã¯ã¹ãšçµäºã€ã³ããã¯ã¹ãããïŒãã¹ãããããããã¯ã«ã¯ãã¹ããããééããããŸãïŒãã³ã³ãã€ã©èªäœããã®ã€ã³ããã¯ã¹ã®é¢é£æ§ãç£èŠããŸãã ãã®ããã«ããŠãã³ã³ãã€ã©ãŒã¯tryãããã¯ã®ã¹ã¿ãã¯ãå®è£ ããŸãã
- åtry-blockã«ã€ããŠãcatch-blockããŒãã«ãéå§ãããŸãã äŸå€ã®ã¿ã€ãããšã«ããã®ã¿ã€ãã®äŸå€ã®éå±€å ã®ãã¹ãŠã®åºæ¬ã¯ã©ã¹ã«å¯ŸããŠtype_infoããŒãã«ãäœæãããŸãã
- é¢æ°ããšã«ã¢ã³ã¯ã€ã³ãããŒãã«ãäœæããããã®åèŠçŽ ã«ã¯ãäžéšã®ãªãœãŒã¹ãšåã®èŠçŽ ã®æ°ã解æŸããé¢æ°ãžã®ãã€ã³ã¿ãå«ãŸããŸãã ãã¹ãã©ã¯ã¿ãæã€ãªããžã§ã¯ãã®ã¹ã³ãŒãã«å¿ããŠãããŒãã«ã«ã¯ããã€ãã®ãã§ãŒã³ããããŸãã äŸå€ã®æç¹ã§ãäžèšã®çŸåšã®ç¶æ ã®ã€ã³ããã¯ã¹ã«ãã£ãŠãå¿ èŠãªãã§ãŒã³ãèŠã€ããŠãå¿ èŠãªãã¹ãŠã®ãã¹ãã©ã¯ã¿ãåŒã³åºãããšãã§ããŸãã
- ããŒãžã§ã³x64ã§ã¯ãå¯èœã§ããã°ãè£å©ã¹ã¿ãã¯æ§é ã.pdataã«è»¢éãããŸãã;ãããããMSã¯æåã®æŠç¥ãããææã§ãããšèããŠããŸãã
- äŸå€ãã¹ããŒããããšãäž»ãªäœæ¥ã¯ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠå®è¡ãããSYSENTERãä»ããŠå¶åŸ¡ãååŸãããŸãã
- äŸå€ãçºçãããã©ãã§ãé©åãªcatchãããã¯ãéžæããããã»ã¹ã¯ãã»ãŒåãããã«èŠããŸãã
- äŸå€ãã¹ããŒããããšããªããžã§ã¯ãã®ã³ããŒãtype_infoããã¹ãã©ã¯ã¿ãžã®ãã€ã³ã¿ãå«ãèšè¿°åãäœæãããŸã
- tryãããã¯ã®ã¹ã¿ãã¯ã«æ²¿ã£ãŠäžæããç»é²ãããŠãããã¹ãŠã®ã¹ã¿ãã¯ãªããžã§ã¯ããã¯ãªã¢ããŸãïŒãã®ã¹ã¿ãã¯ã®ããã²ãŒã·ã§ã³ã¯ã©ãã§ãç°ãªããŸãããæ¬è³ªã¯åãã§ãïŒ ãcatchãããã¯ã®ãªã¹ãã調ã¹ãŠãé©åãªãã®ãæ¢ããŸãã
- é©åãªcatchãããã¯ãèŠã€ãã£ãå ŽåãäŸå€ãªããžã§ã¯ãã¯ããŒã«ã«å€æ°ã«ãªããŸã;ãã®ãããã¯ãåŒã³åºããŸãã catchãããã¯ãåç §ã§ã¯ãªãå€ã«ããäŸå€ãåãåãå Žåããã®ã³ããŒãäœæãããŸãã
- äŸå€ã®ååŒã³åºãããªãã£ãå Žåããªããžã§ã¯ãã匷å¶çµäºããŸã-äŸå€
- ãã¡ã¢ãžã®æ人ãïŒ
äœåãªã³ããŒã³ã³ã¹ãã©ã¯ã¿/ãã¹ãã©ã¯ã¿ãçæããŸãsome_exception exc("oioi"); throw exc;
throw *new some_exception("oioi");
catch(some_exception exc) ...
catch(const some_exception *exc) ...
throw some_exception("oioi"); ... catch (const some_exception &exc)....
ããã...
ãããŠãããã¯ãã¹ãŠã§ãããããããããšã®ããã«æããŸã-æ»äœããã§ã«ååšãããã¹ãã©ã¯ã¿ãæ£ããé åºã§åŒã³åºãããšã§ãã åçŽã§äžè¬çãªã¿ã¹ã¯ã«ãç²æ§ããããéããããã«ã¯ç¬èªã«éçºããããœãªã¥ãŒã·ã§ã³ãããã®ã¯ã©ãããŠã§ããïŒ èšãã®ã¯é£ããã®ã§ãæŽå²çã«ã
ãœãªã¥ãŒã·ã§ã³ãç°¡åã«èª¬æããå¯èœãªå Žåã¯ã¢ãŒããã¯ãã£ã«äŸåããªãããã«ããŸãã
- ãŸããæŠç¥ãéžæããŸã-ããã2çªç®ã®ãªãã·ã§ã³ã«ãªããŸãã
- ã³ã³ãããŒã«è»¢é-setjmp / longjmp
- æ§é äœãäœæããŸãããã®åå«ã¯ãã¹ãŠãå¯èœãªæé²ã«èªå·±ç»é²ããããšãã§ããŸãã
struct unw_item_t { unw_item_t (); virtual ~unw_item_t (); void unreg(); unw_item_t *prev_; };
- ãããŠãã1ã€ãã¹ã³ãŒãã¯tryãããã¯ã§ã
struct jmp_buf_splice { jmp_buf_splice (); ~jmp_buf_splice (); jmp_buf buf_; jmp_buf_splice *prev_; unw_item_t objs_; };
- ç°¡åã«ããããã«ãconst char *äŸå€ã®ã¿ãã¹ããŒããŸãã
extern int throw_slice (const char *str);
- tryãããã¯ãã·ãã¥ã¬ãŒãããããã®ããã€ãã®ãã¯ã
// #define TRY_BLOCK { \ jmp_buf_splice __sl; \ const char *__exc = (const char *)setjmp (__sl.buf_); \ if (NULL == __exc) { ... // - catch(âŠ) .. const char* #define CATCH_BLOCK_FIN \ } else { ... // #define FIN_BLOCK \ } \ } ... // #define THROW_IN_BLOCK(exc) \ throw_slice (exc); ... // , __exc TRY_BLOCK #define RETHROW_IN_BLOCK \ throw_slice (__exc);
- jmp_buf_spliceã¯ã©ã¹ã®ã¡ã³ããŒã®ããã£ã衚瀺ããŸãã
static jmp_buf_splice *root_slice_ = NULL; jmp_buf_splice::jmp_buf_splice () { objs_ = NULL; prev_ = root_slice_; root_slice_ = this; } jmp_buf_splice::~jmp_buf_splice () { root_slice_ = prev_; }
- unw_item_tã¯ã©ã¹ã®ã¡ã³ããŒã®æãæ¥ãŸããïŒ
unw_item_t::unw_item_t () { if (NULL != root_slice_) { prev_ = root_slice_->objs_; root_slice_->objs_ = this; } } unw_item_t::~unw_item_t () { unreg(); } unw_item_t::unreg () { if (NULL != root_slice_ && (prev_ != reinterpret_cast<unw_item_t *>(~0))) { root_slice_->objs_ = prev_; prev_ = reinterpret_cast<unw_item_t *>(~0); } }
- 次ã«ãäŸå€ãçºçãããŠã¹ã¿ãã¯ãææ Œãããããã»ã¹ãæ€èšããŸãã
static int pop_slice () { jmp_buf_splice *sl = root_slice_; assert (NULL != sl); root_slice_ = sl->prev_; return 0; } int throw_slice (const char *str, bool popstate) { if (NULL == str) return -1; jmp_buf_splice *sl = root_slice_; unw_item_t *obj = root_slice_->objs_; while (NULL != obj) { unw_item_t *tmp = obj; obj = obj->prev_; tmp->~unw_item_t (); } if (popstate) pop_slice (); longjmp (sl->buf_, int(str)); return 0; }
- ãµãŒãã¹ã¯ã©ã¹-stdã®ã¢ããã°:: auto_ptrïŒ
template<typename cl> class deleter_t : public unw_item_t { public: deleter_t (cl *obj){ptr_ = obj;}; virtual ~deleter_t () {delete ptr_;}; private: cl *ptr_; deleter_t (); deleter_t (const deleter_t &); deleter_t &operator= (const deleter_t &); };
- ãµãŒãã¹ã¯ã©ã¹-é åïŒ
template<typename cl> class vec_deleter_t : public unw_item_t { public: vec_deleter_t (cl *obj){ptr_ = obj;}; virtual ~ vec_deleter_t () {delete [] ptr_;}; private: cl *ptr_; vec_deleter_t (); vec_deleter_t (const vec_deleter_t &); vec_deleter_t &operator= (const vec_deleter_t &); };
- äŸã ãã¹ãã¯ã©ã¹
class _A { public: _A():val_(++cnt_){printf ("A::A(%d)\n",val_);} _A(int i):val_(i){printf ("A::A(%d)\n",val_);} virtual ~_A(){printf ("A::~A(%d)\n",val_);} static int cnt_; }; int _A::cnt_ = 0; class A : public unw_item_t, _A {};
- äŸ1
A a(1); TRY_BLOCK { A b(2); THROW_IN_BLOCK("error\n"); std::cerr << "notreached\n"; } CATCH_BLOCK_FIN { std::cerr << __exc; } FIN_BLOCK;
A :: AïŒ1ïŒ
A :: AïŒ2ïŒ
A ::ãAïŒ2ïŒ
ãšã©ãŒ
A ::ãAïŒ1ïŒ
- äŸ2
A a(1); TRY_BLOCK { A b(2); TRY_BLOCK { A c(3); THROW_IN_BLOCK("error\n"); std::cerr << "notreached\n"; } CATCH_BLOCK_FIN { std::cerr << "." << __exc; RETHROW_IN_BLOCK; } FIN_BLOCK; std::cerr << "notreached\n"; } CATCH_BLOCK_FIN { std::cerr << ".." << __exc; } FIN_BLOCK;
A :: AïŒ1ïŒ
A :: AïŒ2ïŒ
A :: AïŒ3ïŒ
A ::ãAïŒ3ïŒ
.error
A ::ãAïŒ2ïŒ
..ãšã©ãŒ
A ::ãAïŒ1ïŒ
- äŸ3
TRY_BLOCK { vec_deleter_t<_A> da(new _A[3]); TRY_BLOCK { THROW_IN_BLOCK("error\n"); std::cerr << "notreached\n"; } CATCH_BLOCK_FIN { std::cerr << "." << __exc; RETHROW_IN_BLOCK; } FIN_BLOCK; std::cerr << "notreached\n"; } CATCH_BLOCK_FIN { std::cerr << ".." << __exc; } FIN_BLOCK;
A :: AïŒ1ïŒ
A :: AïŒ2ïŒ
A :: AïŒ3ïŒ
.error
A ::ãAïŒ3ïŒ
A ::ãAïŒ2ïŒ
A ::ãAïŒ1ïŒ
..ãšã©ãŒ
å¶éäºé
ãã®ãœãªã¥ãŒã·ã§ã³ã«ã¯å€ãã®æ¬ ç¹ããããŸãã
- ãã¹ãã©ã¯ã¿ã§äŸå€ãã¹ããŒããããšã¯ã§ããŸããã unw_item_tãã¹ãã©ã¯ã¿ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãžã®ãªã³ã¯ããŸã åé€ããŠããŸããããã®çµæããã¹ãã©ã¯ã¿ãå床åŒã³åºãããŸãã
- newæŒç®åã䜿çšããŠunw_item_tããç¶æ¿ããã¯ã©ã¹ã®ãªããžã§ã¯ããäœæããããšã¯éåžžã«å±éºã§ãã ã¡ã¢ãªèªäœã管çããŠããå Žåã§ãããã®ãããªãã€ã³ã¿ã¯å€éšã®ã³ã³ããã¹ããŸãã¯å€éšã®ã¹ããªãŒã ã«èœã¡ãå¯èœæ§ããããèŠãŠãããªããžã§ã¯ããçªç¶ãã¹ãã©ã¯ã¿ãåŒãèµ·ããã代è¬å€§æšäºãåŒãèµ·ããå¯èœæ§ããããŸãã
- unw_item_tããç¶æ¿ãããã¯ã©ã¹ãå¥ã®ã¯ã©ã¹ã®ã¡ã³ããŒãšããŠéçŽããããšã¯ã§ããŸãããããããªããšããã®ãã¹ãã©ã¯ã¿ãŒã2ååŒã³åºãããŸãã
- 説æãããŠããæ¹æ³ã¯ãããŒããŠã§ã¢äŸå€ãšçµ±åã§ããŸããã
- äŸå€ã¿ã€ãã®å¶éã äžèšã§ã¯ãæååãã€ã³ã¿ã®ã¿ã䜿çšããŸããã ããªããã£ãåãäŸå€ãšããŠæž¡ãå Žåãéžæè¢ã¯1ã€ã ãã§ãã ãªããžã§ã¯ããã€ã³ã¿ãŒãäŸå€ãšããŠäœ¿çšããå ŽåãRTTIã䜿çšã§ããŸãã 次ã®ãããªææ¡ãã§ããŸã
#define CATCH_BLOCK_TYPED(t) \ } else if (NULL != dynamic_cast<t>(__exc)) {
- ãŠãŒã¶ãŒã¯ãã¹ããŒãããäŸå€ãªããžã§ã¯ããåé€ããå¿ èŠããããŸãã
ãããŠãŸã ã
説æãããŠããå¶éã«ããããããã説æãããŠããæ¹æ³ã«ã¯åºæã®å©ç¹ããããŸãã
- ã·ã³ãã«ã æ°åè¡ã®ã³ãŒã-ãã¹ãŠãæ©èœããŸãã
- éææ§ã®ã³ã³ã»ããã
- ç°¡åãªæºåž¯æ§ã ã¢ãŒããã¯ãã£ã«äŸåããŸããã
èè ã¯äœã§é転ããŠããŸããïŒ
æè¡çãªããåŠã®é åºã§ãäžèšã®ã¹ããŒã ãæ£ããå®è£ ããããã«ã³ã³ãã€ã©ãå€æŽããæ¹æ³ã«ã€ããŠèããŸããïŒ
äžèšã®ãœãªã¥ãŒã·ã§ã³ã«ã¯äœãæ¬ ããŠããŸãããïŒ ãªããžã§ã¯ãã®çææ¹æ³ã«é¢ããç¥èã
ããšãã°ããªããžã§ã¯ããå ±éããŒãããå²ãåœãŠãããã¡ã¢ãªäžã«æ§ç¯ãããã¹ã¬ããéã§ç§»è¡ã§ããå Žåãã¹ããªãŒã äŸåã¹ã¿ãã¯ã«æ±ºããŠç»é²ãããã¹ãã§ã¯ãããŸããã å¥ã®ãªããžã§ã¯ãã«éçŽããããªããžã§ã¯ããã©ãã«ãç»é²ããªãã§ãã ããã
ãããŠãåãã¿ã€ãã®ãªããžã§ã¯ãã䜿çšããŸãããã¹ã¿ãã¯ã¡ã¢ãªäžã§ããããè¡ãå¿ èŠããããŸãã ãã¡ããããã®ã¹ã¿ãã¯ãªããžã§ã¯ããžã®ãã€ã³ã¿ãå¥ã®ã¹ã¬ããã«æž¡ãããšã¯å¯èœã§ãããã©ã®ãããªç¶æ³ã§ããã圹ç«ã€ãæ³åããããšã¯å°é£ã§ãã
ã ããïŒ
- ã¿ã€ãTã®ã¹ã¿ãã¯ãªããžã§ã¯ãã®å Žåãã³ã³ãã€ã©ã¯å®éã«ã¿ã€ãã®ã©ãããŒã¯ã©ã¹ãäœæããŸã
template<class T> class __st_wrapper : public unw_item_t { public: virtual ~__st_wrapper() { unreg(); ((T*)data_)->T::~T(); }; private: char data_[sizeof(T)]; };
- jmp_buf_splice :: root_slice_ã¯ã©ã¹ã®éçã¡ã³ããŒã¯ãTLSãŸãã¯å¯Ÿå¿ããã¬ãžã¹ã¿ïŒååšããå ŽåïŒãä»ããŠå®è£ ãããŸãã
- ããã°ã©ããŒã¯ã data_ã«ããã¿ã€ãTã®ãªããžã§ã¯ãã®ã¿ãèŠãŠããŸãã
- ä»®æ³ãã¹ãã©ã¯ã¿ã®ãªãã¹ã¿ãã¯ãªããžã§ã¯ãã®å Žåãããã¯ã©ãããŒã«è¡šç€ºãããŸã
- ãã¹ãã©ã¯ã¿ã§äŸå€ãã¹ããŒã§ããããã«ãªããŸãã ãã¹ãã©ã¯ã¿èªäœãåŒã³åºãåã«ãç»é²ã解é€ããŸããã
- ããŒããŠã§ã¢äŸå€ïŒã«ãŒãã«äŸå€ïŒã¯ãµããŒããããŠããªããããäŸå€ãã¹ããŒãããæç¹ã§ãã³ã³ãã€ã©ãŒã¯ã©ã®ã¬ãžã¹ã¿ãŒããçéžããããå¿ èŠãããããèªèããããããå¿ èŠããããŸãã
- ã¹ã¿ãã¯ãªããžã§ã¯ããå®æçã«ç Žæ£ããããã«ãã³ã³ãã€ã©ã¯__st_wrapperã®ãã¹ãã©ã¯ã¿ãŒãžã®åŒã³åºããäœæããŸã
- é©åãªcatchãããã¯ãéžæããããã®ã¡ã«ããºã ã¯ãã®ãŸãŸã§ãã ã€ãŸã ãããã®ãããã¯ã®èšè¿°åãã³ãŒãå€ã«ããè£å©ããŒãã«æ å ±ãå¿ èŠã§ãã
- setjmpã®ã¢ããã°ã䜿çšããŠå¶åŸ¡ã移è¡ããŸãã äžéïŒäžèšã®2ã€ã«é¢ããŠïŒã³ã³ãããŒã«è»¢éãªãã·ã§ã³ãå®è£
ããããšãææ¡ããŸãã Setjmpã«ã¯é倧ãªæ¬ ç¹ããããŸã-ãããã¡ãµã€ãºã¯éåžžã«å€§ãããå®éã«ã¯å°ããªéšåã䜿çšãããŸãã
äžæ¹ãDWARFãã€ãã³ãŒãã®å®è¡ã¯éåžžã«ç¡é§ãå€ãããã§ãã
ãããã£ãŠãsetjmpãããã¡ãŒã®ä»£ããã«ãå®éã®å€ãããã¹ã¿ãã¯ãã€ã³ã¿ãŒãåºæºã«ããå埩ãšã·ãããå¿ èŠãšããã¬ãžã¹ã¿ãŒã®ãªã¹ããæ ŒçŽããŸãã èšç®å€ã®å Žåãå€ã¯ã¬ãžã¹ã¿ã«çŽæ¥æ ŒçŽãããŸãã ãããè¡ãã«ã¯ãè¿œå ã®ã¡ã¢ãªãã¹ã¿ãã¯ã«å²ãåœãŠãããããã«ã·ãããäžããããŸãã å®éãäžæå€æ°ãéå§ãããŸãã
ã³ã³ãã€ã©ãŒã¯ãäŸå€ãçºçãããåã«ãé¢é£ãããã¹ãŠã®ããŒã¿ãã¬ãžã¹ã¿ãŒããã¢ã³ããŒãããŸãããã®å Žåãæ倱ãªã埩å ã§ããŸãã
ããã§ãã tryãããã¯ã®äœ¿çšã¯æèçãªè¡çºã§ããããšã«æ³šæãã䟡å€ããããŸããããã«ã¯äžå®ã®ã³ã¹ãã䌎ããšããäºå®ã«ã¯äœã®åé¡ããããŸããã ç§èŠãããã®ïŒäžçšåºŠã®ïŒã³ã¹ãã¯ããã«äŸ¿å©ã§ã èšèªããŒã«ã«å¯Ÿãã責任ããæ 床ãåºæ¿ããŸãã
- æŒç®ånewãšnew []ãåŒã³åºããšãã«ãã£ããããäŸå€ã¯ãã®ãŸãŸæ®ãããŸãã ã€ãŸã åtryãå éštryãããã¯ã§ä¿è·ããäŸå€ãçºçããå Žåã¯ä»¥åã®ã€ãã¬ãŒã·ã§ã³ã§äœæããããã¹ãŠãç Žæ£ããŸãã ãããŠããã¡ããããªããžã§ã¯ãã«å²ãåœãŠãããã¡ã¢ãªãè¿ããŸã[sã]
- ã¹ã¿ãã¯ãªããžã§ã¯ãã®é åãå®è£ ããããã«äœãããå¿ èŠã¯ãããŸããã ãã ããç¹å¥ãªã¹ã¿ãã¯ãªããžã§ã¯ãïŒ new []æŒç®åãåŒã³åºããšãã«äœ¿çšããããã¯ãã«ãšåæ§ã®ãã¯ãã«ïŒãå®è£ ããããšã«ãããã¡ã¢ãªãç¯çŽã§ããŸãã
ãšããã§ã
- ãªããžã§ã¯ãã¯ãã¹ã¿ãã¯ã§ããããšã確èªã§ããŸãã ãããè¡ãã«ã¯ã ããã¯çŸåšã®ã¹ã¬ããã®ã¹ã¿ãã¯ã»ã°ã¡ã³ãå ã«ãªããã°ãªããŸããã
- ããã¯ãããªããžã§ã¯ããåé€ã§ããŸããïŒ ãªããããå¿ èŠãªã®ãæ³åã§ããŸãããããã®ãããªæ©äŒããããŸãã
- ããªãããããè±ãããšãã§ãããªããããªãã¯ãããæ€ããããšãã§ããŸãã allocaãä»ããŠã¹ã¿ãã¯ã«ã¡ã¢ãªãå²ãåœãŠãã³ã³ã¹ãã©ã¯ã¿ãŒã匷å¶çã«åŒã³åºããŠãã¹ã¿ãã¯ããã¢ãŒã·ã§ã³ã¡ã«ããºã ã«æ¥ç¶ããŸãã
- åå¥ã®ããŒã¿ã¹ã¿ãã¯ãšã³ã³ãããŒã«ã¹ã¿ãã¯ãæã€ã¢ãŒããã¯ãã£ã®å ŽåãäŸå€åŠçã¯ãªã¹ãã®ä»£ããã«ã³ã³ãããŒã«ã¹ã¿ãã¯ã䜿çšããŠéåžžã«å¹ççã«å®è£ ã§ããŸãã
PSïŒæçãªè°è«ãããŠãããAlexander Artyushinã«æè¬ããŸãã