Browse Source

[core] convert all assert() to LI_FORCE_ASSERT(), and support writing backtraces on fatal errors with libunwind

personal/stbuehler/wip
Stefan Bühler 8 years ago
parent
commit
17a5168793
  1. 12
      configure.ac
  2. 2
      include/lighttpd/actions.h
  3. 8
      include/lighttpd/angel_log.h
  4. 2
      include/lighttpd/core_lua.h
  5. 56
      include/lighttpd/events.h
  6. 18
      include/lighttpd/log.h
  7. 2
      include/lighttpd/settings.h
  8. 8
      include/lighttpd/utils.h
  9. 10
      src/CMakeLists.txt
  10. 2
      src/angel/angel_config_parser.rl
  11. 2
      src/angel/angel_plugin_core.c
  12. 6
      src/angel/angel_server.c
  13. 4
      src/common/Makefile.am
  14. 2
      src/common/angel_connection.c
  15. 5
      src/common/buffer.c
  16. 36
      src/common/events.c
  17. 58
      src/common/fetch.c
  18. 2
      src/common/jobqueue.c
  19. 4
      src/common/memcached.c
  20. 5
      src/common/mempool.c
  21. 8
      src/common/profiler.c
  22. 5
      src/common/radix.c
  23. 64
      src/common/utils.c
  24. 7
      src/common/value.c
  25. 3
      src/config.h.cmake
  26. 8
      src/main/actions.c
  27. 48
      src/main/backends.c
  28. 26
      src/main/chunk.c
  29. 8
      src/main/condition.c
  30. 2
      src/main/condition_lua.c
  31. 8
      src/main/config_lua.c
  32. 14
      src/main/config_parser.rl
  33. 30
      src/main/connection.c
  34. 2
      src/main/core_lua.c
  35. 12
      src/main/filter.c
  36. 4
      src/main/filter_buffer_on_disk.c
  37. 8
      src/main/log.c
  38. 6
      src/main/mimetype.c
  39. 2
      src/main/network.c
  40. 16
      src/main/plugin.c
  41. 4
      src/main/plugin_core.c
  42. 8
      src/main/server.c
  43. 4
      src/main/stat_cache.c
  44. 16
      src/main/stream.c
  45. 2
      src/main/stream_simple_socket.c
  46. 12
      src/main/throttle.c
  47. 14
      src/main/virtualrequest.c
  48. 2
      src/main/worker.c
  49. 58
      src/modules/fastcgi_stream.c
  50. 16
      src/modules/gnutls_filter.c
  51. 2
      src/modules/mod_auth.c
  52. 4
      src/modules/mod_balance.c
  53. 10
      src/modules/mod_fastcgi.c
  54. 24
      src/modules/mod_gnutls.c
  55. 6
      src/modules/mod_memcached.c
  56. 18
      src/modules/mod_openssl.c
  57. 10
      src/modules/mod_proxy.c
  58. 10
      src/modules/mod_scgi.c
  59. 14
      src/modules/mod_throttle.c
  60. 4
      src/modules/mod_vhost.c
  61. 14
      src/modules/openssl_filter.c
  62. 4
      src/modules/ssl-session-db.h
  63. 4
      src/modules/ssl_client_hello_parser.h

12
configure.ac

