Why should I know this?

C에서 TRY-CATCH 구현 본문

Technic

C에서 TRY-CATCH 구현

die4taoam 2022. 3. 14. 03:01

Droid knights에서 발표한 "Android Native Module 안정적으로 개발하기" 내용 중에 내가 만든 TRY-CATCH 매크로를 공유했었는데 대충 이런식이었다.

void do_signal_handling()
{
    int sig = 0;
    int watch_signals = sigill | sigtrap | sigabrt | sigbus | sigsegv;
    fprintf(stderr, "fn size : %lx\n", get_func_size((unsigned long)&do_segv));
    TRY(sig, watch_signals, do_segv1) {
        do_segv1();
    }
    CATCH (sig, sigsegv, e) {
        fprintf(stderr, "inside catch!!\n");
        fprintf(stderr, "catch!! signal %d\n", sig);
        fprintf(stderr, "exception code: %d addr: %lx \n", e.code, e.addr);
    }
    FINAL(watch_signals);
}

 

최근에 GDB 내에 구현한 코드를 우연히 찾아 공유함.

/* Macro to wrap up standard try/catch behavior.

   The double loop lets us correctly handle code "break"ing out of the
   try catch block.  (It works as the "break" only exits the inner
   "while" loop, the outer for loop detects this handling it
   correctly.)  Of course "return" and "goto" are not so lucky.

   For instance:

   *INDENT-OFF*

   TRY_SJLJ
     {
     }
   CATCH_SJLJ (e, RETURN_MASK_ERROR)
     {
       switch (e.reason)
         {
           case RETURN_ERROR: ...
         }
     }
   END_CATCH_SJLJ

   The SJLJ variants are needed in some cases where gdb exceptions
   need to cross third-party library code compiled without exceptions
   support (e.g., readline).  */

#define TRY_SJLJ \
     { \
       jmp_buf *buf = \
         exceptions_state_mc_init (); \
       setjmp (*buf); \
     } \
     while (exceptions_state_mc_action_iter ()) \
       while (exceptions_state_mc_action_iter_1 ())

#define CATCH_SJLJ(EXCEPTION, MASK)                             \
  {                                                     \
    struct gdb_exception EXCEPTION;                             \
    if (exceptions_state_mc_catch (&(EXCEPTION), MASK))

#define END_CATCH_SJLJ                          \
  }

 

출처 - https://sourceware.org/git?p=binutils-gdb.git;a=blob;f=gdbsupport/common-exceptions.h;h=b7e6f2dd7ca2c28d6f2222071ba6b4faa04f8011;hb=HEAD#l227 

 

sourceware.org Git - binutils-gdb.git/blob - gdbsupport/common-exceptions.h

1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger. 3 Copyright (C) 1986-2022 Free Software Foundation, Inc. 5 This file is part of GDB. 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU G

sourceware.org

다음 커밋 참고

commit 284e6217cf8f96c7648b13274431dcf73aa084a9 (HEAD)
Author: Pedro Alves <palves@redhat.com>
Date:   Sat Mar 7 14:50:03 2015 +0000

    kill volatile struct gdb_exception

    After the previous patch, this is the last remaining use of a volatile
    struct gdb_exception.  Kill it, as it's troublesome for C++: we can't
    assign volatile <-> non-volatile without copy constructors /
    assignment operators that do that, which I'd rather avoid.

    gdb/ChangeLog:
    2015-03-07  Pedro Alves  <palves@redhat.com>

            * main.c (handle_command_errors): Remove volatile qualifier from
            parameter.

 

 

 

 

Comments