with_pcap_include_dir
with_collectdclient_lib_dir
with_collectdclient_include_dir
+with_cap_lib_dir
+with_cap_include_dir
with_execinfo_lib_dir
with_execinfo_include_dir
with_pcre_lib_dir
--with-collectdclient-include-dir=DIR
directory in which to look for collectdclient
include files
+ --with-cap-lib-dir=DIR directory in which to look for cap library files
+ --with-cap-include-dir=DIR
+ directory in which to look for cap include files
--with-execinfo-lib-dir=DIR
directory in which to look for execinfo library
files
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
fi
LIBS="${old_LIBS}"
+cap_lib_dir=
+
+# Check whether --with-cap-lib-dir was given.
+if test "${with_cap_lib_dir+set}" = set; then :
+ withval=$with_cap_lib_dir; case "$withval" in
+ no)
+ as_fn_error $? "Need cap-lib-dir" "$LINENO" 5
+ ;;
+ yes)
+ ;;
+ *)
+ cap_lib_dir="$withval"
+ ;;
+ esac
+fi
+
+
+cap_include_dir=
+
+# Check whether --with-cap-include-dir was given.
+if test "${with_cap_include_dir+set}" = set; then :
+ withval=$with_cap_include_dir; case "$withval" in
+ no)
+ as_fn_error $? "Need cap-include-dir" "$LINENO" 5
+ ;;
+ yes)
+ ;;
+ *)
+ cap_include_dir="$withval"
+ ;;
+ esac
+fi
+
+
+smart_try_dir="$cap_lib_dir"
+
+
+sm_lib_safe=`echo "cap" | sed 'y%./+-%__p_%'`
+sm_func_safe=`echo "cap_get_proc" | sed 'y%./+-%__p_%'`
+
+old_LIBS="$LIBS"
+old_CPPFLAGS="$CPPFLAGS"
+smart_lib=
+smart_ldflags=
+smart_lib_dir=
+
+if test "x$smart_try_dir" != "x"; then
+ for try in $smart_try_dir; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_get_proc in -lcap in $try" >&5
+$as_echo_n "checking for cap_get_proc in -lcap in $try... " >&6; }
+ LIBS="-lcap $old_LIBS"
+ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern char cap_get_proc();
+int
+main ()
+{
+cap_get_proc()
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ smart_lib="-lcap"
+ smart_ldflags="-L$try -Wl,-rpath,$try"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ break
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ LIBS="$old_LIBS"
+ CPPFLAGS="$old_CPPFLAGS"
+fi
+
+if test "x$smart_lib" = "x"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_get_proc in -lcap" >&5
+$as_echo_n "checking for cap_get_proc in -lcap... " >&6; }
+ LIBS="-lcap $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern char cap_get_proc();
+int
+main ()
+{
+cap_get_proc()
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ smart_lib="-lcap"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$old_LIBS"
+fi
+
+if test "x$smart_lib" = "x"; then
+
+
+if test "x$LOCATE" != "x"; then
+ DIRS=
+ file=libcap${libltdl_cv_shlibext}
+
+ for x in `${LOCATE} $file 2>/dev/null`; do
+ base=`echo $x | sed "s%/${file}%%"`
+ if test "x$x" = "x$base"; then
+ continue;
+ fi
+
+ dir=`${DIRNAME} $x 2>/dev/null`
+ exclude=`echo ${dir} | ${GREP} /home`
+ if test "x$exclude" != "x"; then
+ continue
+ fi
+
+ already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+ if test "x$already" = "x"; then
+ DIRS="$DIRS $dir"
+ fi
+ done
+fi
+
+eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+
+
+
+if test "x$LOCATE" != "x"; then
+ DIRS=
+ file=libcap.a
+
+ for x in `${LOCATE} $file 2>/dev/null`; do
+ base=`echo $x | sed "s%/${file}%%"`
+ if test "x$x" = "x$base"; then
+ continue;
+ fi
+
+ dir=`${DIRNAME} $x 2>/dev/null`
+ exclude=`echo ${dir} | ${GREP} /home`
+ if test "x$exclude" != "x"; then
+ continue
+ fi
+
+ already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+ if test "x$already" = "x"; then
+ DIRS="$DIRS $dir"
+ fi
+ done
+fi
+
+eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+
+
+ for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_get_proc in -lcap in $try" >&5
+$as_echo_n "checking for cap_get_proc in -lcap in $try... " >&6; }
+ LIBS="-lcap $old_LIBS"
+ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern char cap_get_proc();
+int
+main ()
+{
+cap_get_proc()
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ smart_lib="-lcap"
+ smart_ldflags="-L$try -Wl,-rpath,$try"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ break
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ LIBS="$old_LIBS"
+ CPPFLAGS="$old_CPPFLAGS"
+fi
+
+if test "x$smart_lib" != "x"; then
+ eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+ LIBS="$smart_ldflags $smart_lib $old_LIBS"
+ SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
+fi
+
+if test "x$ac_cv_lib_cap_cap_get_proc" != "xyes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cap library not found, debugger checks will not be enabled. Use --with-cap-lib-dir=<path>." >&5
+$as_echo "$as_me: WARNING: cap library not found, debugger checks will not be enabled. Use --with-cap-lib-dir=<path>." >&2;}
+else
+
+$as_echo "#define HAVE_LIBCAP 1" >>confdefs.h
+
+ HAVE_LIBCAP=1
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a readline compatible library" >&5
$as_echo_n "checking for a readline compatible library... " >&6; }
fi
fi
+if test "x$HAVE_LIBCAP" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: skipping test for cap.h." >&5
+$as_echo "$as_me: skipping test for cap.h." >&6;}
+else
+ smart_try_dir="$cap_include_dir"
+
+
+ac_safe=`echo "sys/capability.h" | sed 'y%./+-%__pm%'`
+old_CPPFLAGS="$CPPFLAGS"
+smart_include=
+smart_include_dir="/usr/local/include /opt/include"
+
+_smart_try_dir=
+_smart_include_dir=
+
+for _prefix in $smart_prefix ""; do
+ for _dir in $smart_try_dir; do
+ _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
+ done
+
+ for _dir in $smart_include_dir; do
+ _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
+ done
+done
+
+if test "x$_smart_try_dir" != "x"; then
+ for try in $_smart_try_dir; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/capability.h in $try" >&5
+$as_echo_n "checking for sys/capability.h in $try... " >&6; }
+ CPPFLAGS="-isystem $try $old_CPPFLAGS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <sys/capability.h>
+int
+main ()
+{
+int a = 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ smart_include="-isystem $try"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ break
+
+else
+
+ smart_include=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ CPPFLAGS="$old_CPPFLAGS"
+fi
+
+if test "x$smart_include" = "x"; then
+ for _prefix in $smart_prefix; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/sys/capability.h" >&5
+$as_echo_n "checking for ${_prefix}/sys/capability.h... " >&6; }
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <sys/capability.h>
+int
+main ()
+{
+int a = 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ smart_include="-isystem ${_prefix}/"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ break
+
+else
+
+ smart_include=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+fi
+
+if test "x$smart_include" = "x"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/capability.h" >&5
+$as_echo_n "checking for sys/capability.h... " >&6; }
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <sys/capability.h>
+int
+main ()
+{
+int a = 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ smart_include=" "
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ break
+
+else
+
+ smart_include=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "x$smart_include" = "x"; then
+
+ for prefix in $smart_prefix; do
+
+
+if test "x$LOCATE" != "x"; then
+ DIRS=
+ file="${_prefix}/${1}"
+
+ for x in `${LOCATE} $file 2>/dev/null`; do
+ base=`echo $x | sed "s%/${file}%%"`
+ if test "x$x" = "x$base"; then
+ continue;
+ fi
+
+ dir=`${DIRNAME} $x 2>/dev/null`
+ exclude=`echo ${dir} | ${GREP} /home`
+ if test "x$exclude" != "x"; then
+ continue
+ fi
+
+ already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+ if test "x$already" = "x"; then
+ DIRS="$DIRS $dir"
+ fi
+ done
+fi
+
+eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
+
+ done
+
+
+if test "x$LOCATE" != "x"; then
+ DIRS=
+ file=sys/capability.h
+
+ for x in `${LOCATE} $file 2>/dev/null`; do
+ base=`echo $x | sed "s%/${file}%%"`
+ if test "x$x" = "x$base"; then
+ continue;
+ fi
+
+ dir=`${DIRNAME} $x 2>/dev/null`
+ exclude=`echo ${dir} | ${GREP} /home`
+ if test "x$exclude" != "x"; then
+ continue
+ fi
+
+ already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+ if test "x$already" = "x"; then
+ DIRS="$DIRS $dir"
+ fi
+ done
+fi
+
+eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
+
+
+ for try in $_smart_include_dir; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/capability.h in $try" >&5
+$as_echo_n "checking for sys/capability.h in $try... " >&6; }
+ CPPFLAGS="-isystem $try $old_CPPFLAGS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <sys/capability.h>
+int
+main ()
+{
+int a = 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ smart_include="-isystem $try"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ break
+
+else
+
+ smart_include=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ CPPFLAGS="$old_CPPFLAGS"
+fi
+
+if test "x$smart_include" != "x"; then
+ eval "ac_cv_header_$ac_safe=yes"
+ CPPFLAGS="$smart_include $old_CPPFLAGS"
+ SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
+fi
+
+smart_prefix=
+
+ if test "x$ac_cv_header_sys_capability_h" == "xyes"; then
+
+$as_echo "#define HAVE_CAPABILITY_H 1" >>confdefs.h
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cap headers not found, will not perform debugger checks. Use --with-cap-include-dir=<path>." >&5
+$as_echo "$as_me: WARNING: cap headers not found, will not perform debugger checks. Use --with-cap-include-dir=<path>." >&2;}
+ fi
+fi
+
ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
if test "x$ac_cv_type_off_t" = xyes; then :
fr_fault_log_t fr_fault_log = _fr_fault_log; //!< Function to use to process logging output.
static int fr_fault_log_fd = STDERR_FILENO; //!< Where to write debug output.
-static int debugger_attached = -1; //!< Whether were attached to by a debugger.
+fr_debug_state_t fr_debug_state = DEBUG_STATE_UNKNOWN; //!< Whether were attached to by a debugger.
#ifdef HAVE_SYS_RESOURCE_H
static struct rlimit core_limits;
# define _PTRACE(_x, _y) ptrace(_x, _y, NULL, 0)
# endif
+# ifdef HAVE_CAPABILITY_H
+# include <sys/capability.h>
+# endif
+
/** Determine if we're running under a debugger by attempting to attach using pattach
*
- * @return 0 if we're not, EPERM if we are, -1 if we can't tell.
+ * @return 0 if we're not, 1 if we are, -1 if we can't tell because of an error,
+ * -2 if we can't tell because we don't have the CAP_SYS_PTRACE capability.
*/
-static int fr_debugger_attached(void)
+static int fr_get_debug_state(void)
{
int pid;
int from_child[2] = {-1, -1};
+#ifdef HAVE_CAPABILITY_H
+ cap_flag_value_t value;
+ cap_t current;
+
+ /*
+ * If we're running under linux, we first need to check if we have
+ * permission to to ptrace. We do that using the capabilities
+ * functions.
+ */
+ current = cap_get_proc();
+ if (!current) {
+ fr_strerror_printf("Failed getting process capabilities: %s", fr_syserror(errno));
+ return DEBUG_STATE_UNKNOWN;
+ }
+
+ if (cap_get_flag(current, CAP_SYS_PTRACE, CAP_PERMITTED, &value) < 0) {
+ fr_strerror_printf("Failed getting permitted ptrace capability state: %s",
+ fr_syserror(errno));
+ cap_free(current);
+ return DEBUG_STATE_UNKNOWN;
+ }
+
+ if ((value == CAP_SET) && (cap_get_flag(current, CAP_SYS_PTRACE, CAP_EFFECTIVE, &value) < 0)) {
+ fr_strerror_printf("Failed getting effective ptrace capability state: %s",
+ fr_syserror(errno));
+ cap_free(current);
+ return DEBUG_STATE_UNKNOWN;
+ }
+
+ /*
+ * We don't have permission to ptrace, so this test will always fail.
+ */
+ if (value == CAP_CLEAR) {
+ fr_strerror_printf("ptrace capability not set. If debugger detection is required run as root or: "
+ "setcap cap_sys_ptrace+ep <path_to_radiusd>");
+ cap_free(current);
+ return DEBUG_STATE_UNKNOWN_NO_PTRACE_CAP;
+ }
+ cap_free(current);
+#endif
+
if (pipe(from_child) < 0) {
- fr_strerror_printf("Debugger check failed: Error opening internal pipe: %s", fr_syserror(errno));
- return -1;
+ fr_strerror_printf("Error opening internal pipe: %s", fr_syserror(errno));
+ return DEBUG_STATE_UNKNOWN;
}
pid = fork();
if (pid == -1) {
- fr_strerror_printf("Debugger check failed: Error forking: %s", fr_syserror(errno));
- return -1;
+ fr_strerror_printf("Error forking: %s", fr_syserror(errno));
+ return DEBUG_STATE_UNKNOWN;
}
/* Child */
if (pid == 0) {
- int ret = 0;
+ int8_t ret = DEBUG_STATE_NOT_ATTACHED;
int ppid = getppid();
/* Close parent's side */
exit(0);
}
- ret = errno;
+ ret = DEBUG_STATE_ATTACHED;
/* Tell the parent what happened */
if (write(from_child[1], &ret, sizeof(ret)) < 0) {
fprintf(stderr, "Writing ptrace status to parent failed: %s", fr_syserror(errno));
exit(0);
/* Parent */
} else {
- int ret = -1;
+ int8_t ret = DEBUG_STATE_UNKNOWN;
/*
* The child writes errno (reason) if pattach failed else 0.
*/
while ((read(from_child[0], &ret, sizeof(ret)) < 0) && (errno == EINTR));
- /* Ret not updated */
- if (ret < 0) {
- fr_strerror_printf("Debugger check failed: Error getting status from child: %s",
- fr_syserror(errno));
- } else {
- fr_strerror_printf("Failed attaching to process: %s", fr_syserror(errno));
- }
-
/* Close the pipes here (if we did it above, it might race with pattach) */
close(from_child[1]);
close(from_child[0]);
}
}
#else
-static int fr_debugger_attached(void)
+static int fr_get_debug_state(void)
{
- fr_strerror_printf("Debugger check failed: PTRACE not available");
+ fr_strerror_printf("PTRACE not available");
- return -1;
+ return DEBUG_STATE_UNKNOWN_NO_PTRACE;
}
#endif
+/** Should be run before using setuid or setgid to get useful results
+ *
+ * @note sets the fr_debug_state global.
+ */
+void fr_store_debug_state(void)
+{
+ fr_debug_state = fr_get_debug_state();
+
+#ifndef NDEBUG
+ /*
+ * There are many reasons why this might happen with
+ * a vanilla install, so we don't want to spam users
+ * with messages they won't understand and may not
+ * want to resolve.
+ */
+ if (fr_debug_state < 0) fprintf(stderr, "Getting debug state failed: %s\n", fr_strerror());
+#endif
+}
+
+/** Return current value of debug_state
+ *
+ * @param state to translate into a humanly readable value.
+ * @return humanly readable version of debug state.
+ */
+char const *fr_debug_state_to_msg(fr_debug_state_t state)
+{
+ switch (state) {
+ case DEBUG_STATE_UNKNOWN_NO_PTRACE:
+ return "Debug state unknown (ptrace functionality not available)";
+
+ case DEBUG_STATE_UNKNOWN_NO_PTRACE_CAP:
+ return "Debug state unknown (cap_sys_ptrace capability not set)";
+
+ case DEBUG_STATE_UNKNOWN:
+ return "Debug state unknown";
+
+ case DEBUG_STATE_ATTACHED:
+ return "Found debugger attached";
+
+ case DEBUG_STATE_NOT_ATTACHED:
+ return "Debugger not attached";
+ }
+
+ return "<INVALID>";
+}
+
/** Break in debugger (if were running under a debugger)
*
* If the server is running under a debugger this will raise a
*/
void fr_debug_break(void)
{
- if (debugger_attached == -1) {
- debugger_attached = fr_debugger_attached();
- }
-
- if (debugger_attached == 1) {
+ if (fr_debug_state < 0) fr_debug_state = fr_get_debug_state();
+ if (fr_debug_state == DEBUG_STATE_ATTACHED) {
fprintf(stderr, "Debugger detected, raising SIGTRAP\n");
fflush(stderr);
* The only exception are SIGUSR1 and SIGUSR2 which print out various
* debugging info, and should be allowed to continue.
*/
- if (debugger_attached && (sig != SIGUSR1) && (sig != SIGUSR2)) {
+ if (fr_debug_state && (sig != SIGUSR1) && (sig != SIGUSR2)) {
FR_FAULT_LOG("RAISING SIGNAL: %s", strsignal(sig));
raise(sig);
goto finish;
/* Unsure what the side effects of changing the signal handler mid execution might be */
if (!setup) {
- int ret;
-
/*
* Setup the default logger
*/
/*
* Figure out if we were started under a debugger
*/
-
- ret = fr_debugger_attached();
+ if (fr_debug_state < 0) fr_debug_state = fr_get_debug_state();
/*
* These signals can't be properly dealt with in the debugger
- * if we set our own signal handlers
+ * if we set our own signal handlers.
*/
- if (ret == 0) {
- debugger_attached = 0;
+ switch (fr_debug_state) {
+ default:
+#ifndef NDEBUG
+ FR_FAULT_LOG("Debugger check failed: %s", fr_strerror());
+ FR_FAULT_LOG("Signal processing in debuggers may not work as expected");
+#endif
+
+ case 0:
#ifdef SIGABRT
if (fr_set_signal(SIGABRT, fr_fault) < 0) return -1;
#ifdef SIGSEGV
if (fr_set_signal(SIGSEGV, fr_fault) < 0) return -1;
#endif
+ break;
-
- } else {
- debugger_attached = 1;
-
- FR_FAULT_LOG("Not enabling panic action signal handlers: %s", fr_strerror());
+ case 1:
+ break;
}
#ifdef SIGUSR1
if (fr_set_signal(SIGUSR1, fr_fault) < 0) return -1;