diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | gpgscm/ffi.c | 1 | ||||
-rw-r--r-- | gpgscm/main.c | 1 | ||||
-rw-r--r-- | gpgscm/scheme.c | 3 | ||||
-rw-r--r-- | src/estream-printf.c | 13 | ||||
-rw-r--r-- | src/estream.c | 17 | ||||
-rw-r--r-- | src/gpg-error.def.in | 3 | ||||
-rw-r--r-- | src/gpg-error.h.in | 6 | ||||
-rw-r--r-- | src/gpg-error.vers | 3 | ||||
-rw-r--r-- | src/gpgrt-int.h | 4 | ||||
-rw-r--r-- | src/init.c | 79 | ||||
-rw-r--r-- | src/logging.c | 21 | ||||
-rw-r--r-- | src/posix-lock.c | 18 | ||||
-rw-r--r-- | src/spawn-posix.c | 1 | ||||
-rw-r--r-- | src/spawn-w32.c | 1 | ||||
-rw-r--r-- | src/visibility.c | 16 | ||||
-rw-r--r-- | src/visibility.h | 4 | ||||
-rw-r--r-- | src/w32-estream.c | 9 | ||||
-rw-r--r-- | src/w32-lock.c | 6 |
19 files changed, 161 insertions, 50 deletions
@@ -1,6 +1,11 @@ Noteworthy changes in version 1.34 (unreleased) [C25/A25/R_] ----------------------------------------------- + * Interface changes relative to the 1.33 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgrt_abort NEW. + gpgrt_add_emergency_cleanup NEW. + Noteworthy changes in version 1.33 (2018-12-07) [C25/A25/R0] ----------------------------------------------- diff --git a/gpgscm/ffi.c b/gpgscm/ffi.c index 578c68d..2067b0d 100644 --- a/gpgscm/ffi.c +++ b/gpgscm/ffi.c @@ -19,7 +19,6 @@ #include <config.h> -#include <assert.h> #include <ctype.h> #include <dirent.h> #include <errno.h> diff --git a/gpgscm/main.c b/gpgscm/main.c index 22c7c98..07d8e07 100644 --- a/gpgscm/main.c +++ b/gpgscm/main.c @@ -19,7 +19,6 @@ #include <config.h> -#include <assert.h> #include <ctype.h> #include <errno.h> #include <fcntl.h> diff --git a/gpgscm/scheme.c b/gpgscm/scheme.c index 906e563..1b489e4 100644 --- a/gpgscm/scheme.c +++ b/gpgscm/scheme.c @@ -33,7 +33,6 @@ # include <math.h> #endif -#include <assert.h> #include <limits.h> #include <stdint.h> #include <float.h> @@ -881,7 +880,7 @@ gc_reservation_failure(struct scheme *sc) sc->frame_freelist == sc->NIL ? "frame" : "cell", sc->reserved_lineno); #endif - abort(); + _gpgrt_abort(); } /* Disable the garbage collection and reserve the given number of diff --git a/src/estream-printf.c b/src/estream-printf.c index 2171409..bce6147 100644 --- a/src/estream-printf.c +++ b/src/estream-printf.c @@ -89,7 +89,6 @@ #include <stdarg.h> #include <errno.h> #include <stddef.h> -#include <assert.h> #if defined(HAVE_INTMAX_T) || defined(HAVE_UINTMAX_T) # ifdef HAVE_STDINT_H # include <stdint.h> @@ -1405,13 +1404,13 @@ do_format (estream_printf_out_t outfnc, void *outfncarg, s += arg->length; format = s; - assert (argidx < argspecs_len); + gpgrt_assert (argidx < argspecs_len); argidx++; /* Apply indirect field width and precision values. */ if (arg->width == STAR_FIELD_VALUE) { - assert (valuetable[arg->width_pos-1].vt == VALTYPE_INT); + gpgrt_assert (valuetable[arg->width_pos-1].vt == VALTYPE_INT); arg->width = valuetable[arg->width_pos-1].value.a_int; if (arg->width < 0) { @@ -1421,7 +1420,7 @@ do_format (estream_printf_out_t outfnc, void *outfncarg, } if (arg->precision == STAR_FIELD_VALUE) { - assert (valuetable[arg->precision_pos-1].vt == VALTYPE_INT); + gpgrt_assert (valuetable[arg->precision_pos-1].vt == VALTYPE_INT); arg->precision = valuetable[arg->precision_pos-1].value.a_int; if (arg->precision < 0) arg->precision = NO_FIELD_VALUE; @@ -1431,13 +1430,13 @@ do_format (estream_printf_out_t outfnc, void *outfncarg, value.a_string = strerror (myerrno); else { - assert (arg->vt == valuetable[arg->arg_pos-1].vt); + gpgrt_assert (arg->vt == valuetable[arg->arg_pos-1].vt); value = valuetable[arg->arg_pos-1].value; } switch (arg->conspec) { - case CONSPEC_UNKNOWN: assert (!"bug"); break; + case CONSPEC_UNKNOWN: gpgrt_assert (!"bug"); break; case CONSPEC_DECIMAL: case CONSPEC_UNSIGNED: @@ -1864,7 +1863,7 @@ _gpgrt_estream_vasprintf (char **bufp, const char *format, va_list arg_ptr) *bufp = NULL; return -1; } - assert (parm.used); /* We have at least the terminating Nul. */ + gpgrt_assert (parm.used); /* We have at least the terminating Nul. */ *bufp = parm.buffer; return parm.used - 1; /* Do not include that Nul. */ } diff --git a/src/estream.c b/src/estream.c index 3645dfe..8b7ccc5 100644 --- a/src/estream.c +++ b/src/estream.c @@ -84,7 +84,6 @@ #include <fcntl.h> #include <errno.h> #include <stddef.h> -#include <assert.h> #ifdef HAVE_W32_SYSTEM # ifdef HAVE_WINSOCK2_H # include <winsock2.h> @@ -653,7 +652,7 @@ func_mem_write (void *cookie, const void *buffer, size_t size) mem_cookie->offset = mem_cookie->data_len; } - assert (mem_cookie->memory_size >= mem_cookie->offset); + gpgrt_assert (mem_cookie->memory_size >= mem_cookie->offset); nleft = mem_cookie->memory_size - mem_cookie->offset; /* If we are not allowed to grow the buffer, limit the size to the @@ -698,7 +697,7 @@ func_mem_write (void *cookie, const void *buffer, size_t size) return -1; } - assert (mem_cookie->func_realloc); + gpgrt_assert (mem_cookie->func_realloc); newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize); if (!newbuf) return -1; @@ -706,10 +705,10 @@ func_mem_write (void *cookie, const void *buffer, size_t size) mem_cookie->memory = newbuf; mem_cookie->memory_size = newsize; - assert (mem_cookie->memory_size >= mem_cookie->offset); + gpgrt_assert (mem_cookie->memory_size >= mem_cookie->offset); nleft = mem_cookie->memory_size - mem_cookie->offset; - assert (size <= nleft); + gpgrt_assert (size <= nleft); } memcpy (mem_cookie->memory + mem_cookie->offset, buffer, size); @@ -776,7 +775,7 @@ func_mem_seek (void *cookie, gpgrt_off_t *offset, int whence) return -1; } - assert (mem_cookie->func_realloc); + gpgrt_assert (mem_cookie->func_realloc); newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize); if (!newbuf) return -1; @@ -1885,7 +1884,7 @@ flush_stream (estream_t stream) gpgrt_cookie_write_function_t func_write = stream->intern->func_write; int err; - assert (stream->flags.writing); + gpgrt_assert (stream->flags.writing); if (stream->data_offset) { @@ -1966,7 +1965,7 @@ flush_stream (estream_t stream) static void es_empty (estream_t stream) { - assert (!stream->flags.writing); + gpgrt_assert (!stream->flags.writing); stream->data_len = 0; stream->data_offset = 0; stream->unread_data_len = 0; @@ -3556,7 +3555,7 @@ _gpgrt__get_std_stream (int fd) { fprintf (stderr, "fatal: error creating a dummy estream" " for %d: %s\n", fd, strerror (errno)); - abort(); + _gpgrt_abort(); } } diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 0eca3c7..a55b31a 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -226,4 +226,7 @@ EXPORTS gpgrt_w32_override_locale @173 + gpgrt_add_emergency_cleanup @174 + gogrt_abort @175 + ;; end of file with public symbols for Windows. diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index b7aa5f6..a31fb84 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -324,6 +324,12 @@ void gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void)); /* Register a custom malloc/realloc/free function. */ void gpgrt_set_alloc_func (void *(*f)(void *a, size_t n)); +/* Register an emergency cleanup handler. */ +void gpgrt_add_emergency_cleanup (void (*f)(void)); + +/* Wrapper around abort to make sure emergency cleanups are run. */ +void gpgrt_abort (void) GPGRT_ATTR_NORETURN; + /* diff --git a/src/gpg-error.vers b/src/gpg-error.vers index 105e3bb..eef4cbc 100644 --- a/src/gpg-error.vers +++ b/src/gpg-error.vers @@ -196,6 +196,9 @@ GPG_ERROR_1.0 { gpgrt_fprintf_sf; gpgrt_fprintf_sf_unlocked; + gpgrt_add_emergency_cleanup; + gpgrt_abort; + local: *; }; diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index 17244c5..08496b2 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -107,6 +107,10 @@ void _gpg_err_set_errno (int err); gpg_error_t _gpg_err_init (void); void _gpg_err_deinit (int mode); + +void _gpgrt_add_emergency_cleanup (void (*f)(void)); +void _gpgrt_abort (void) GPGRT_ATTR_NORETURN; + void _gpgrt_set_alloc_func (void *(*f)(void *a, size_t n)); void *_gpgrt_realloc (void *a, size_t n); @@ -61,6 +61,20 @@ static void drop_locale_dir (char *locale_dir); #endif /*!HAVE_W32_SYSTEM*/ +/* The list of emergency cleanup functions; see _gpgrt_abort and + * _gpgrt_add_emergency_cleanup. */ +struct emergency_cleanup_item_s; +typedef struct emergency_cleanup_item_s *emergency_cleanup_item_t; +struct emergency_cleanup_item_s +{ + emergency_cleanup_item_t next; + void (*func) (void); +}; +static emergency_cleanup_item_t emergency_cleanup_list; + + + + /* The realloc function as set by gpgrt_set_alloc_func. */ static void *(*custom_realloc)(void *a, size_t n); @@ -106,7 +120,7 @@ _gpg_err_init (void) if (tls_index == TLS_OUT_OF_INDEXES) { /* No way to continue - commit suicide. */ - abort (); + _gpgrt_abort (); } _gpg_w32__init_gettext_module (); real_init (); @@ -151,6 +165,67 @@ _gpg_err_deinit (int mode) } +/* Add the emergency cleanup function F to the list of those function. + * If the a function with that address has already been registered, it + * is not added a second time. These emergency functions are called + * whenever gpgrt_abort is called and at no other place. Like signal + * handles the emergency cleanup functions shall not call any + * non-trivial functions and return as soon as possible. They allow + * to cleanup internal states which should not go into a core dumps or + * similar. This is independent of any atexit functions. We don't + * use locks here because in an emergency case we can't use them + * anyway. */ +void +_gpgrt_add_emergency_cleanup (void (*f)(void)) +{ + emergency_cleanup_item_t item; + + for (item = emergency_cleanup_list; item; item = item->next) + if (item->func == f) + return; /* Function has already been registered. */ + + /* We use a standard malloc here. */ + item = malloc (sizeof *item); + if (item) + { + item->func = f; + item->next = emergency_cleanup_list; + emergency_cleanup_list = item; + } + else + _gpgrt_log_fatal ("out of core in gpgrt_add_emergency_cleanup\n"); +} + + +/* Run the emergency handlers. No locks are used because we are anyway + * in an emergency state. We also can't release any memory. */ +static void +run_emergency_cleanup (void) +{ + emergency_cleanup_item_t next; + void (*f)(void); + + while (emergency_cleanup_list) + { + next = emergency_cleanup_list->next; + f = emergency_cleanup_list->func; + emergency_cleanup_list->func = NULL; + emergency_cleanup_list = next; + if (f) + f (); + } +} + + +/* Wrapper around abort to be able to run all emergency cleanup + * functions. */ +void +_gpgrt_abort (void) +{ + run_emergency_cleanup (); + abort (); +} + /* Register F as allocation function. This function is used for all @@ -503,7 +578,7 @@ get_tls (void) if (!tls) { /* No way to continue - commit suicide. */ - abort (); + _gpgrt_abort (); } tls->gt_use_utf8 = 0; TlsSetValue (tls_index, tls); diff --git a/src/logging.c b/src/logging.c index 01732ca..86cf7c3 100644 --- a/src/logging.c +++ b/src/logging.c @@ -46,7 +46,6 @@ #endif /*!HAVE_W32_SYSTEM*/ #include <unistd.h> #include <fcntl.h> -#include <assert.h> /* #include <execinfo.h> */ #define _GPGRT_NEED_AFLOCAL 1 @@ -690,7 +689,11 @@ _gpgrt_log_get_stream () { /* Make sure a log stream has been set. */ _gpgrt_log_set_sink (NULL, NULL, -1); - assert (logstream); + if (!logstream) + { + fputs ("gpgrt fatal: failed to init log stream\n", stderr); + _gpgrt_abort (); + } } return logstream; } @@ -902,7 +905,11 @@ _gpgrt_logv_internal (int level, int ignore_arg_ptr, const char *extrastring, /* Make sure a log stream has been set. */ _gpgrt_log_set_sink (NULL, NULL, -1); #endif - assert (logstream); + if (!logstream) + { + fputs ("gpgrt fatal: failed to init log stream\n", stderr); + _gpgrt_abort (); + } } _gpgrt_flockfile (logstream); @@ -1038,7 +1045,7 @@ _gpgrt_logv_internal (int level, int ignore_arg_ptr, const char *extrastring, /* for (btidx=0; btidx < btlen; btidx++) */ /* log_debug ("[%d] %s\n", btidx, btstr[btidx]); */ /* } */ - abort (); + _gpgrt_abort (); } else _gpgrt_funlockfile (logstream); @@ -1136,7 +1143,7 @@ _gpgrt_log_fatal (const char *fmt, ...) va_start (arg_ptr, fmt); _gpgrt_logv_internal (GPGRT_LOGLVL_FATAL, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); - abort (); /* Never called; just to make the compiler happy. */ + _gpgrt_abort (); /* Never called; just to make the compiler happy. */ } @@ -1148,7 +1155,7 @@ _gpgrt_log_bug (const char *fmt, ...) va_start (arg_ptr, fmt); _gpgrt_logv_internal (GPGRT_LOGLVL_BUG, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); - abort (); /* Never called; just to make the compiler happy. */ + _gpgrt_abort (); /* Never called; just to make the compiler happy. */ } @@ -1331,5 +1338,5 @@ _gpgrt__log_assert (const char *expr, const char *file, _gpgrt_log (GPGRT_LOGLVL_BUG, "Assertion \"%s\" failed (%s:%d)\n", expr, file, line); #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ - abort (); /* Never called; just to make the compiler happy. */ + _gpgrt_abort (); /* Never called; just to make the compiler happy. */ } diff --git a/src/posix-lock.c b/src/posix-lock.c index b5e6916..be4cc27 100644 --- a/src/posix-lock.c +++ b/src/posix-lock.c @@ -33,7 +33,6 @@ #include <stdio.h> #include <string.h> #include <errno.h> -#include <assert.h> #if USE_POSIX_THREADS # include <pthread.h> @@ -90,8 +89,9 @@ use_pthread_p (void) void *retval; if (pthread_join (thread, &retval) != 0) { - assert (!"pthread_join"); - abort (); + fputs ("gpgrt fatal: pthread_join in use_pthread_p failed\n", + stderr); + _gpgrt_abort (); } result = 1; } @@ -110,13 +110,13 @@ get_lock_object (gpgrt_lock_t *lockhd) if (lock->vers != LOCK_ABI_VERSION) { - assert (!"lock ABI version"); - abort (); + fputs ("gpgrt fatal: lock ABI version mismatch\n", stderr); + _gpgrt_abort (); } if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t)) { - assert (!"sizeof lock obj"); - abort (); + fputs ("gpgrt fatal: sizeof lock obj\n", stderr); + _gpgrt_abort (); } return lock; @@ -136,8 +136,8 @@ _gpgrt_lock_init (gpgrt_lock_t *lockhd) { if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t)) { - assert (!"sizeof lock obj"); - abort (); + fputs ("gpgrt fatal: sizeof lock obj\n", stderr); + _gpgrt_abort (); } lock->vers = LOCK_ABI_VERSION; } diff --git a/src/spawn-posix.c b/src/spawn-posix.c index 52780a8..7be15ea 100644 --- a/src/spawn-posix.c +++ b/src/spawn-posix.c @@ -32,7 +32,6 @@ #include <stdint.h> #include <string.h> #include <errno.h> -#include <assert.h> #ifdef HAVE_SIGNAL_H # include <signal.h> #endif diff --git a/src/spawn-w32.c b/src/spawn-w32.c index 4c57756..91f9ac4 100644 --- a/src/spawn-w32.c +++ b/src/spawn-w32.c @@ -31,7 +31,6 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#include <assert.h> #ifdef HAVE_SIGNAL_H # include <signal.h> #endif diff --git a/src/visibility.c b/src/visibility.c index 573a5a4..d754032 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -80,6 +80,18 @@ gpg_err_deinit (int mode) _gpg_err_deinit (mode); } +void +gpgrt_add_emergency_cleanup (void (*f)(void)) +{ + _gpgrt_add_emergency_cleanup (f); +} + +void +gpgrt_abort (void) +{ + _gpgrt_abort (); +} + const char * gpg_error_check_version (const char *req_version) { @@ -981,7 +993,7 @@ gpgrt_log_fatal (const char *fmt, ...) va_start (arg_ptr, fmt); _gpgrt_logv (GPGRT_LOGLVL_FATAL, fmt, arg_ptr); va_end (arg_ptr); - abort (); /* Never called; just to make the compiler happy. */ + _gpgrt_abort (); /* Never called; just to make the compiler happy. */ } void @@ -992,7 +1004,7 @@ gpgrt_log_bug (const char *fmt, ...) va_start (arg_ptr, fmt); _gpgrt_logv (GPGRT_LOGLVL_BUG, fmt, arg_ptr); va_end (arg_ptr); - abort (); /* Never called; just to make the compiler happy. */ + _gpgrt_abort (); /* Never called; just to make the compiler happy. */ } void diff --git a/src/visibility.h b/src/visibility.h index 2dde522..28038d0 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -54,6 +54,8 @@ MARK_VISIBLE (gpg_err_set_errno) MARK_VISIBLE (gpg_err_init) MARK_VISIBLE (gpg_err_deinit) +MARK_VISIBLE (gpgrt_add_emergency_cleanup) +MARK_VISIBLE (gpgrt_abort) MARK_VISIBLE (gpg_error_check_version) MARK_VISIBLE (gpgrt_check_version) @@ -231,6 +233,8 @@ MARK_VISIBLE (gpgrt_cmp_version); #define gpg_err_init _gpgrt_USE_UNDERSCORED_FUNCTION #define gpg_err_deinit _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_add_emergency_cleanup _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_abort _gpgrt_USE_UNDERSCORED_FUNCTION #define gpg_error_check_version _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_check_version _gpgrt_USE_OTHER_FUNCTION diff --git a/src/w32-estream.c b/src/w32-estream.c index 5d29b2c..9e33cdd 100644 --- a/src/w32-estream.c +++ b/src/w32-estream.c @@ -28,7 +28,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <assert.h> #include <errno.h> #include <fcntl.h> #ifdef HAVE_SYS_TIME_H @@ -144,7 +143,7 @@ reader (void *arg) trace (("%p: got space", ctx)); EnterCriticalSection (&ctx->mutex); } - assert (((ctx->writepos + 1) % READBUF_SIZE != ctx->readpos)); + gpgrt_assert (((ctx->writepos + 1) % READBUF_SIZE != ctx->readpos)); if (ctx->stop_me) { LeaveCriticalSection (&ctx->mutex); @@ -152,7 +151,7 @@ reader (void *arg) } nbytes = (ctx->readpos + READBUF_SIZE - ctx->writepos - 1) % READBUF_SIZE; - assert (nbytes); + gpgrt_assert (nbytes); if (nbytes > READBUF_SIZE - ctx->writepos) nbytes = READBUF_SIZE - ctx->writepos; LeaveCriticalSection (&ctx->mutex); @@ -714,7 +713,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) /* If no error occurred, the number of bytes in the buffer must be zero. */ - assert (!ctx->nbytes); + gpgrt_assert (!ctx->nbytes); if (count > WRITEBUF_SIZE) count = WRITEBUF_SIZE; @@ -881,7 +880,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) { if (WaitForSingleObject (waitbuf[i], 0) == WAIT_OBJECT_0) { - assert (waitidx[i] >=0 && waitidx[i] < nfds); + gpgrt_assert (waitidx[i] >=0 && waitidx[i] < nfds); /* XXX: What if one wants read and write, is that supported? */ if (fds[waitidx[i]].want_read) diff --git a/src/w32-lock.c b/src/w32-lock.c index a55f932..feed1e6 100644 --- a/src/w32-lock.c +++ b/src/w32-lock.c @@ -44,7 +44,7 @@ get_lock_object (gpgrt_lock_t *lockhd) _gpgrt_lock_t *lock = (_gpgrt_lock_t*)lockhd; if (lock->vers != LOCK_ABI_VERSION) - abort (); + _gpgrt_abort (); return lock; } @@ -61,14 +61,14 @@ _gpgrt_lock_init (gpgrt_lock_t *lockhd) if (!lock->vers) { if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t)) - abort (); + _gpgrt_abort (); lock->vers = LOCK_ABI_VERSION; } else /* Run the usual check. */ { lock = get_lock_object (lockhd); if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t)) - abort (); + _gpgrt_abort (); } InitializeCriticalSection (&lock->csec); |