Currently, failures of pthread_* functions are printed to stderr only and then OVS aborts. These error messages are hard to find and may be even just lost.
Use VLOG_ABORT() instead. It will do the same thing, but will try to log the error to the log file and syslog first, if configured. Using VLOG_ABORT() instead of VLOG_FATAL() to preserve the abort() logic and not just exit with a failure code, because it's likely we want a core dump if one of these function failed. For example, we would like to have a stack trace in a core dump in case a mutex lock failed with 'deadlock avoided'. Signed-off-by: Ilya Maximets <[email protected]> --- Another thing we can do to improve debugability is to also dump the stack trace on ovs_abort. It will also help with debugging assertions on systems where coredumps are disabled for some reason. But it's a separate topic. lib/ovs-thread.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c index ac5d2c3d0..f80008061 100644 --- a/lib/ovs-thread.c +++ b/lib/ovs-thread.c @@ -63,13 +63,14 @@ static bool multithreaded; \ /* Verify that 'l' was initialized. */ \ if (OVS_UNLIKELY(!l->where)) { \ - ovs_abort(0, "%s: %s() passed uninitialized ovs_"#TYPE, \ - where, __func__); \ + VLOG_ABORT("%s: %s() passed uninitialized ovs_"#TYPE, \ + where, __func__); \ } \ \ error = pthread_##TYPE##_##FUN(&l->lock); \ if (OVS_UNLIKELY(error)) { \ - ovs_abort(error, "%s: pthread_%s_%s failed", where, #TYPE, #FUN); \ + VLOG_ABORT("%s: pthread_%s_%s failed: %s", where, #TYPE, #FUN, \ + ovs_strerror(error)); \ } \ l->where = where; \ } @@ -91,13 +92,14 @@ LOCK_FUNCTION(spin, lock); \ /* Verify that 'l' was initialized. */ \ if (OVS_UNLIKELY(!l->where)) { \ - ovs_abort(0, "%s: %s() passed uninitialized ovs_"#TYPE, \ - where, __func__); \ + VLOG_ABORT("%s: %s() passed uninitialized ovs_"#TYPE, \ + where, __func__); \ } \ \ error = pthread_##TYPE##_##FUN(&l->lock); \ if (OVS_UNLIKELY(error) && error != EBUSY) { \ - ovs_abort(error, "%s: pthread_%s_%s failed", where, #TYPE, #FUN); \ + VLOG_ABORT("%s: pthread_%s_%s failed: %s", where, #TYPE, #FUN, \ + ovs_strerror(error)); \ } \ if (!error) { \ l->where = where; \ @@ -125,7 +127,8 @@ TRY_LOCK_FUNCTION(spin, trylock); l->where = WHERE; \ error = pthread_##TYPE##_##FUN(&l->lock); \ if (OVS_UNLIKELY(error)) { \ - ovs_abort(error, "pthread_%s_%s failed", #TYPE, #FUN); \ + VLOG_ABORT("%s: pthread_%s_%s failed: %s", l->where, #TYPE, #FUN, \ + ovs_strerror(error)); \ } \ } UNLOCK_FUNCTION(mutex, unlock, "<unlocked>"); @@ -143,7 +146,8 @@ UNLOCK_FUNCTION(spin, destroy, NULL); { \ int error = FUNCTION(arg1); \ if (OVS_UNLIKELY(error)) { \ - ovs_abort(error, "%s failed", #FUNCTION); \ + VLOG_ABORT("%s failed: %s", #FUNCTION, \ + ovs_strerror(error)); \ } \ } #define XPTHREAD_FUNC2(FUNCTION, PARAM1, PARAM2) \ @@ -152,7 +156,8 @@ UNLOCK_FUNCTION(spin, destroy, NULL); { \ int error = FUNCTION(arg1, arg2); \ if (OVS_UNLIKELY(error)) { \ - ovs_abort(error, "%s failed", #FUNCTION); \ + VLOG_ABORT("%s failed: %s", #FUNCTION, \ + ovs_strerror(error)); \ } \ } #define XPTHREAD_FUNC3(FUNCTION, PARAM1, PARAM2, PARAM3)\ @@ -161,7 +166,8 @@ UNLOCK_FUNCTION(spin, destroy, NULL); { \ int error = FUNCTION(arg1, arg2, arg3); \ if (OVS_UNLIKELY(error)) { \ - ovs_abort(error, "%s failed", #FUNCTION); \ + VLOG_ABORT("%s failed: %s", #FUNCTION, \ + ovs_strerror(error)); \ } \ } @@ -204,7 +210,7 @@ ovs_mutex_init__(const struct ovs_mutex *l_, int type) xpthread_mutexattr_settype(&attr, type); error = pthread_mutex_init(&l->lock, &attr); if (OVS_UNLIKELY(error)) { - ovs_abort(error, "pthread_mutex_init failed"); + VLOG_ABORT("pthread_mutex_init failed: %s", ovs_strerror(error)); } xpthread_mutexattr_destroy(&attr); } @@ -257,7 +263,7 @@ ovs_rwlock_init(const struct ovs_rwlock *l_) #endif if (OVS_UNLIKELY(error)) { - ovs_abort(error, "pthread_rwlock_init failed"); + VLOG_ABORT("pthread_rwlock_init failed: %s", ovs_strerror(error)); } } @@ -275,7 +281,7 @@ ovs_mutex_cond_wait(pthread_cond_t *cond, const struct ovs_mutex *mutex_) error = pthread_cond_wait(cond, &mutex->lock); if (OVS_UNLIKELY(error)) { - ovs_abort(error, "pthread_cond_wait failed"); + VLOG_ABORT("pthread_cond_wait failed: %s", ovs_strerror(error)); } } @@ -289,7 +295,7 @@ ovs_spin_init__(const struct ovs_spin *l_, int pshared) l->where = "<unlocked>"; error = pthread_spin_init(&l->lock, pshared); if (OVS_UNLIKELY(error)) { - ovs_abort(error, "pthread_spin_init failed"); + VLOG_ABORT("pthread_spin_init failed: %s", ovs_strerror(error)); } } @@ -431,13 +437,15 @@ set_min_stack_size(pthread_attr_t *attr, size_t min_stacksize) error = pthread_attr_getstacksize(attr, &stacksize); if (error) { - ovs_abort(error, "pthread_attr_getstacksize failed"); + VLOG_ABORT("pthread_attr_getstacksize failed: %s", + ovs_strerror(error)); } if (stacksize < min_stacksize) { error = pthread_attr_setstacksize(attr, min_stacksize); if (error) { - ovs_abort(error, "pthread_attr_setstacksize failed"); + VLOG_ABORT("pthread_attr_setstacksize failed: %s", + ovs_strerror(error)); } } } @@ -486,7 +494,7 @@ ovs_thread_create(const char *name, void *(*start)(void *), void *arg) error = pthread_create(&thread, &attr, ovsthread_wrapper, aux); if (error) { - ovs_abort(error, "pthread_create failed"); + VLOG_ABORT("pthread_create failed: %s", ovs_strerror(error)); } pthread_attr_destroy(&attr); return thread; -- 2.43.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
