1 /* 2 * %CopyrightBegin% 3 * 4 * Copyright Ericsson AB 1996-2016. All Rights Reserved. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * %CopyrightEnd% 19 */ 20 21 #ifndef __ERROR_H__ 22 #define __ERROR_H__ 23 24 #include "code_ix.h" 25 26 /* 27 * There are three primary exception classes: 28 * 29 * - exit Process termination - not an error. 30 * - error Error (adds stacktrace; will be logged). 31 * - thrown Nonlocal return (turns into a 'nocatch' 32 * error if not caught by the process). 33 * 34 * In addition, we define a number of exit codes as a convenient 35 * short-hand: instead of building the error descriptor term at the time 36 * the exception is raised, it is built as necessary when the exception 37 * is handled. Examples are EXC_NORMAL, EXC_BADARG, EXC_BADARITH, etc. 38 * Some of these have convenient aliases, like BADARG and BADARITH. 39 */ 40 41 /* 42 * Exception class tags (indices into the 'exception_tag' array) 43 */ 44 #define EXTAG_OFFSET 0 45 #define EXTAG_BITS 2 46 47 #define EXTAG_ERROR 0 48 #define EXTAG_EXIT 1 49 #define EXTAG_THROWN 2 50 51 #define NUMBER_EXC_TAGS 3 /* The number of exception class tags */ 52 53 /* 54 * Index to the 'exception class tag' table. 55 */ 56 #define EXC_CLASSBITS ((1<<EXTAG_BITS)-1) 57 #define GET_EXC_CLASS(x) ((x) & EXC_CLASSBITS) 58 59 /* 60 * Exit code flags 61 * 62 * These flags make is easier and quicker to decide what to do with the 63 * exception in the early stages, before a handler is found, and also 64 * maintains some separation between the class tag and the actions. 65 */ 66 #define EXF_OFFSET EXTAG_BITS 67 #define EXF_BITS 8 68 69 #define EXF_PANIC (1<<(0+EXF_OFFSET)) /* ignore catches */ 70 #define EXF_THROWN (1<<(1+EXF_OFFSET)) /* nonlocal return */ 71 #define EXF_LOG (1<<(2+EXF_OFFSET)) /* write to logger on termination */ 72 #define EXF_NATIVE (1<<(3+EXF_OFFSET)) /* occurred in native code */ 73 #define EXF_SAVETRACE (1<<(4+EXF_OFFSET)) /* save stack trace in internal form */ 74 #define EXF_ARGLIST (1<<(5+EXF_OFFSET)) /* has arglist for top of trace */ 75 #define EXF_RESTORE_NFUNC (1<<(6+EXF_OFFSET)) /* restore original bif/nif */ 76 #define EXF_HAS_EXT_INFO (1<<(7+EXF_OFFSET)) /* has arglist for top of trace */ 77 78 #define EXC_FLAGBITS (((1<<(EXF_BITS+EXF_OFFSET))-1) \ 79 & ~((1<<(EXF_OFFSET))-1)) 80 81 /* 82 * The primary fields of an exception code 83 */ 84 #define EXF_PRIMARY (EXF_PANIC | EXF_THROWN | EXF_LOG | EXF_NATIVE) 85 #define PRIMARY_EXCEPTION(x) ((x) & (EXF_PRIMARY | EXC_CLASSBITS)) 86 #define NATIVE_EXCEPTION(x) ((x) | EXF_NATIVE) 87 88 /* 89 * Error code used for indexing into 90 * the short-hand error descriptor table. 91 */ 92 #define EXC_OFFSET (EXF_OFFSET+EXF_BITS) 93 #define EXC_BITS 5 94 95 #define EXC_INDEXBITS (((1<<(EXC_BITS+EXC_OFFSET))-1) \ 96 & ~((1<<(EXC_OFFSET))-1)) 97 98 #define GET_EXC_INDEX(x) (((x) & EXC_INDEXBITS) >> EXC_OFFSET) 99 100 /* 101 * Exit codes used for raising a fresh exception. The primary exceptions 102 * share index 0 in the descriptor table. EXC_NULL signals that no 103 * exception has occurred. The primary exit codes EXC_EXIT, EXC_ERROR 104 * and EXC_THROWN are the basis for all other exit codes, and must 105 * always have the EXF_SAVETRACE flag set so that a trace is saved 106 * whenever a new exception occurs; the flag is then cleared. 107 */ 108 #define EXC_NULL 0 /* Initial value for p->freason */ 109 #define EXC_PRIMARY (0 | EXF_SAVETRACE) 110 #define EXC_ERROR (EXC_PRIMARY | EXTAG_ERROR | EXF_LOG) 111 /* Generic error (exit term 112 * in p->fvalue) */ 113 #define EXC_EXIT (EXC_PRIMARY | EXTAG_EXIT) 114 /* Generic exit (exit term 115 * in p->fvalue) */ 116 #define EXC_THROWN (EXC_PRIMARY | EXTAG_THROWN | EXF_THROWN) 117 /* Generic nonlocal return 118 * (thrown term in p->fvalue) */ 119 120 #define EXC_ERROR_2 (EXC_ERROR | EXF_ARGLIST) 121 /* Error with given arglist term 122 * (exit reason in p->fvalue) */ 123 124 #define EXC_ERROR_3 (EXC_ERROR | EXF_ARGLIST | EXF_HAS_EXT_INFO) 125 /* Error with given arglist term 126 * and extended error info 127 * (exit reason in p->fvalue) */ 128 129 #define EXC_NORMAL ((1 << EXC_OFFSET) | EXC_EXIT) 130 /* Normal exit (reason 'normal') */ 131 #define EXC_INTERNAL_ERROR ((2 << EXC_OFFSET) | EXC_ERROR | EXF_PANIC) 132 /* Things that shouldn't happen */ 133 #define EXC_BADARG ((3 << EXC_OFFSET) | EXC_ERROR) 134 /* Bad argument to a BIF */ 135 #define EXC_BADARITH ((4 << EXC_OFFSET) | EXC_ERROR) 136 /* Bad arithmetic */ 137 #define EXC_BADMATCH ((5 << EXC_OFFSET) | EXC_ERROR) 138 /* Bad match in function body */ 139 #define EXC_FUNCTION_CLAUSE ((6 << EXC_OFFSET) | EXC_ERROR) 140 /* No matching function head */ 141 #define EXC_CASE_CLAUSE ((7 << EXC_OFFSET) | EXC_ERROR) 142 /* No matching case clause */ 143 #define EXC_IF_CLAUSE ((8 << EXC_OFFSET) | EXC_ERROR) 144 /* No matching if clause */ 145 #define EXC_UNDEF ((9 << EXC_OFFSET) | EXC_ERROR) 146 /* No farity that matches */ 147 #define EXC_BADFUN ((10 << EXC_OFFSET) | EXC_ERROR) 148 /* Not an existing fun */ 149 #define EXC_BADARITY ((11 << EXC_OFFSET) | EXC_ERROR) 150 /* Attempt to call fun with 151 * wrong number of arguments. */ 152 #define EXC_TIMEOUT_VALUE ((12 << EXC_OFFSET) | EXC_ERROR) 153 /* Bad time out value */ 154 #define EXC_NOPROC ((13 << EXC_OFFSET) | EXC_ERROR) 155 /* No process or port */ 156 #define EXC_NOTALIVE ((14 << EXC_OFFSET) | EXC_ERROR) 157 /* Not distributed */ 158 #define EXC_SYSTEM_LIMIT ((15 << EXC_OFFSET) | EXC_ERROR) 159 /* Ran out of something */ 160 #define EXC_TRY_CLAUSE ((16 << EXC_OFFSET) | EXC_ERROR) 161 /* No matching try clause */ 162 #define EXC_NOTSUP ((17 << EXC_OFFSET) | EXC_ERROR) 163 /* Not supported */ 164 #define EXC_BADMAP ((18 << EXC_OFFSET) | EXC_ERROR) 165 /* Bad map */ 166 #define EXC_BADKEY ((19 << EXC_OFFSET) | EXC_ERROR) 167 /* Bad key in map */ 168 169 #define NUMBER_EXIT_CODES 20 /* The number of exit code indices */ 170 171 /* 172 * Internal pseudo-error codes. 173 */ 174 #define TRAP (1 << EXC_OFFSET) /* BIF Trap to erlang code */ 175 176 /* 177 * Aliases for some common exit codes. 178 */ 179 #define BADARG EXC_BADARG 180 #define BADARITH EXC_BADARITH 181 #define BADKEY EXC_BADKEY 182 #define BADMAP EXC_BADMAP 183 #define BADMATCH EXC_BADMATCH 184 #define SYSTEM_LIMIT EXC_SYSTEM_LIMIT 185 186 /* 187 * Pseudo error codes (these are never seen by the user). 188 */ 189 #define TLOAD_OK 0 /* The threaded code linking was successful */ 190 #define TLOAD_MAGIC_NUMBER 1 /* Wrong kind of object file */ 191 #define TLOAD_FORMAT 2 /* Format error while reading object code */ 192 #define TLOAD_MODULE 3 /* Module name in object code does not match */ 193 #define TLOAD_SIZE 4 /* Given size in object code differs from actual size */ 194 195 /* 196 * The exception stack trace parameters. 197 */ 198 #define MAX_BACKTRACE_SIZE 64 /* whatever - just not too huge */ 199 #define DEFAULT_BACKTRACE_SIZE 8 200 201 /* 202 * The table translating an exception code to an atom. 203 */ 204 extern Eterm error_atom[NUMBER_EXIT_CODES]; 205 206 /* 207 * The exception tag table. 208 */ 209 extern Eterm exception_tag[NUMBER_EXC_TAGS]; 210 211 /* 212 * The quick-saved stack trace structure 213 */ 214 struct StackTrace { 215 Eterm header; /* bignum header - must be first in struct */ 216 Eterm freason; /* original exception reason is saved in the struct */ 217 ErtsCodePtr pc; 218 const ErtsCodeMFA* current; 219 int depth; /* number of saved pointers in trace[] */ 220 ErtsCodePtr trace[1]; /* varying size - must be last in struct */ 221 }; 222 223 #endif /* __ERROR_H__ */ 224