#include <ctype.h>
#include <errno.h>
#include <netdb.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static Dl_info dli_main;
static int dli_main_done; // 0 = not resolved, 1 = resolve in progress, 2 = done
__decl_thread_var(static HA_SPINLOCK_T dladdr_lock);
+ sigset_t new_mask, old_mask;
int isolated;
Dl_info dli;
size_t size = 0;
HA_SPIN_TRYLOCK(OTHER_LOCK, &dladdr_lock) != 0)
goto use_array;
+ /* make sure we don't re-enter from wdt nor debug coming from other
+ * threads as dladdr() is not re-entrant. We'll block these sensitive
+ * signals while possibly dumping a backtrace.
+ */
+ sigemptyset(&new_mask);
+#ifdef WDTSIG
+ sigaddset(&new_mask, WDTSIG);
+#endif
+#ifdef DEBUGSIG
+ sigaddset(&new_mask, DEBUGSIG);
+#endif
+ ha_sigmask(SIG_BLOCK, &new_mask, &old_mask);
+
+ /* now resolve the symbol */
i = dladdr_and_size(addr, &dli, &size);
if (!i) {
+ /* unblock temporarily blocked signals */
+ ha_sigmask(SIG_SETMASK, &old_mask, NULL);
+
if (!isolated)
HA_SPIN_UNLOCK(OTHER_LOCK, &dladdr_lock);
goto use_array;
ha_thread_relax();
}
+ /* unblock temporarily blocked signals */
+ ha_sigmask(SIG_SETMASK, &old_mask, NULL);
+
if (!isolated)
HA_SPIN_UNLOCK(OTHER_LOCK, &dladdr_lock);