1.. index:: error handling 2 3************** 4Error Handling 5************** 6 7This chapter describes the way that GSL functions report and handle 8errors. By examining the status information returned by every function 9you can determine whether it succeeded or failed, and if it failed you 10can find out what the precise cause of failure was. You can also define 11your own error handling functions to modify the default behavior of the 12library. 13 14The functions described in this section are declared in the header file 15:file:`gsl_errno.h`. 16 17Error Reporting 18=============== 19 20The library follows the thread-safe error reporting conventions of the 21POSIX Threads library. Functions return a non-zero error code to 22indicate an error and :code:`0` to indicate success:: 23 24 int status = gsl_function (...) 25 26 if (status) { /* an error occurred */ 27 ..... 28 /* status value specifies the type of error */ 29 } 30 31The routines report an error whenever they cannot perform the task 32requested of them. For example, a root-finding function would return a 33non-zero error code if could not converge to the requested accuracy, or 34exceeded a limit on the number of iterations. Situations like this are 35a normal occurrence when using any mathematical library and you should 36check the return status of the functions that you call. 37 38Whenever a routine reports an error the return value specifies the type 39of error. The return value is analogous to the value of the variable 40:code:`errno` in the C library. The caller can examine the return code 41and decide what action to take, including ignoring the error if it is 42not considered serious. 43 44In addition to reporting errors by return codes the library also has an 45error handler function :func:`gsl_error`. This function is called by 46other library functions when they report an error, just before they 47return to the caller. The default behavior of the error handler is to 48print a message and abort the program:: 49 50 gsl: file.c:67: ERROR: invalid argument supplied by user 51 Default GSL error handler invoked. 52 Aborted 53 54The purpose of the :func:`gsl_error` handler is to provide a function 55where a breakpoint can be set that will catch library errors when 56running under the debugger. It is not intended for use in production 57programs, which should handle any errors using the return codes. 58 59.. index:: 60 single: error codes, reserved 61 62Error Codes 63=========== 64 65The error code numbers returned by library functions are defined in 66the file :file:`gsl_errno.h`. They all have the prefix :code:`GSL_` and 67expand to non-zero constant integer values. Error codes above 1024 are 68reserved for applications, and are not used by the library. Many of 69the error codes use the same base name as the corresponding error code 70in the C library. Here are some of the most common error codes, 71 72.. index:: 73 single: error codes 74 75.. var:: int GSL_EDOM 76 77 Domain error; used by mathematical functions when an argument value does 78 not fall into the domain over which the function is defined (like 79 :data:`EDOM` in the C library) 80 81.. var:: int GSL_ERANGE 82 83 Range error; used by mathematical functions when the result value is not 84 representable because of overflow or underflow (like :data:`ERANGE` in the C 85 library) 86 87.. var:: int GSL_ENOMEM 88 89 No memory available. The system cannot allocate more virtual memory 90 because its capacity is full (like :data:`ENOMEM` in the C library). This error 91 is reported when a GSL routine encounters problems when trying to 92 allocate memory with :func:`malloc`. 93 94.. var:: int GSL_EINVAL 95 96 Invalid argument. This is used to indicate various kinds of problems 97 with passing the wrong argument to a library function (like :data:`EINVAL` in the C 98 library). 99 100The error codes can be converted into an error message using the 101function :func:`gsl_strerror`. 102 103.. function:: const char * gsl_strerror (const int gsl_errno) 104 105 This function returns a pointer to a string describing the error code 106 :data:`gsl_errno`. For example:: 107 108 printf ("error: %s\n", gsl_strerror (status)); 109 110 would print an error message like :code:`error: output range error` for a 111 status value of :data:`GSL_ERANGE`. 112 113.. index:: error handlers 114 115Error Handlers 116============== 117 118The default behavior of the GSL error handler is to print a short 119message and call :func:`abort`. When this default is in use programs 120will stop with a core-dump whenever a library routine reports an error. 121This is intended as a fail-safe default for programs which do not check 122the return status of library routines (we don't encourage you to write 123programs this way). 124 125If you turn off the default error handler it is your responsibility to 126check the return values of routines and handle them yourself. You can 127also customize the error behavior by providing a new error handler. For 128example, an alternative error handler could log all errors to a file, 129ignore certain error conditions (such as underflows), or start the 130debugger and attach it to the current process when an error occurs. 131 132All GSL error handlers have the type :code:`gsl_error_handler_t`, which is 133defined in :file:`gsl_errno.h`, 134 135.. type:: gsl_error_handler_t 136 137 This is the type of GSL error handler functions. An error handler will 138 be passed four arguments which specify the reason for the error (a 139 string), the name of the source file in which it occurred (also a 140 string), the line number in that file (an integer) and the error number 141 (an integer). The source file and line number are set at compile time 142 using the :code:`__FILE__` and :code:`__LINE__` directives in the 143 preprocessor. An error handler function returns type :code:`void`. 144 Error handler functions should be defined like this:: 145 146 void handler (const char * reason, 147 const char * file, 148 int line, 149 int gsl_errno) 150 151To request the use of your own error handler you need to call the 152function :func:`gsl_set_error_handler` which is also declared in 153:file:`gsl_errno.h`, 154 155.. function:: gsl_error_handler_t * gsl_set_error_handler (gsl_error_handler_t * new_handler) 156 157 This function sets a new error handler, :data:`new_handler`, for the GSL 158 library routines. The previous handler is returned (so that you can 159 restore it later). Note that the pointer to a user defined error 160 handler function is stored in a static variable, so there can be only 161 one error handler per program. This function should be not be used in 162 multi-threaded programs except to set up a program-wide error handler 163 from a master thread. The following example shows how to set and 164 restore a new error handler:: 165 166 /* save original handler, install new handler */ 167 old_handler = gsl_set_error_handler (&my_handler); 168 169 /* code uses new handler */ 170 ..... 171 172 /* restore original handler */ 173 gsl_set_error_handler (old_handler); 174 175 To use the default behavior (:func:`abort` on error) set the error 176 handler to :code:`NULL`:: 177 178 old_handler = gsl_set_error_handler (NULL); 179 180.. function:: gsl_error_handler_t * gsl_set_error_handler_off () 181 182 This function turns off the error handler by defining an error handler 183 which does nothing. This will cause the program to continue after any 184 error, so the return values from any library routines must be checked. 185 This is the recommended behavior for production programs. The previous 186 handler is returned (so that you can restore it later). 187 188The error behavior can be changed for specific applications by 189recompiling the library with a customized definition of the 190:code:`GSL_ERROR` macro in the file :file:`gsl_errno.h`. 191 192.. index:: error handling macros 193 194Using GSL error reporting in your own functions 195=============================================== 196 197If you are writing numerical functions in a program which also uses GSL 198code you may find it convenient to adopt the same error reporting 199conventions as in the library. 200 201To report an error you need to call the function :func:`gsl_error` with a 202string describing the error and then return an appropriate error code 203from :file:`gsl_errno.h`, or a special value, such as :code:`NaN`. For 204convenience the file :file:`gsl_errno.h` defines two macros which carry 205out these steps: 206 207.. macro:: GSL_ERROR (reason, gsl_errno) 208 209 This macro reports an error using the GSL conventions and returns a 210 status value of :code:`gsl_errno`. It expands to the following code fragment:: 211 212 gsl_error (reason, __FILE__, __LINE__, gsl_errno); 213 return gsl_errno; 214 215 The macro definition in :file:`gsl_errno.h` actually wraps the code 216 in a :code:`do { ... } while (0)` block to prevent possible 217 parsing problems. 218 219Here is an example of how the macro could be used to report that a 220routine did not achieve a requested tolerance. To report the error the 221routine needs to return the error code :code:`GSL_ETOL`:: 222 223 if (residual > tolerance) 224 { 225 GSL_ERROR("residual exceeds tolerance", GSL_ETOL); 226 } 227 228.. macro:: GSL_ERROR_VAL (reason, gsl_errno, value) 229 230 This macro is the same as :code:`GSL_ERROR` but returns a user-defined 231 value of :data:`value` instead of an error code. It can be used for 232 mathematical functions that return a floating point value. 233 234The following example shows how to return a :code:`NaN` at a mathematical 235singularity using the :code:`GSL_ERROR_VAL` macro:: 236 237 if (x == 0) 238 { 239 GSL_ERROR_VAL("argument lies on singularity", GSL_ERANGE, GSL_NAN); 240 } 241 242 243Examples 244======== 245 246Here is an example of some code which checks the return value of a 247function where an error might be reported:: 248 249 #include <stdio.h> 250 #include <gsl/gsl_errno.h> 251 #include <gsl/gsl_fft_complex.h> 252 253 ... 254 int status; 255 size_t n = 37; 256 257 gsl_set_error_handler_off(); 258 259 status = gsl_fft_complex_radix2_forward (data, stride, n); 260 261 if (status) { 262 if (status == GSL_EINVAL) { 263 fprintf (stderr, "invalid argument, n=%d\n", n); 264 } else { 265 fprintf (stderr, "failed, gsl_errno=%d\n", status); 266 } 267 exit (-1); 268 } 269 ... 270 271The function :func:`gsl_fft_complex_radix2_forward` only accepts integer lengths 272which are a power of two. If the variable :code:`n` is not a power of 273two then the call to the library function will return :code:`GSL_EINVAL`, 274indicating that the length argument is invalid. The function call to 275:func:`gsl_set_error_handler_off` stops the default error handler from 276aborting the program. The :code:`else` clause catches any other possible 277errors. 278 279