diff --git a/configure.in b/configure.in index 5ca01661..f3a924f2 100644 --- a/configure.in +++ b/configure.in @@ -550,6 +550,30 @@ AC_SUBST(HAVE_GMOZ) AC_SUBST(GMOZ_INC) AC_SUBST(GMOZ_LIB) +HAVE_COREDUMPER=no +COREDUMPER_INC="" +COREDUMPER_LIB="" +AC_ARG_WITH(coredumper,AC_HELP_STRING([--with-coredumper],[use Google coredumper if available (default)]),[ac_cv_use_coredumper=$withval],[ac_cv_use_coredumper=yes]) +gcdinc="include/google/coredumper.h" +if [[ "x$ac_cv_use_coredumper" = "xyes" ]]; then +for i in /usr /usr/local; do + ac_cv_use_coredumper="$i" + test -f "$ac_cv_use_coredumper/$gcdinc" && break +done +fi +if [[ "x$ac_cv_use_coredumper" != "xno" ]]; then +AC_MSG_CHECKING([for coredumper.h in $ac_cv_use_coredumper]) +if [[ -f "$ac_cv_use_coredumper/$gcdinc" ]]; then + HAVE_COREDUMPER=yes + COREDUMPER_INC="-I$ac_cv_use_coredumper" + COREDUMPER_LIB="-L$ac_cv_use_coredumper -lcoredumper" +fi +AC_MSG_RESULT([$HAVE_COREDUMPER]) +fi +AC_SUBST(HAVE_COREDUMPER) +AC_SUBST(COREDUMPER_INC) +AC_SUBST(COREDUMPER_LIB) + RTTI_OPT="" AC_ARG_ENABLE(rtti,AC_HELP_STRING([--enable-rtti],[Enable RTTI support (default: like pwlib)]),want_rtti=$enableval,want_rtti=auto) AC_MSG_CHECKING([whether to enable RTTI support]) diff --git a/modules/Makefile.in b/modules/Makefile.in index 2e959596..939f44fb 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -76,6 +76,11 @@ ifeq (@HAVE_GTK2@_@HAVE_GMOZ@,yes_yes) PROGS := $(PROGS) gtk2/gtk2mozilla.yate endif +ifeq (@HAVE_COREDUMPER@,yes) +COREDUMP_INC := -DHAVE_COREDUMPER @COREDUMPER_INC@ +COREDUMP_LIB := @COREDUMPER_LIB@ +endif + LOCALFLAGS = LOCALLIBS = COMPILE = $(CXX) $(DEFS) $(DEBUG) $(INCLUDES) $(CFLAGS) @@ -203,6 +208,9 @@ gtk2/gtk2mozilla.yate: @top_srcdir@/contrib/gtk2/gtk2client.h gtk2/gtk2mozilla.yate: LOCALFLAGS = @GTK2_INC@ @GMOZ_INC@ -I@top_srcdir@/contrib/gtk2 gtk2/gtk2mozilla.yate: LOCALLIBS = @GMOZ_LIB@ +rmanager.yate: LOCALFLAGS = $(COREDUMP_INC) +rmanager.yate: LOCALLIBS = $(COREDUMP_LIB) + ../contrib/iax/libiax.a: $(MAKE) -C ../contrib/iax diff --git a/modules/rmanager.cpp b/modules/rmanager.cpp index 5b0da889..9cfc3652 100644 --- a/modules/rmanager.cpp +++ b/modules/rmanager.cpp @@ -32,6 +32,10 @@ #include #include +#ifdef HAVE_COREDUMPER +#include +#endif + using namespace TelEngine; static const char s_helpmsg[] = @@ -46,6 +50,9 @@ static const char s_helpmsg[] = " auth password\n" "Authenticated commands:\n" " debug [level|on|off]\n" +#ifdef HAVE_COREDUMPER +" coredump [filename]\n" +#endif " drop {chan|*|all}\n" " call chan target\n" " reload\n" @@ -274,6 +281,9 @@ bool Connection::processLine(const char *line) if ((str == "\\") || (str == "\033[A") || (str == "\033[1A") || (str == "\033A")) { if (m_lastcmd.null()) return false; + // display up arrow, clear to EOL, last command + str = "\033[A\033[K" + m_lastcmd + "\n"; + writeStr(str); str = m_lastcmd; } else @@ -470,6 +480,37 @@ bool Connection::processLine(const char *line) } writeStr(str); } +#ifdef HAVE_COREDUMPER + else if (str.startSkip("coredump")) + { + if (str.null()) + (str << "core.yate-" << ::getpid() << "-").append(SysUsage::runTime()); + s_mutex.lock(); + int err = 0; + for (int i = 0; i < 4; i++) { + if (!WriteCoreDump(str)) { + err = 0; + break; + } + err = errno; + switch (err) { + case EINTR: + case EAGAIN: + case ECHILD: + continue; + } + break; + } + if (err) { + str = "Failed to dump core: "; + str << ::strerror(err) << " (" << err << ")\n"; + } + else + str = "Dumped core to: " + str + "\n"; + s_mutex.unlock(); + writeStr(str); + } +#endif else if (str.startSkip("reload")) { writeStr(m_machine ? "%%=reload\n" : "Reinitializing...\n");