@ -268,6 +268,18 @@ if test "ac_cv_sockaddr_storage_support" = yes; then
fi
dnl Checking for libunwind
AC_MSG_CHECKING(for libunwind)
AC_ARG_WITH(libunwind,
AC_HELP_STRING([--with-libunwind],[Include libunwind support for backtraces on assert failures]),
[WITH_LIBUNWIND=$withval],[WITH_LIBUNWIND=no])
if test "$WITH_LIBUNWIND" != "no"; then
PKG_CHECK_MODULES(LIBUNWIND, libunwind)
AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support])
fi
dnl Check for openssl
AC_MSG_CHECKING([for OpenSSL])
AC_ARG_WITH([openssl],

2
include/lighttpd/actions.h

@ -93,7 +93,7 @@ LI_API liAction* li_action_new_list(void);
LI_API liAction* li_action_new_condition(liCondition *cond, liAction *target, liAction *target_else);
LI_API liAction* li_action_new_balancer(liBackendSelectCB bselect, liBackendFallbackCB bfallback, liBackendFinishedCB bfinished, liBalancerFreeCB bfree, gpointer param, gboolean provide_backlog);
/* assert(list->refcount == 1)! converts list to a list in place if necessary */
/* LI_FORCE_ASSERT(list->refcount == 1)! converts list to a list in place if necessary */
LI_API void li_action_append_inplace(liAction *list, liAction *element);
#endif

8
include/lighttpd/angel_log.h

@ -5,13 +5,11 @@
#error Please include <lighttpd/angel_base.h> instead of this file
#endif
/* #include <lighttpd/valgrind/valgrind.h> */
#define SEGFAULT(srv, fmt, ...) \
do { \
li_log_write_(srv, LI_LOG_LEVEL_ABORT, LI_LOG_FLAG_TIMESTAMP, "(crashing) %s.%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__); \
/* VALGRIND_PRINTF_BACKTRACE(fmt, __VA_ARGS__); */\
abort();\
li_log_write_(srv, LI_LOG_LEVEL_ABORT, LI_LOG_FLAG_TIMESTAMP, "(crashing) %s:%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__); \
li_print_backtrace_stderr(); \
abort(); \
} while(0)
#define ERROR(srv, fmt, ...) \

2
include/lighttpd/core_lua.h

@ -114,7 +114,7 @@ INLINE void li_lua_lock(liLuaState *LL) {
gboolean b;
g_static_rec_mutex_lock(&LL->lualock);
b = lua_checkstack(LL->L, LUA_MINSTACK);
assert(b);
LI_FORCE_ASSERT(b);
}
INLINE void li_lua_unlock(liLuaState *LL) {

56
include/lighttpd/events.h

@ -201,8 +201,8 @@ INLINE li_tstamp li_event_time(void) {
}
INLINE void li_event_attach_(liEventLoop *loop, liEventBase *base) {
assert(NULL == base->link_watchers.data);
assert(NULL != loop);
LI_FORCE_ASSERT(NULL == base->link_watchers.data);
LI_FORCE_ASSERT(NULL != loop);
base->link_watchers.data = loop;
g_queue_push_tail_link(&loop->watchers, &base->link_watchers);
@ -238,8 +238,8 @@ INLINE liEventLoop* li_event_get_loop_(liEventBase *base) {
INLINE void li_event_start_(liEventBase *base) {
liEventLoop *loop = base->link_watchers.data;
assert(NULL != base->callback);
assert(LI_EVT_NONE != base->type);
LI_FORCE_ASSERT(NULL != base->callback);
LI_FORCE_ASSERT(LI_EVT_NONE != base->type);
if (base->active) return;
base->active = 1;
@ -251,8 +251,8 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_IO:
{
liEventIO *io = li_event_io_from(base);
assert(!ev_is_active(&io->libevmess.w));
assert(-1 != io->libevmess.io.fd);
LI_FORCE_ASSERT(!ev_is_active(&io->libevmess.w));
LI_FORCE_ASSERT(-1 != io->libevmess.io.fd);
ev_io_start(loop->loop, &io->libevmess.io);
if (!base->keep_loop_alive) ev_unref(loop->loop);
}
@ -260,7 +260,7 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_TIMER:
{
liEventTimer *timer = li_event_timer_from(base);
assert(!ev_is_active(&timer->libevmess.w));
LI_FORCE_ASSERT(!ev_is_active(&timer->libevmess.w));
if (0 >= timer->libevmess.timer.repeat) timer->libevmess.timer.repeat = 0.0001;
ev_timer_again(loop->loop, &timer->libevmess.timer);
if (!base->keep_loop_alive) ev_unref(loop->loop);
@ -269,7 +269,7 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_ASYNC:
{
liEventAsync *async = li_event_async_from(base);
assert(!ev_is_active(&async->libevmess.w));
LI_FORCE_ASSERT(!ev_is_active(&async->libevmess.w));
ev_async_start(loop->loop, &async->libevmess.async);
if (!base->keep_loop_alive) ev_unref(loop->loop);
}
@ -277,7 +277,7 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_CHILD:
{
liEventChild *child = li_event_child_from(base);
assert(!ev_is_active(&child->libevmess.w));
LI_FORCE_ASSERT(!ev_is_active(&child->libevmess.w));
ev_child_start(loop->loop, &child->libevmess.child);
if (!base->keep_loop_alive) ev_unref(loop->loop);
}
@ -285,7 +285,7 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_SIGNAL:
{
liEventSignal *sig = li_event_signal_from(base);
assert(!ev_is_active(&sig->libevmess.w));
LI_FORCE_ASSERT(!ev_is_active(&sig->libevmess.w));
ev_signal_start(loop->loop, &sig->libevmess.sig);
if (!base->keep_loop_alive) ev_unref(loop->loop);
}
@ -293,7 +293,7 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_PREPARE:
{
liEventPrepare *prepare = li_event_prepare_from(base);
assert(!ev_is_active(&prepare->libevmess.w));
LI_FORCE_ASSERT(!ev_is_active(&prepare->libevmess.w));
ev_prepare_start(loop->loop, &prepare->libevmess.prepare);
if (!base->keep_loop_alive) ev_unref(loop->loop);
}
@ -301,7 +301,7 @@ INLINE void li_event_start_(liEventBase *base) {
case LI_EVT_CHECK:
{
liEventCheck *check = li_event_check_from(base);
assert(!ev_is_active(&check->libevmess.w));
LI_FORCE_ASSERT(!ev_is_active(&check->libevmess.w));
ev_check_start(loop->loop, &check->libevmess.check);
if (!base->keep_loop_alive) ev_unref(loop->loop);
}
@ -316,8 +316,8 @@ INLINE void li_event_stop_(liEventBase *base) {
if (!base->active) return;
base->active = 0;
assert(NULL != base->callback);
assert(LI_EVT_NONE != base->type);
LI_FORCE_ASSERT(NULL != base->callback);
LI_FORCE_ASSERT(LI_EVT_NONE != base->type);
if (NULL != loop) {
switch (base->type) {
@ -326,7 +326,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_IO:
{
liEventIO *io = li_event_io_from(base);
assert(ev_is_active(&io->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&io->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_io_stop(loop->loop, &io->libevmess.io);
}
@ -334,7 +334,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_TIMER:
{
liEventTimer *timer = li_event_timer_from(base);
assert(ev_is_active(&timer->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&timer->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_timer_stop(loop->loop, &timer->libevmess.timer);
}
@ -342,7 +342,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_ASYNC:
{
liEventAsync *async = li_event_async_from(base);
assert(ev_is_active(&async->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&async->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_async_stop(loop->loop, &async->libevmess.async);
}
@ -350,7 +350,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_CHILD:
{
liEventChild *child = li_event_child_from(base);
assert(ev_is_active(&child->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&child->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_child_stop(loop->loop, &child->libevmess.child);
}
@ -358,7 +358,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_SIGNAL:
{
liEventSignal *sig = li_event_signal_from(base);
assert(ev_is_active(&sig->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&sig->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_signal_stop(loop->loop, &sig->libevmess.sig);
}
@ -366,7 +366,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_PREPARE:
{
liEventPrepare *prepare = li_event_prepare_from(base);
assert(ev_is_active(&prepare->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&prepare->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_prepare_stop(loop->loop, &prepare->libevmess.prepare);
}
@ -374,7 +374,7 @@ INLINE void li_event_stop_(liEventBase *base) {
case LI_EVT_CHECK:
{
liEventCheck *check = li_event_check_from(base);
assert(ev_is_active(&check->libevmess.w));
LI_FORCE_ASSERT(ev_is_active(&check->libevmess.w));
if (!base->keep_loop_alive) ev_ref(loop->loop);
ev_check_stop(loop->loop, &check->libevmess.check);
}
@ -473,7 +473,7 @@ INLINE int li_event_io_fd(liEventIO *io) {
}
INLINE liEventIO* li_event_io_from(liEventBase *base) {
assert(LI_EVT_IO == base->type);
LI_FORCE_ASSERT(LI_EVT_IO == base->type);
return LI_CONTAINER_OF(base, liEventIO, base);
}
@ -484,7 +484,7 @@ INLINE void li_event_timer_once(liEventTimer *timer, li_tstamp timeout) {
}
INLINE liEventTimer* li_event_timer_from(liEventBase *base) {
assert(LI_EVT_TIMER == base->type);
LI_FORCE_ASSERT(LI_EVT_TIMER == base->type);
return LI_CONTAINER_OF(base, liEventTimer, base);
}
@ -494,7 +494,7 @@ INLINE void li_event_async_send(liEventAsync *async) {
}
INLINE liEventAsync* li_event_async_from(liEventBase *base){
assert(LI_EVT_ASYNC == base->type);
LI_FORCE_ASSERT(LI_EVT_ASYNC == base->type);
return LI_CONTAINER_OF(base, liEventAsync, base);
}
@ -507,7 +507,7 @@ INLINE int li_event_child_status(liEventChild *child) {
}
INLINE liEventChild* li_event_child_from(liEventBase *base) {
assert(LI_EVT_CHILD == base->type);
LI_FORCE_ASSERT(LI_EVT_CHILD == base->type);
return LI_CONTAINER_OF(base, liEventChild, base);
}
@ -516,17 +516,17 @@ INLINE int li_event_signal_signum(liEventSignal *sig) {
}
INLINE liEventSignal* li_event_signal_from(liEventBase *base) {
assert(LI_EVT_SIGNAL == base->type);
LI_FORCE_ASSERT(LI_EVT_SIGNAL == base->type);
return LI_CONTAINER_OF(base, liEventSignal, base);
}
INLINE liEventPrepare* li_event_prepare_from(liEventBase *base) {
assert(LI_EVT_PREPARE == base->type);
LI_FORCE_ASSERT(LI_EVT_PREPARE == base->type);
return LI_CONTAINER_OF(base, liEventPrepare, base);
}
INLINE liEventCheck* li_event_check_from(liEventBase *base) {
assert(LI_EVT_CHECK == base->type);
LI_FORCE_ASSERT(LI_EVT_CHECK == base->type);
return LI_CONTAINER_OF(base, liEventCheck, base);
}

18
include/lighttpd/log.h

@ -16,27 +16,25 @@
* Logs are sent once per event loop iteration to the logging thread in order to reduce syscalls and lock contention.
*/
/* #include <lighttpd/valgrind/valgrind.h> */
/* at least one of srv and wrk must not be NULL. log_map may be NULL. */
#define _SEGFAULT(srv, wrk, log_map, fmt, ...) \
do { \
li_log_write(srv, NULL, NULL, LI_LOG_LEVEL_ABORT, LI_LOG_FLAG_TIMESTAMP, "(crashing) %s.%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__); \
/* VALGRIND_PRINTF_BACKTRACE(fmt, __VA_ARGS__); */\
abort();\
li_log_write(srv, NULL, NULL, LI_LOG_LEVEL_ABORT, LI_LOG_FLAG_TIMESTAMP, "(crashing) %s:%d: %s " fmt, LI_REMOVE_PATH(__FILE__), __LINE__, G_STRFUNC, __VA_ARGS__); \
li_print_backtrace_stderr(); \
abort(); \
} while(0)
#define _ERROR(srv, wrk, ctx, fmt, ...) \
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_ERROR, LI_LOG_FLAG_TIMESTAMP, "(error) %s.%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_ERROR, LI_LOG_FLAG_TIMESTAMP, "(error) %s:%d: " fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
#define _WARNING(srv, wrk, ctx, fmt, ...) \
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_WARNING, LI_LOG_FLAG_TIMESTAMP, "(warning) %s.%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_WARNING, LI_LOG_FLAG_TIMESTAMP, "(warning) %s:%d: " fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
#define _INFO(srv, wrk, ctx, fmt, ...) \
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_INFO, LI_LOG_FLAG_TIMESTAMP, "(info) %s.%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_INFO, LI_LOG_FLAG_TIMESTAMP, "(info) %s:%d: " fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
#define _DEBUG(srv, wrk, ctx, fmt, ...) \
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_DEBUG, LI_LOG_FLAG_TIMESTAMP, "(debug) %s.%d: "fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_DEBUG, LI_LOG_FLAG_TIMESTAMP, "(debug) %s:%d: " fmt, LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
#define _BACKEND(srv, wrk, ctx, fmt, ...) \
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_BACKEND, LI_LOG_FLAG_TIMESTAMP, fmt, __VA_ARGS__)
@ -44,7 +42,7 @@
li_log_split_lines_(srv, wrk, ctx, LI_LOG_LEVEL_BACKEND, LI_LOG_FLAG_TIMESTAMP, txt, fmt, __VA_ARGS__)
#define _GERROR(srv, wrk, ctx, error, fmt, ...) \
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_ERROR, LI_LOG_FLAG_TIMESTAMP, "(error) %s.%d: " fmt "\n %s", LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__, error ? error->message : "Empty GError")
li_log_write(srv, wrk, ctx, LI_LOG_LEVEL_ERROR, LI_LOG_FLAG_TIMESTAMP, "(error) %s:%d: " fmt "\n %s", LI_REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__, error ? error->message : "Empty GError")
#define VR_SEGFAULT(vr, fmt, ...) _SEGFAULT(vr->wrk->srv, vr->wrk, &vr->log_context, fmt, __VA_ARGS__)
#define VR_ERROR(vr, fmt, ...) _ERROR(vr->wrk->srv, vr->wrk, &vr->log_context, fmt, __VA_ARGS__)

2
include/lighttpd/settings.h

@ -65,8 +65,6 @@
#define GUSTR_LEN(x) ((const guchar*) ((x)->str)), ((x)->len)
#define GSTR_SAFE_STR(x) ((x && x->str) ? x->str : "(null)")
#include <assert.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

8
include/lighttpd/utils.h

@ -9,7 +9,13 @@ typedef enum {
COUNTER_UNITS
} liCounterType;
LI_API void li_fatal(const gchar* msg);
/* log message, print backtrace, and abort() (use LI_FATAL(msg) to call it) */
LI_API void li_fatal(const char *filename, unsigned int line, const char *function, const char *msg) G_GNUC_NORETURN;
/* if libunwind is available this prints a backtrace to STDERR */
LI_API void li_print_backtrace_stderr(void);
/* LI_FORCE_ASSERT is *always* active - in debug and release builds */
#define LI_FORCE_ASSERT(x) do { if (G_UNLIKELY(!(x))) li_fatal(__FILE__, __LINE__, G_STRFUNC, "Assertion `" #x "' failed."); } while(0)
#define LI_FATAL(msg) li_fatal(__FILE__, __LINE__, G_STRFUNC, msg)
/* set O_NONBLOCK and FD_CLOEXEC */
LI_API void li_fd_init(int fd);

10
src/CMakeLists.txt

@ -19,6 +19,7 @@ ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES)
OPTION(WITH_LUA "with lua 5.1 for lua-configfile [default: on]" ON)
OPTION(WITHOUT_CONFIG_PARSER "without standard config parser [default: off]" OFF)
OPTION(WITH_UNWIND "with (lib)unwind support in asserts to print backtraces [default: off]" OFF)
OPTION(WITH_OPENSSL "with openssl support [default: off]")
OPTION(WITH_GNUTLS "with gnutls support [default: off]")
OPTION(WITH_SNI "with SNI support for gnutls/openssl, needs libidn [default: off]")
@ -109,6 +110,11 @@ IF(WITH_GNUTLS)
pkg_search_module(GNUTLS REQUIRED gnutls)
ENDIF(WITH_GNUTLS)
IF(WITH_UNWIND)
pkg_search_module(UNWIND REQUIRED libunwind)
SET(HAVE_LIBUNWIND 1 "Have libunwind")
ENDIF(WITH_UNWIND)
IF(WITH_OPENSSL)
CHECK_INCLUDE_FILES(openssl/ssl.h HAVE_OPENSSL_SSL_H)
IF(HAVE_OPENSSL_SSL_H)
@ -388,8 +394,8 @@ IF(WITH_OPENSSL)
ADD_TARGET_PROPERTIES(mod_openssl COMPILE_FLAGS ${IDN_CFLAGS})
ENDIF(WITH_OPENSSL)
TARGET_LINK_LIBRARIES(lighttpd-${PACKAGE_VERSION}-common ${COMMON_LDFLAGS})
ADD_TARGET_PROPERTIES(lighttpd-${PACKAGE_VERSION}-common COMPILE_FLAGS ${COMMON_CFLAGS})
TARGET_LINK_LIBRARIES(lighttpd-${PACKAGE_VERSION}-common ${COMMON_LDFLAGS} ${UNWIND_LDFLAGS})
ADD_TARGET_PROPERTIES(lighttpd-${PACKAGE_VERSION}-common COMPILE_FLAGS ${COMMON_CFLAGS} ${UNWIND_CFLAGS})
TARGET_LINK_LIBRARIES(lighttpd-${PACKAGE_VERSION}-shared ${COMMON_LDFLAGS})
ADD_TARGET_PROPERTIES(lighttpd-${PACKAGE_VERSION}-shared COMPILE_FLAGS ${COMMON_CFLAGS})

2
src/angel/angel_config_parser.rl

@ -413,7 +413,7 @@ static liConfigToken tokenizer_next(liConfigTokenizerContext *ctx, GError **erro
else if (TK_ERROR == (token = tokenizer_next(ctx, error))) goto error; \
} while (0)
#define REMEMBER(token) do { \
assert(TK_ERROR == ctx->next_token); /* mustn't contain a token */ \
LI_FORCE_ASSERT(TK_ERROR == ctx->next_token); /* mustn't contain a token */ \
ctx->next_token = token; \
} while (0)

2
src/angel/angel_plugin_core.c

@ -498,7 +498,7 @@ static void listen_ref_release(liServer *srv, liInstance *i, liPlugin *p, liInst
UNUSED(i);
UNUSED(srv);
assert(g_atomic_int_get(&sock->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&sock->refcount) > 0);
if (g_atomic_int_dec_and_test(&sock->refcount)) {
liPluginCoreConfig *config = (liPluginCoreConfig*) p->data;

6
src/angel/angel_server.c

@ -387,7 +387,7 @@ void li_instance_release(liInstance *i) {
}
void li_instance_acquire(liInstance *i) {
assert(g_atomic_int_get(&i->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&i->refcount) > 0);
g_atomic_int_inc(&i->refcount);
}
@ -406,7 +406,7 @@ liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username
void li_instance_conf_release(liInstanceConf *ic) {
if (!ic) return;
assert(g_atomic_int_get(&ic->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&ic->refcount) > 0);
if (!g_atomic_int_dec_and_test(&ic->refcount)) return;
if (ic->username) g_string_free(ic->username, TRUE);
@ -416,7 +416,7 @@ void li_instance_conf_release(liInstanceConf *ic) {
}
void li_instance_conf_acquire(liInstanceConf *ic) {
assert(g_atomic_int_get(&ic->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&ic->refcount) > 0);
g_atomic_int_inc(&ic->refcount);
}

4
src/common/Makefile.am

@ -39,5 +39,5 @@ ip_parsers.c: ip_parsers.rl
liblighttpd2_common_la_SOURCES=$(common_src)
nodist_liblighttpd2_common_la_SOURCES=$(nodist_common_src)
liblighttpd2_common_la_CPPFLAGS=$(common_cflags) $(GTHREAD_CFLAGS) $(GMODULE_CFLAGS) $(LIBEV_CFLAGS)
liblighttpd2_common_la_LDFLAGS=-release $(PACKAGE_VERSION) -export-dynamic $(GTHREAD_LIBS) $(GMODULE_LIBS) $(LIBEV_LIBS) $(CRYPT_LIB)
liblighttpd2_common_la_CPPFLAGS=$(common_cflags) $(GTHREAD_CFLAGS) $(GMODULE_CFLAGS) $(LIBEV_CFLAGS) $(LIBUNWIND_CFLAGS)
liblighttpd2_common_la_LDFLAGS=-release $(PACKAGE_VERSION) -export-dynamic $(GTHREAD_LIBS) $(GMODULE_LIBS) $(LIBEV_LIBS) $(CRYPT_LIB) $(LIBUNWIND_LIBS)

2
src/common/angel_connection.c

@ -489,7 +489,7 @@ static void angel_call_result_cb(liEventBase *watcher, int events) {
liAngelCall* call = LI_CONTAINER_OF(li_event_async_from(watcher), liAngelCall, result_watcher);
UNUSED(events);
assert(-1 == call->id);
LI_FORCE_ASSERT(-1 == call->id);
call->acon = NULL;

5
src/common/buffer.c

@ -1,5 +1,6 @@
#include <lighttpd/buffer.h>
#include <lighttpd/utils.h>
static void _buffer_init(liBuffer *buf, gsize alloc_size) {
buf->alloc_size = alloc_size;
@ -47,13 +48,13 @@ liBuffer* li_buffer_new_slice(gsize max_size) {
void li_buffer_release(liBuffer *buf) {
if (!buf) return;
assert(g_atomic_int_get(&buf->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&buf->refcount) > 0);
if (g_atomic_int_dec_and_test(&buf->refcount)) {
_buffer_destroy(buf);
}
}
void li_buffer_acquire(liBuffer *buf) {
assert(g_atomic_int_get(&buf->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&buf->refcount) > 0);
g_atomic_int_inc(&buf->refcount);
}

36
src/common/events.c

@ -103,9 +103,9 @@ struct ev_loop* li_event_loop_clear(liEventLoop *loop) {
while (NULL != (lnk = loop->watchers.head)) {
liEventBase *base = LI_CONTAINER_OF(lnk, liEventBase, link_watchers);
assert(li_event_attached_(base));
LI_FORCE_ASSERT(li_event_attached_(base));
li_event_detach_(base);
assert(lnk != loop->watchers.head);
LI_FORCE_ASSERT(lnk != loop->watchers.head);
}
loop->loop = NULL;
return evloop;
@ -155,8 +155,8 @@ static void event_io_cb(struct ev_loop *loop, ev_io *w, int revents) {
liEventLoop *my_loop = io->base.link_watchers.data;
int events = 0;
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
if (revents & EV_READ) events |= LI_EV_READ;
if (revents & EV_WRITE) events |= LI_EV_WRITE;
@ -193,7 +193,7 @@ void li_event_io_set_fd(liEventIO *io, int fd) {
if (li_event_attached(io) && li_event_active(io)) {
liEventLoop *loop = io->base.link_watchers.data;
assert(NULL != loop);
LI_FORCE_ASSERT(NULL != loop);
ev_ref(loop->loop);
@ -213,7 +213,7 @@ void li_event_io_set_events(liEventIO *io, int events) {
if (li_event_attached(io) && li_event_active(io)) {
liEventLoop *loop = io->base.link_watchers.data;
assert(NULL != loop);
LI_FORCE_ASSERT(NULL != loop);
ev_ref(loop->loop);
@ -239,8 +239,8 @@ static void event_timer_cb(struct ev_loop *loop, ev_timer *w, int revents) {
liEventLoop *my_loop = timer->base.link_watchers.data;
UNUSED(revents);
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
if (ev_is_active(w)) {
if (!timer->base.keep_loop_alive) ev_ref(loop);
@ -267,8 +267,8 @@ static void event_async_cb(struct ev_loop *loop, ev_async *w, int revents) {
liEventLoop *my_loop = async->base.link_watchers.data;
UNUSED(revents);
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
async->base.callback(&async->base, LI_EV_WAKEUP);
}
@ -290,8 +290,8 @@ static void event_child_cb(struct ev_loop *loop, ev_child *w, int revents) {
liEventLoop *my_loop = child->base.link_watchers.data;
UNUSED(revents);
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
if (ev_is_active(w)) {
if (!child->base.keep_loop_alive) ev_ref(loop);
@ -320,8 +320,8 @@ static void event_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
liEventLoop *my_loop = sig->base.link_watchers.data;
UNUSED(revents);
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
sig->base.callback(&sig->base, LI_EV_WAKEUP);
}
@ -344,8 +344,8 @@ static void event_prepare_cb(struct ev_loop *loop, ev_prepare *w, int revents) {
liEventLoop *my_loop = prepare->base.link_watchers.data;
UNUSED(revents);
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
prepare->base.callback(&prepare->base, LI_EV_WAKEUP);
}
@ -367,8 +367,8 @@ static void event_check_cb(struct ev_loop *loop, ev_check *w, int revents) {
liEventLoop *my_loop = check->base.link_watchers.data;
UNUSED(revents);
assert(NULL != my_loop);
assert(loop == my_loop->loop);
LI_FORCE_ASSERT(NULL != my_loop);
LI_FORCE_ASSERT(loop == my_loop->loop);
check->base.callback(&check->base, LI_EV_WAKEUP);
}

58
src/common/fetch.c

@ -87,7 +87,7 @@ static void append_to_lru(liFetchEntryP *pentry) {
GQueue *q = NULL != pentry->public.data ? &db->lru_queue : &db->lru_negative_queue;
guint limit = NULL != pentry->public.data ? db->cache_size : db->neg_cache_size;
assert(LI_ENTRY_VALID == pentry->state);
LI_FORCE_ASSERT(LI_ENTRY_VALID == pentry->state);
g_queue_push_tail_link(q, &pentry->lru_link);
while (q->length > limit) {
GList *lru_link =g_queue_peek_head_link(q);
@ -97,15 +97,15 @@ static void append_to_lru(liFetchEntryP *pentry) {
}
static void fetch_db_int_acquire(liFetchDatabase* db) {
assert(g_atomic_int_get(&db->internal_refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&db->internal_refcount) > 0);
g_atomic_int_inc(&db->internal_refcount);
}
static void fetch_db_int_release(liFetchDatabase* db) {
assert(g_atomic_int_get(&db->internal_refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&db->internal_refcount) > 0);
if (g_atomic_int_dec_and_test(&db->internal_refcount)) {
db->internal_refcount = 1;
assert(NULL == db->cache);
LI_FORCE_ASSERT(NULL == db->cache);
if (NULL != db->callbacks->free_db) db->callbacks->free_db(db->data);
@ -113,33 +113,33 @@ static void fetch_db_int_release(liFetchDatabase* db) {
db->lock = NULL;
db->data = NULL;
db->callbacks = NULL;
assert(1 == db->internal_refcount);
LI_FORCE_ASSERT(1 == db->internal_refcount);
g_slice_free(liFetchDatabase, db);
}
}
void li_fetch_database_acquire(liFetchDatabase* db) {
assert(g_atomic_int_get(&db->refcount) > 0);
assert(g_atomic_int_get(&db->internal_refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&db->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&db->internal_refcount) > 0);
g_atomic_int_inc(&db->refcount);
}
void li_fetch_database_release(liFetchDatabase* db) {
assert(g_atomic_int_get(&db->refcount) > 0);
assert(g_atomic_int_get(&db->internal_refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&db->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&db->internal_refcount) > 0);
if (g_atomic_int_dec_and_test(&db->refcount)) {
GHashTable *cache = db->cache;
db->refcount = 1;
g_mutex_lock(db->lock);
assert(NULL != cache);
LI_FORCE_ASSERT(NULL != cache);
db->cache = NULL;
g_hash_table_destroy(cache);
g_mutex_unlock(db->lock);
assert(1 == db->refcount);
LI_FORCE_ASSERT(1 == db->refcount);
db->refcount = 0;
fetch_db_int_release(db);
}
@ -147,7 +147,7 @@ void li_fetch_database_release(liFetchDatabase* db) {
void li_fetch_entry_acquire(liFetchEntry *entry) {
liFetchEntryP *pentry = LI_CONTAINER_OF(entry, liFetchEntryP, public);
assert(g_atomic_int_get(&pentry->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&pentry->refcount) > 0);
g_atomic_int_inc(&pentry->refcount);
}
@ -156,7 +156,7 @@ void li_fetch_entry_release(liFetchEntry *entry) {
if (NULL == entry) return;
pentry = LI_CONTAINER_OF(entry, liFetchEntryP, public);
assert(g_atomic_int_get(&pentry->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&pentry->refcount) > 0);
if (g_atomic_int_dec_and_test(&pentry->refcount)) {
liFetchEntryState state = g_atomic_int_get(&pentry->state);
liFetchDatabase *db = pentry->db;
@ -167,11 +167,11 @@ void li_fetch_entry_release(liFetchEntry *entry) {
g_string_free(pentry->public.key, TRUE);
pentry->public.key = NULL;
assert(LI_ENTRY_INVALID == state);
LI_FORCE_ASSERT(LI_ENTRY_INVALID == state);
pentry->db = NULL;
fetch_db_int_release(db);
assert(1 == pentry->refcount);
LI_FORCE_ASSERT(1 == pentry->refcount);
pentry->refcount = 0;
g_slice_free(liFetchEntryP, pentry);
}
@ -188,7 +188,7 @@ void li_fetch_invalidate(liFetchDatabase* db, GString *key) {
if (NULL == pentry) goto out;
state = g_atomic_int_get(&pentry->state);
assert(LI_ENTRY_REFRESH_NEW != state && LI_ENTRY_INVALID != state); /* this is never in the cache */
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW != state && LI_ENTRY_INVALID != state); /* this is never in the cache */
switch (state) {
case LI_ENTRY_LOOKUP:
goto out;
@ -221,7 +221,7 @@ static void cache_delete_data_cb(gpointer data) {
GQueue wait_queue = G_QUEUE_INIT;
liFetchEntryP *new_entry = NULL;
assert(LI_ENTRY_REFRESH_NEW != state && LI_ENTRY_INVALID != state); /* this is never in the cache */
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW != state && LI_ENTRY_INVALID != state); /* this is never in the cache */
switch (state) {
case LI_ENTRY_LOOKUP:
@ -248,8 +248,8 @@ static void cache_delete_data_cb(gpointer data) {
g_atomic_int_set(&pentry->state, LI_ENTRY_INVALID);
if (NULL != new_entry) {
assert(pentry == new_entry->refreshing);
assert(LI_ENTRY_REFRESH_NEW == g_atomic_int_get(&new_entry->state));
LI_FORCE_ASSERT(pentry == new_entry->refreshing);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW == g_atomic_int_get(&new_entry->state));
new_entry->refreshing = NULL;
g_atomic_int_set(&new_entry->state, LI_ENTRY_INVALID);
li_fetch_entry_release(&pentry->public);
@ -290,7 +290,7 @@ void li_fetch_entry_ready(liFetchEntry *entry) {
if (LI_ENTRY_INVALID == state) goto out;
assert(LI_ENTRY_LOOKUP == state);
LI_FORCE_ASSERT(LI_ENTRY_LOOKUP == state);
g_atomic_int_set(&pentry->state, LI_ENTRY_VALID);
append_to_lru(pentry);
@ -373,14 +373,14 @@ void li_fetch_entry_refresh_skip(liFetchEntry *new_entry) {
if (LI_ENTRY_INVALID == state) goto out;
assert(LI_ENTRY_REFRESH_NEW == state);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW == state);
pentry = pnew_entry->refreshing;
pnew_entry->refreshing = NULL;
assert(pnew_entry == pentry->refreshing);
LI_FORCE_ASSERT(pnew_entry == pentry->refreshing);
state = g_atomic_int_get(&pentry->state);
assert(LI_ENTRY_REFRESH_OLD == state || LI_ENTRY_REFRESH_INVALID == state);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_OLD == state || LI_ENTRY_REFRESH_INVALID == state);
if (LI_ENTRY_REFRESH_OLD == state) {
g_atomic_int_set(&pentry->state, LI_ENTRY_VALID);
append_to_lru(pentry);
@ -426,14 +426,14 @@ void li_fetch_entry_refresh_ready(liFetchEntry *new_entry) {
if (LI_ENTRY_INVALID == state) goto out;
assert(LI_ENTRY_REFRESH_NEW == state);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW == state);
pentry = pnew_entry->refreshing;
pnew_entry->refreshing = NULL;
assert(pnew_entry == pentry->refreshing);
LI_FORCE_ASSERT(pnew_entry == pentry->refreshing);
state = g_atomic_int_get(&pentry->state);
assert(LI_ENTRY_REFRESH_OLD == state || LI_ENTRY_REFRESH_INVALID == state);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_OLD == state || LI_ENTRY_REFRESH_INVALID == state);
wait_queue = entry_extract_wait_queue(pnew_entry);
@ -460,7 +460,7 @@ gboolean li_fetch_entry_revalidate(liFetchEntry *entry) {
liFetchDatabase *db = pentry->db;
liFetchEntryState state = g_atomic_int_get(&pentry->state);
assert(LI_ENTRY_REFRESH_NEW != state);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW != state);
switch (state) {
case LI_ENTRY_LOOKUP:
return FALSE;
@ -506,7 +506,7 @@ liFetchEntry* li_fetch_get2(liFetchDatabase* db, GString *key, liFetchWakeupCB w
liFetchEntryP *result = NULL;
liFetchEntryState state;
assert(NULL != wakeup);
LI_FORCE_ASSERT(NULL != wakeup);
g_mutex_lock(db->lock);
@ -536,7 +536,7 @@ liFetchEntry* li_fetch_get2(liFetchDatabase* db, GString *key, liFetchWakeupCB w
pentry_new = pentry;
state = g_atomic_int_get(&pentry->state);
assert(LI_ENTRY_REFRESH_NEW != state);
LI_FORCE_ASSERT(LI_ENTRY_REFRESH_NEW != state);
switch (state) {
case LI_ENTRY_LOOKUP:
/* lookup in progress, just register wakeup */

2
src/common/jobqueue.c

@ -169,7 +169,7 @@ void li_job_now(liJobQueue *jq, liJob *job) {
/* unqueue if queued */
if (NULL != job->link.data) {
assert(jq == job->link.data);
LI_FORCE_ASSERT(jq == job->link.data);
g_queue_unlink(&jq->queue, &job->link);
job->link.data = NULL;
}

4
src/common/memcached.c

@ -835,14 +835,14 @@ static void li_memcached_con_free(liMemcachedCon* con) {
void li_memcached_con_release(liMemcachedCon* con) {
if (!con) return;
assert(g_atomic_int_get(&con->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&con->refcount) > 0);
if (g_atomic_int_dec_and_test(&con->refcount)) {
li_memcached_con_free(con);
}
}
void li_memcached_con_acquire(liMemcachedCon* con) {
assert(g_atomic_int_get(&con->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&con->refcount) > 0);
g_atomic_int_inc(&con->refcount);
}

5
src/common/mempool.c

@ -1,5 +1,6 @@
#include <lighttpd/mempool.h>
#include <lighttpd/utils.h>
#ifdef WITH_PROFILER
#include <lighttpd/profiler.h>
@ -224,7 +225,7 @@ static mp_magazine* mp_mag_new(mp_pool *pool) {
/* do NOT call with lock held */
static inline void mp_mag_release(mp_magazine *mag) {
if (!mag) return;
assert(g_atomic_int_get(&mag->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&mag->refcount) > 0);
if (g_atomic_int_dec_and_test(&mag->refcount)) {
MP_LOCK_FREE(mag->mutex);
g_slice_free(mp_magazine, mag);
@ -232,7 +233,7 @@ static inline void mp_mag_release(mp_magazine *mag) {
}
static inline void mp_mag_acquire(mp_magazine *mag) {
assert(g_atomic_int_get(&mag->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&mag->refcount) > 0);
g_atomic_int_inc(&mag->refcount);
}

8
src/common/profiler.c

@ -103,7 +103,7 @@ static gpointer profiler_try_malloc(gsize n_bytes) {
static gpointer profiler_malloc(gsize n_bytes) {
gpointer p = profiler_try_malloc(n_bytes);
assert(p);
LI_FORCE_ASSERT(p);
return p;
}
@ -137,7 +137,7 @@ static gpointer profiler_try_realloc(gpointer mem, gsize n_bytes) {
static gpointer profiler_realloc(gpointer mem, gsize n_bytes) {
gpointer p = profiler_try_realloc(mem, n_bytes);
assert(p);
LI_FORCE_ASSERT(p);
return p;
}
@ -157,13 +157,13 @@ static gpointer profiler_calloc(gsize n_blocks, gsize n_bytes) {
li_profiler_hashtable_insert(p, n_bytes);
}
assert(p);
LI_FORCE_ASSERT(p);
return p;
}
static void profiler_free(gpointer mem) {
assert(mem);
LI_FORCE_ASSERT(mem);
li_profiler_hashtable_remove(mem);
free(mem);
}

5
src/common/radix.c

@ -1,5 +1,6 @@
#include <lighttpd/radix.h>
#include <lighttpd/utils.h>
/* internal data is saved in "host"-order; search from high to low bit */
typedef guint32 rdxBase;
@ -87,13 +88,13 @@ gpointer li_radixtree_insert(liRadixTree *tree, const void *key, guint32 bits, g
/* split node */
liRadixNode *newnode;
guint32 width = (node->width > bits) ? bits : node->width;
assert(width <= RDXBITS);
LI_FORCE_ASSERT(width <= RDXBITS);
mask = RDX_MASK(width);
while ((current & mask) != (node->key & mask)) {
width--;
mask <<= 1;
}
assert(width <= RDXBITS-1);
LI_FORCE_ASSERT(width <= RDXBITS-1);
newnode = g_slice_new0(liRadixNode);
newnode->width = width;
newnode->key = current & mask;

64
src/common/utils.c

@ -15,9 +15,67 @@ union fdmsg {
gchar buf[1000];
};
#ifdef HAVE_LIBUNWIND
# define UNW_LOCAL_ONLY
# include <libunwind.h>
void li_print_backtrace_stderr(void) {
unw_cursor_t cursor;
unw_context_t context;
unw_proc_info_t procinfo;
unw_word_t proc_offset;
void *proc_ip;
char procname[256];
int ret;
unsigned int frame = 0;
if (0 != (ret = unw_getcontext(&context))) goto error;
if (0 != (ret = unw_init_local(&cursor, &context))) goto error;
fprintf(stderr, "Backtrace:\n");
while (0 < (ret = unw_step(&cursor))) {
if (0 != (ret = unw_get_proc_info(&cursor, &procinfo))) goto error;
if (0 != (ret = unw_get_proc_name(&cursor, procname, sizeof(procname), &proc_offset))) {
switch (-ret) {
case UNW_ENOMEM:
memset(procname + sizeof(procname) - 4, '.', 3);
procname[sizeof(procname) - 1] = '\0';
break;
case UNW_ENOINFO:
procname[0] = '?';
procname[1] = '\0';
proc_offset = 0;
break;
default:
goto error;
}
}
++frame;
proc_ip = (void*) (intptr_t) (procinfo.start_ip + proc_offset);
fprintf(stderr, "%u: %s (+0x%x) [%p]\n", frame, procname, (unsigned int) proc_offset, proc_ip);
}
if (0 != ret) goto error;
return;
error:
fprintf(stderr, "Error while generating backtrace: unwind error %i\n", (int) -ret);
}
#else
void li_print_backtrace_stderr(void) {
}
#endif
void li_fatal(const gchar* msg) {
fprintf(stderr, "%s\n", msg);
void li_fatal(const char *filename, unsigned int line, const char *function, const gchar* msg) {
if (!filename || !filename[0]) filename = "<unknown file>";
if (!function || !function[0]) function = "<unknown function>";
fprintf(stderr, "[%lu] %s:%u: %s: %s\n",
(gulong) getpid(), LI_REMOVE_PATH(filename), line, function, msg);
li_print_backtrace_stderr();
abort();
}
@ -960,7 +1018,7 @@ void li_safe_crypt(GString *dest, const GString *password, const GString *salt)
void li_g_queue_merge(GQueue *dest, GQueue *src) {
assert(dest != src);
LI_FORCE_ASSERT(dest != src);
if (g_queue_is_empty(src)) return; /* nothing to do */
/* if dest is empty, just swap dest / src */

7
src/common/value.c

@ -1,6 +1,7 @@
#define _LIGHTTPD_COMMON_VALUE_C_
#include <lighttpd/value.h>
#include <lighttpd/utils.h>
liValue* li_value_new_none(void) {
liValue *v = g_slice_new0(liValue);
@ -51,13 +52,13 @@ GHashTable *li_value_new_hashtable(void) {
}
void li_value_list_append(liValue *list, liValue *item) {
assert(LI_VALUE_LIST == list->type);
LI_FORCE_ASSERT(LI_VALUE_LIST == list->type);
g_ptr_array_add(list->data.list, item);
}
void li_value_wrap_in_list(liValue *val) {
liValue *item;
assert(NULL != val);
LI_FORCE_ASSERT(NULL != val);
item = li_value_extract(val);
val->type = LI_VALUE_LIST;
@ -117,7 +118,7 @@ void li_value_free(liValue* val) {
}
void li_value_move(liValue *dest, liValue *src) {
assert(NULL != dest && NULL != src && dest != src);
LI_FORCE_ASSERT(NULL != dest && NULL != src && dest != src);
li_value_clear(dest);
*dest = *src;
_li_value_clear(src);

3
src/config.h.cmake

@ -105,6 +105,9 @@
#cmakedefine HAVE_LUA_H
#cmakedefine HAVE_LIBLUA
/* libunwind */
#cmakedefine HAVE_LIBUNWIND
/* inotify */
#cmakedefine HAVE_INOTIFY_INIT
#cmakedefine HAVE_SYS_INOTIFY_H

8
src/main/actions.c

@ -15,7 +15,7 @@ struct action_stack_element {
void li_action_release(liServer *srv, liAction *a) {
guint i;
if (!a) return;
assert(g_atomic_int_get(&a->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&a->refcount) > 0);
if (g_atomic_int_dec_and_test(&a->refcount)) {
switch (a->type) {
case LI_ACTION_TNOTHING:
@ -52,7 +52,7 @@ void li_action_release(liServer *srv, liAction *a) {
}
void li_action_acquire(liAction *a) {
assert(g_atomic_int_get(&a->refcount) > 0);
LI_FORCE_ASSERT(g_atomic_int_get(&a->refcount) > 0);
g_atomic_int_inc(&a->refcount);
}
@ -140,8 +140,8 @@ liAction *li_action_new_balancer(liBackendSelectCB bselect, liBackendFallbackCB
}
void li_action_append_inplace(liAction *list, liAction *element) {
assert(NULL != list && NULL != element);
assert(1 == g_atomic_int_get(&list->refcount));
LI_FORCE_ASSERT(NULL != list && NULL != element);
LI_FORCE_ASSERT(1 == g_atomic_int_get(&list->refcount));
if (LI_ACTION_TLIST != list->type) {
liAction *wrapped = NULL;

48
src/main/backends.c

@ -105,9 +105,9 @@ static void S_backend_pool_worker_remove_con(liBackendPool_p *pool, liBackendCon
gint last_reserved_ndx = last_active_ndx + wpool->reserved;
gint last_idle_ndx = last_reserved_ndx + wpool->idle;
assert(con->ndx >= 0 && (guint)con->ndx < wpool->connections->len);
assert(g_ptr_array_index(wpool->connections, con->ndx) == con);
assert(last_idle_ndx == (gint) wpool->connections->len - 1);
LI_FORCE_ASSERT(con->ndx >= 0 && (guint)con->ndx < wpool->connections->len);
LI_FORCE_ASSERT(g_ptr_array_index(wpool->connections, con->ndx) == con);
LI_FORCE_ASSERT(last_idle_ndx == (gint) wpool->connections->len - 1);
if (ndx <= last_active_ndx) {
--wpool->active;
@ -205,7 +205,7 @@ static void S_backend_pool_worker_insert_con(liBackendPool_p *pool, liWorker *wr
con->ndx = wpool->active + wpool->reserved;
}
g_ptr_array_index(wpool->connections, con->ndx) = con;
assert(con->ndx == min_ndx);
LI_FORCE_ASSERT(con->ndx == min_ndx);
} else if (con->ndx > max_ndx) {
if ((guint) con->ndx > wpool->active + wpool->reserved - 1) {
liBackendConnection_p *move = g_ptr_array_index(wpool->connections, wpool->active + wpool->reserved - 1);
@ -220,9 +220,9 @@ static void S_backend_pool_worker_insert_con(liBackendPool_p *pool, liWorker *wr
con->ndx = wpool->active - 1;
}
g_ptr_array_index(wpool->connections, con->ndx) = con;
assert(con->ndx == max_ndx);
LI_FORCE_ASSERT(con->ndx == max_ndx);
} else {
assert(con->ndx >= min_ndx && con->ndx <= max_ndx);
LI_FORCE_ASSERT(con->ndx >= min_ndx && con->ndx <= max_ndx);
}
}
@ -516,7 +516,7 @@ static void S_backend_pool_distribute(liBackendPool_p *pool, liWorker *wrk) {
guint src = 0;
guint i;
assert(pool->idle >= use);
LI_FORCE_ASSERT(pool->idle >= use);
for (i = 0; i < worker_count; ++i) {
liBackendWorkerPool *wpool = &pool->worker_pools[i];
@ -527,7 +527,7 @@ static void S_backend_pool_distribute(liBackendPool_p *pool, liWorker *wrk) {
while (0 == pool->worker_pools[src].idle) {
++src;
assert(src < worker_count);
LI_FORCE_ASSERT(src < worker_count);
}
srcpool = &pool->worker_pools[src];
con = g_ptr_array_index(srcpool->connections, srcpool->active + srcpool->reserved);
@ -650,7 +650,7 @@ static void backend_pool_worker_run_reserved(liBackendWorkerPool *wpool) {
liBackendConnection_p *con = g_ptr_array_index(wpool->connections, wpool->active);
if (NULL == con->worker) {
/* attach */
assert(con->worker_next == wrk);
LI_FORCE_ASSERT(con->worker_next == wrk);
con->worker = wrk;
con->worker_next = NULL;
@ -671,10 +671,10 @@ static void backend_pool_worker_run_reserved(liBackendWorkerPool *wpool) {
}
}
assert(NULL != con->wait);
LI_FORCE_ASSERT(NULL != con->wait);
if (NULL == con->worker_next) {
assert(con->wait->vr->wrk == wrk);
LI_FORCE_ASSERT(con->wait->vr->wrk == wrk);
if (!con->active) {
con->active = TRUE;
S_backend_pool_worker_insert_con(pool, wrk, con);
@ -795,7 +795,7 @@ static void backend_pool_worker_init_done(gpointer cbdata, gpointer fdata, GPtrA
}
static void S_backend_pool_init(liWorker *wrk, liBackendPool_p *pool) {
assert(!pool->shutdown);
LI_FORCE_ASSERT(!pool->shutdown);
if (pool->initialized) return;
@ -847,10 +847,10 @@ static gpointer backend_pool_worker_shutdown(liWorker *wrk, gpointer fdata) {
}
li_waitqueue_stop(&wpool->connect_queue);
assert(0 == wpool->active);
assert(0 == wpool->reserved);
assert(0 == wpool->idle);
assert(0 == wpool->pending);
LI_FORCE_ASSERT(0 == wpool->active);
LI_FORCE_ASSERT(0 == wpool->reserved);
LI_FORCE_ASSERT(0 == wpool->idle);
LI_FORCE_ASSERT(0 == wpool->pending);
g_ptr_array_free(wpool->connections, TRUE);
@ -892,8 +892,8 @@ void li_backend_pool_free(liBackendPool *bpool) {
g_mutex_lock(pool->lock);
assert(0 == pool->active);
assert(!pool->shutdown);
LI_FORCE_ASSERT(0 == pool->active);
LI_FORCE_ASSERT(!pool->shutdown);
pool->shutdown = TRUE;
@ -916,8 +916,8 @@ liBackendResult li_backend_get(liVRequest *vr, liBackendPool *bpool, liBackendCo
liBackendResult result = LI_BACKEND_TIMEOUT;
liBackendWait *bwait = NULL;
assert(pbcon);
assert(pbwait);
LI_FORCE_ASSERT(pbcon);
LI_FORCE_ASSERT(pbwait);
g_mutex_lock(pool->lock);
S_backend_pool_init(vr->wrk, pool);
@ -926,7 +926,7 @@ liBackendResult li_backend_get(liVRequest *vr, liBackendPool *bpool, liBackendCo
if (*pbwait) {
bwait = *pbwait;
assert(vr == bwait->vr);