Repository: trafficserver
Updated Branches:
refs/heads/master efec3eb6f -> edff64d19
TS-3195: initial signal handling refactor
- Move features specific traffic_server from the generic signal
handling code to traffic_server main.
- Refactor signal handling into a small API and remove cruft for
systems that don't support sigaction(2).
- Move signal handling specific to traffic_server into traffic_server
main, adopting the small signal handling API.
- Update other apps that shared traffic_server's signal handling
policy. In most cases, these don't need to do
anything special with signal handling.
- Remove (now) unused proxy.config.stack_dump_enabled.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ecea9413
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ecea9413
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ecea9413
Branch: refs/heads/master
Commit: ecea94131bf29d645297c41e9661a876d53fae1e
Parents: efec3eb
Author: James Peach <[email protected]>
Authored: Wed Oct 29 11:19:38 2014 -0700
Committer: James Peach <[email protected]>
Committed: Thu Nov 13 09:18:28 2014 -0800
----------------------------------------------------------------------
configure.ac | 1 +
.../using-a-debugger.en.rst | 10 -
lib/perl/lib/Apache/TS/AdminClient.pm | 1 -
lib/ts/Makefile.am | 13 +-
lib/ts/ink_queue.h | 2 +
lib/ts/signals.cc | 220 ++++++++++
lib/ts/signals.h | 58 +++
mgmt/RecordsConfig.cc | 2 -
proxy/Main.cc | 173 +++++++-
proxy/Main.h | 1 -
proxy/Makefile.am | 5 -
proxy/logging/LogConfig.cc | 2 +-
proxy/logging/LogStandalone.cc | 19 +-
proxy/sac.cc | 13 +
proxy/shared/Makefile.am | 5 -
proxy/shared/signals.cc | 416 -------------------
proxy/shared/signals.h | 53 ---
17 files changed, 462 insertions(+), 532 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 044cf0a..6e8cf4f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1164,6 +1164,7 @@ fi
AC_CHECK_FUNCS([clock_gettime kqueue epoll_ctl posix_memalign posix_fadvise
posix_madvise posix_fallocate inotify_init])
AC_CHECK_FUNCS([lrand48_r srand48_r port_create strlcpy strlcat sysconf
getpagesize])
AC_CHECK_FUNCS([getreuid getresuid getresgid setreuid setresuid])
+AC_CHECK_FUNCS([strsignal psignal psiginfo])
# Check for eventfd() and sys/eventfd.h (both must exist ...)
AC_CHECK_HEADERS([sys/eventfd.h], [
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/doc/sdk/troubleshooting-tips/using-a-debugger.en.rst
----------------------------------------------------------------------
diff --git a/doc/sdk/troubleshooting-tips/using-a-debugger.en.rst
b/doc/sdk/troubleshooting-tips/using-a-debugger.en.rst
index b4b55ce..0c687f6 100644
--- a/doc/sdk/troubleshooting-tips/using-a-debugger.en.rst
+++ b/doc/sdk/troubleshooting-tips/using-a-debugger.en.rst
@@ -29,16 +29,6 @@ the core files in the :file:`records.config` file to -1 as
follows:
This is the equivalent of setting ``ulimit -c unlimited``
-Also, if you want to generate a core dump, you must set the variable:
-
-::
-
- CONFIG :ts:cv:`proxy.config.stack_dump_enabled` INT 0
-
-If this variable is set to 1, ATS will handle the SIGSEGV signal and
-print the backtrace to traffic.out, preventing the core file from being
-generated.
-
Debugging Tips:
~~~~~~~~~~~~~~~
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/lib/perl/lib/Apache/TS/AdminClient.pm
----------------------------------------------------------------------
diff --git a/lib/perl/lib/Apache/TS/AdminClient.pm
b/lib/perl/lib/Apache/TS/AdminClient.pm
index 01fe9ff..f89c370 100644
--- a/lib/perl/lib/Apache/TS/AdminClient.pm
+++ b/lib/perl/lib/Apache/TS/AdminClient.pm
@@ -709,7 +709,6 @@ The Apache Traffic Server Administration Manual will
explain what these strings
proxy.config.ssl.server.multicert.filename
proxy.config.ssl.server_port
proxy.config.ssl.server.private_key.path
- proxy.config.stack_dump_enabled
proxy.config.stat_collector.interval
proxy.config.stat_collector.port
proxy.config.stats.config_file
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/lib/ts/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am
index a46eb7f..150182d 100644
--- a/lib/ts/Makefile.am
+++ b/lib/ts/Makefile.am
@@ -46,9 +46,9 @@ libtsutil_la_SOURCES = \
Bitops.cc \
Bitops.h \
Compatability.h \
- Cryptohash.h \
ConsistentHash.cc \
ConsistentHash.h \
+ Cryptohash.h \
Diags.cc \
Diags.h \
DynArray.h \
@@ -76,18 +76,20 @@ libtsutil_la_SOURCES = \
IpMapConf.h \
Layout.cc \
List.h \
+ MMH.cc \
+ MMH.h \
Map.h \
MatcherUtils.cc \
MatcherUtils.h \
MimeTable.cc \
MimeTable.h \
- MMH.h \
- MMH.cc \
ParseRules.cc \
ParseRules.h \
Ptr.h \
RawHashTable.cc \
RawHashTable.h \
+ RbTree.cc \
+ RbTree.h \
Regex.cc \
Regex.h \
Regression.cc \
@@ -178,9 +180,8 @@ libtsutil_la_SOURCES = \
libts.h \
llqueue.cc \
lockfile.cc \
- RbTree.cc \
- RbTree.h
-
+ signals.cc \
+ signals.h
#test_UNUSED_SOURCES = \
# load_http_hdr.cc \
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/lib/ts/ink_queue.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_queue.h b/lib/ts/ink_queue.h
index 4c8562b..6c1b1c2 100644
--- a/lib/ts/ink_queue.h
+++ b/lib/ts/ink_queue.h
@@ -62,6 +62,8 @@ extern "C"
{
#endif /* __cplusplus */
+ extern int fastmemtotal;
+
void ink_queue_load_64(void *dst, void *src);
#ifdef __x86_64__
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/lib/ts/signals.cc
----------------------------------------------------------------------
diff --git a/lib/ts/signals.cc b/lib/ts/signals.cc
new file mode 100644
index 0000000..58676b3
--- /dev/null
+++ b/lib/ts/signals.cc
@@ -0,0 +1,220 @@
+/** @file
+
+ A brief file description
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+/**************************************************************************
+ Signal functions and handlers.
+
+**************************************************************************/
+
+#include "libts.h"
+#include "signals.h"
+#include "ink_stack_trace.h"
+
+bool
+signal_check_handler(int signal, signal_handler_t handler)
+{
+ struct sigaction oact;
+ void * sigact;
+
+ ink_release_assert(sigaction(signal, NULL, &oact) == 0);
+ if (handler == (signal_handler_t)SIG_DFL || handler ==
(signal_handler_t)SIG_IGN) {
+ sigact = (void *)oact.sa_handler;
+ } else {
+ sigact = (void *)oact.sa_sigaction;
+ }
+
+ if (sigact != handler) {
+ Warning("handler for signal %d was %p, not %p as expected", signal,
sigact, handler);
+ return false;
+ }
+
+ return true;
+}
+
+//
+// This is used during debugging to insure that the signals
+// don't change from under us, as they did on the DEC alpha
+// with a specific version of pthreads.
+//
+
+void
+check_signals(signal_handler_t handler)
+{
+ signal_check_handler(SIGPIPE, (signal_handler_t) SIG_IGN);
+ signal_check_handler(SIGQUIT, handler);
+ signal_check_handler(SIGHUP, handler);
+ signal_check_handler(SIGTERM, handler);
+ signal_check_handler(SIGINT, handler);
+ signal_check_handler(SIGUSR1, handler);
+}
+
+static void
+set_signal(int signo, signal_handler_t handler)
+{
+ struct sigaction act;
+
+ act.sa_handler = NULL;
+ act.sa_sigaction = handler;
+ act.sa_flags = SA_SIGINFO;
+ sigemptyset(&(act.sa_mask));
+
+ ink_release_assert(sigaction(signo, &act, NULL) == 0);
+}
+
+// Reset a signal handler to the default handler.
+static void
+signal_reset_default(int signo)
+{
+ struct sigaction act;
+
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
+ sigemptyset(&(act.sa_mask));
+
+ ink_release_assert(sigaction(signo, &act, NULL) == 0);
+}
+
+//
+// This thread checks the signals every 2 seconds to make
+// certain the DEC pthreads SIGPIPE bug isn't back..
+//
+static void *
+check_signal_thread(void * ptr)
+{
+ signal_handler_t handler = (signal_handler_t)ptr;
+ for (;;) {
+ check_signals(handler);
+ sleep(2);
+ }
+ return NULL;
+}
+
+void
+signal_start_check_thread(signal_handler_t handler)
+{
+ ink_thread_create(check_signal_thread, (void *)handler);
+}
+
+bool
+signal_is_masked(int signo)
+{
+ sigset_t current;
+
+ sigemptyset(¤t);
+ if (ink_thread_sigsetmask(SIG_SETMASK, NULL /* oldset */, ¤t) == 0) {
+ return sigismember(¤t, signo) == 1;
+ }
+
+ return false;
+}
+
+bool
+signal_is_crash(int signo)
+{
+ switch (signo) {
+ case SIGILL:
+ case SIGTRAP:
+#if defined(SIGEMT)
+ case SIGEMT:
+#endif
+#if defined(SIGSYS)
+ case SIGSYS:
+#endif
+ case SIGFPE:
+ case SIGBUS:
+ case SIGXCPU:
+ case SIGXFSZ:
+ case SIGSEGV:
+ case SIGABRT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void
+signal_format_siginfo(int signo, siginfo_t * info, const char * msg)
+{
+ (void)info;
+ (void)signo;
+
+#if HAVE_PSIGINFO
+ psiginfo(info, msg);
+#elif HAVE_PSIGNAL
+ psignal(signo, msg);
+#else
+ char buf[64];
+ size_t len;
+
+#if HAVE_STRSIGNAL
+ snprintf(buf, sizeof(buf), "%s: received signal %d (%s)\n", msg, signo,
strsignal(signo));
+#else
+ snprintf(buf, sizeof(buf), "%s: received signal %d\n", msg, signo);
+#endif
+
+ write(STDERR_FILENO, buf, strlen(buf));
+#endif
+}
+
+void
+signal_crash_handler(int signo, siginfo_t *, void *)
+{
+ ink_stack_trace_dump();
+
+ // Make sure to drop a core for signals that normally would do so.
+ signal_reset_default(signo);
+}
+
+void
+signal_register_crash_handler(signal_handler_t handler)
+{
+ set_signal(SIGBUS, handler);
+ set_signal(SIGSEGV, handler);
+ set_signal(SIGILL, handler);
+ set_signal(SIGTRAP, handler);
+ set_signal(SIGFPE, handler);
+ set_signal(SIGABRT, handler);
+}
+
+void
+signal_register_default_handler(signal_handler_t handler)
+{
+ sigset_t sigsToBlock;
+
+ sigemptyset(&sigsToBlock);
+ ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
+
+ // SIGPIPE is just annoying to handle,we never care about it
+ signal(SIGPIPE, SIG_IGN);
+
+ // SIGHUP ought to reconfigure, but it's surprisingly complex to figure out
+ // how to do that. so leave that to libmgmt.
+ signal(SIGHUP, SIG_IGN);
+
+ set_signal(SIGQUIT, handler);
+ set_signal(SIGTERM, handler);
+ set_signal(SIGINT, handler);
+ set_signal(SIGUSR1, handler);
+ set_signal(SIGUSR2, handler);
+
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/lib/ts/signals.h
----------------------------------------------------------------------
diff --git a/lib/ts/signals.h b/lib/ts/signals.h
new file mode 100644
index 0000000..b94f30f
--- /dev/null
+++ b/lib/ts/signals.h
@@ -0,0 +1,58 @@
+/** @file
+
+ A brief file description
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+/**************************************************************************
+ Signal functions and handlers.
+
+**************************************************************************/
+
+#ifndef __SIGNALS_H__
+#define __SIGNALS_H__
+
+typedef void (*signal_handler_t)(int signo, siginfo_t * info, void * ctx);
+
+// Default crash signal handler that dumps a stack trace and exits.
+void signal_crash_handler(int, siginfo_t *, void *);
+
+// Attach a signal handler to fatal crash signals.
+void signal_register_crash_handler(signal_handler_t);
+// Attach a signal handler to the default et of signals we care about.
+void signal_register_default_handler(signal_handler_t);
+
+// Format a siginfo_t into an informative(?) message on stderr.
+void signal_format_siginfo(int signo, siginfo_t *, const char *);
+
+// Test whether a signal indicates a process crashing.
+bool signal_is_crash(int signo);
+
+// Test whether the signal is masked.
+bool signal_is_masked(int signo);
+
+// Test whether the signal is being handled by the given handler.
+bool signal_check_handler(int signo, signal_handler_t handler);
+
+// Start a thread to test whether signals have the expected handler.
Apparantly useful for
+// finding pthread bugs in some version of DEC Unix.
+void signal_start_check_thread(signal_handler_t handler);
+
+#endif /* __SIGNALS_H__ */
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 2c24c0b..e6a0ad8 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -66,8 +66,6 @@ RecordElement RecordsConfig[] = {
//# Negative core limit means max out limit
{RECT_CONFIG, "proxy.config.core_limit", RECD_INT, "-1", RECU_NULL, RR_NULL,
RECC_NULL, NULL, RECA_NULL}
,
- {RECT_CONFIG, "proxy.config.stack_dump_enabled", RECD_INT, "1", RECU_NULL,
RR_NULL, RECC_NULL, NULL, RECA_NULL}
- ,
// 0 - Disabled, 1 - enabled for important pages (e.g. cache directory), 2 -
enabled for all pages
{RECT_CONFIG, "proxy.config.mlock_enabled", RECD_INT, "0", RECU_NULL,
RR_NULL, RECC_NULL, NULL, RECA_NULL}
,
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/Main.cc
----------------------------------------------------------------------
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 46f340d..beb82ee 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -154,6 +154,8 @@ static int accept_mss = 0;
static int cmd_line_dprintf_level = 0; // default debug output level from
ink_dprintf function
static int poll_timeout = -1; // No value set.
+static volatile bool sigusr1_received = false;
+
// 1: delay listen, wait for cache.
// 0: Do not delay, start listen ASAP.
// -1: cache is already initialized, don't delay.
@@ -210,21 +212,153 @@ static const ArgumentDescription argument_descriptions[]
= {
VERSION_ARGUMENT_DESCRIPTION()
};
+class SignalContinuation : public Continuation
+{
+public:
+ char *end;
+ char *snap;
+ int fastmemsnap;
+
+ SignalContinuation() : Continuation(new_ProxyMutex()) {
+ end = snap = 0;
+ fastmemsnap = 0;
+ SET_HANDLER(&SignalContinuation::periodic);
+ }
+
+ int periodic(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) {
+ if (sigusr1_received) {
+ sigusr1_received = false;
+
+ // TODO: TS-567 Integrate with debugging allocators "dump" features?
+ ink_freelists_dump(stderr);
+ ResourceTracker::dump(stderr);
+ if (!end)
+ end = (char *) sbrk(0);
+ if (!snap)
+ snap = (char *) sbrk(0);
+ char *now = (char *) sbrk(0);
+ // TODO: Use logging instead directly writing to stderr
+ // This is not error condition at the first place
+ // so why stderr?
+ //
+ fprintf(stderr, "sbrk 0x%" PRIu64 "x from first %" PRIu64 " from last %"
PRIu64 "\n",
+ (uint64_t) ((ptrdiff_t) now), (uint64_t) ((ptrdiff_t) (now -
end)),
+ (uint64_t) ((ptrdiff_t) (now - snap)));
+#ifdef DEBUG
+ int fmdelta = fastmemtotal - fastmemsnap;
+ fprintf(stderr, "fastmem %" PRId64 " from last %" PRId64 "\n", (int64_t)
fastmemtotal, (int64_t) fmdelta);
+ fastmemsnap += fmdelta;
+#endif
+ snap = now;
+ }
+
+ return EVENT_CONT;
+ }
+};
+
+class TrackerContinuation : public Continuation {
+public:
+ int baseline_taken;
+ int use_baseline;
+
+ TrackerContinuation() : Continuation(new_ProxyMutex()) {
+ SET_HANDLER(&TrackerContinuation::periodic);
+ use_baseline = 0;
+ // TODO: ATS prefix all those environment stuff or
+ // even better use config since env can be
+ // different for parent and child process users.
+ //
+ if (getenv("MEMTRACK_BASELINE")) {
+ use_baseline = 1;
+ }
+
+ baseline_taken = 0;
+ }
+
+ int periodic(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) {
+ if (use_baseline) {
+ // TODO: TS-567 Integrate with debugging allocators "dump" features?
+ ink_freelists_dump_baselinerel(stderr);
+ } else {
+ // TODO: TS-567 Integrate with debugging allocators "dump" features?
+ ink_freelists_dump(stderr);
+ ResourceTracker::dump(stderr);
+ }
+ if (!baseline_taken && use_baseline) {
+ ink_freelists_snap_baseline();
+ // TODO: TS-567 Integrate with debugging allocators "dump" features?
+ baseline_taken = 1;
+ }
+ return EVENT_CONT;
+ }
+};
+
+static int
+init_memory_tracker(const char *config_var, RecDataT /* type ATS_UNUSED */,
RecData data, void * /* cookie ATS_UNUSED */)
+{
+ static Event *tracker_event = NULL;
+ int dump_mem_info_frequency = 0;
+
+ if (config_var) {
+ dump_mem_info_frequency = data.rec_int;
+ } else {
+ dump_mem_info_frequency =
REC_ConfigReadInteger("proxy.config.dump_mem_info_frequency");
+ }
+
+ Debug("tracker", "init_tracker called [%d]\n", dump_mem_info_frequency);
+
+ if (tracker_event) {
+ tracker_event->cancel();
+ tracker_event = NULL;
+ }
+
+ if (dump_mem_info_frequency > 0) {
+ tracker_event = eventProcessor.schedule_every(new TrackerContinuation,
+
HRTIME_SECONDS(dump_mem_info_frequency), ET_CALL);
+ }
+
+ return 1;
+}
+
+static void
+proxy_signal_handler(int signo, siginfo_t * info, void *)
+{
+ switch (signo) {
+ case SIGUSR1:
+ sigusr1_received = true;
+ return;
+ case SIGHUP:
+ return;
+ }
+
+ signal_format_siginfo(signo, info, appVersionInfo.AppStr);
+
+#if TS_HAS_PROFILER
+ ProfilerStop();
+#endif
+
+ if (signal_is_crash(signo)) {
+ // The only call to abort(2) should be from ink_fatal, which has already
logged a stack trace.
+ if (signo != SIGABRT) {
+ ink_stack_trace_dump();
+ }
+
+ // Make sure to drop a core for signals that normally would do so.
+ signal(signo, SIG_DFL);
+ return;
+ }
+
+ _exit(signo);
+}
+
//
// Initialize operating system related information/services
//
static void
init_system()
{
- RecInt stackDump;
- bool found = (RecGetRecordInt("proxy.config.stack_dump_enabled", &stackDump)
== REC_ERR_OKAY);
-
- if (found == false) {
- Warning("Unable to determine stack_dump_enabled , assuming enabled");
- stackDump = 1;
- }
-
- init_signals(stackDump == 1);
+ signal_register_default_handler(proxy_signal_handler);
+ signal_register_crash_handler(proxy_signal_handler);
syslog(LOG_NOTICE, "NOTE: --- %s Starting ---", appVersionInfo.AppStr);
syslog(LOG_NOTICE, "NOTE: %s Version: %s", appVersionInfo.AppStr,
appVersionInfo.FullVersionInfoStr);
@@ -331,14 +465,6 @@ initialize_process_manager()
RecRegisterStatString(RECT_PROCESS,
"proxy.process.version.server.build_person", appVersionInfo.BldPersonStr,
RECP_NON_PERSISTENT);
}
-//
-// Shutdown
-//
-void
-shutdown_system()
-{
-}
-
#define CMD_ERROR -2 // serious error, exit maintaince mode
#define CMD_FAILED -1 // error, but recoverable
#define CMD_OK 0 // ok, or minor (user) error
@@ -1076,12 +1202,12 @@ chdir_root()
const char * prefix = Layout::get()->prefix;
if (chdir(prefix) < 0) {
- fprintf(stderr,"unable to change to root directory \"%s\" [%d '%s']\n",
- prefix, errno, strerror(errno));
- fprintf(stderr," please set correct path in env variable TS_ROOT \n");
+ fprintf(stderr, "%s: unable to change to root directory \"%s\" [%d
'%s']\n",
+ appVersionInfo.AppStr, prefix, errno, strerror(errno));
+ fprintf(stderr, "%s: please correct the path or set the TS_ROOT
environment variable\n", appVersionInfo.AppStr);
_exit(1);
} else {
- printf("[TrafficServer] using root directory '%s'\n", prefix);
+ printf("%s: using root directory '%s'\n", appVersionInfo.AppStr, prefix);
}
}
@@ -1455,7 +1581,10 @@ main(int /* argc ATS_UNUSED */, char **argv)
remapProcessor.setUseSeparateThread();
}
- init_signals2();
+ eventProcessor.schedule_every(new SignalContinuation, HRTIME_MSECOND * 500,
ET_CALL);
+ REC_RegisterConfigUpdateFunc("proxy.config.dump_mem_info_frequency",
init_memory_tracker, NULL);
+ init_memory_tracker(NULL, RECD_NULL, RecData(), NULL);
+
// log initialization moved down
if (command_flag) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/Main.h
----------------------------------------------------------------------
diff --git a/proxy/Main.h b/proxy/Main.h
index 4006a65..1a9e27b 100644
--- a/proxy/Main.h
+++ b/proxy/Main.h
@@ -70,7 +70,6 @@ extern int default_rcvbuf_size;
//
// Functions
//
-void shutdown_system();
inline bool
maintainance_mode()
{
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index 6a659b1..34ae17b 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -202,7 +202,6 @@ traffic_server_LDADD = \
hdrs/libhdrs.a \
shared/liberror.a \
shared/libdiagsconfig.a \
- shared/libsignals.a \
shared/libxml.a \
$(top_builddir)/mgmt/libmgmt_p.la \
$(top_builddir)/iocore/utils/libinkutils.a \
@@ -245,7 +244,6 @@ traffic_logcat_LDADD = \
logging/liblogging.a \
shared/libdiagsconfig.a \
shared/libUglyLogStubs.a \
- shared/libsignals.a \
shared/libxml.a \
$(top_builddir)/mgmt/libmgmt_p.la \
$(top_builddir)/lib/records/librecords_p.a \
@@ -260,7 +258,6 @@ traffic_logstats_LDADD = \
logging/liblogging.a \
shared/libdiagsconfig.a \
shared/libUglyLogStubs.a \
- shared/libsignals.a \
shared/libxml.a \
$(top_builddir)/mgmt/libmgmt_p.la \
$(top_builddir)/lib/records/librecords_p.a \
@@ -310,7 +307,6 @@ traffic_sac_LDADD = \
logging/liblogcollation.a \
hdrs/libhdrs.a \
shared/liberror.a \
- shared/libsignals.a \
shared/libxml.a \
$(top_builddir)/mgmt/libmgmt_p.la \
$(top_builddir)/iocore/cluster/libinkcluster.a \
@@ -338,7 +334,6 @@ test_xml_parser_LDADD = \
$(top_builddir)/lib/records/librecords_p.a \
$(top_builddir)/iocore/eventsystem/libinkevent.a \
$(top_builddir)/lib/ts/libtsutil.la \
- shared/libsignals.a \
shared/libxml.a \
@LIBTCL@
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/logging/LogConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/LogConfig.cc b/proxy/logging/LogConfig.cc
index 171c77b..385a944 100644
--- a/proxy/logging/LogConfig.cc
+++ b/proxy/logging/LogConfig.cc
@@ -163,7 +163,7 @@ void *
LogConfig::reconfigure_mgmt_variables(void * /* token ATS_UNUSED */, char * /*
data_raw ATS_UNUSED */,
int /* data_len ATS_UNUSED */)
{
- Note("[TrafficServer:LogConfig] : Roll_Log_Files event received. rolling
now");
+ Note("received log reconfiguration event, rolling now");
Log::config->roll_log_files_now = true;
return NULL;
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/logging/LogStandalone.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/LogStandalone.cc b/proxy/logging/LogStandalone.cc
index c4f5122..fd7ff24 100644
--- a/proxy/logging/LogStandalone.cc
+++ b/proxy/logging/LogStandalone.cc
@@ -71,12 +71,20 @@ AppVersionInfo appVersionInfo;
init_system
-------------------------------------------------------------------------*/
+// Handle fatal signals by logging and core dumping ...
+static void
+logging_crash_handler(int signo, siginfo_t * info, void * ptr)
+{
+ signal_format_siginfo(signo, info, appVersionInfo.AppStr);
+ signal_crash_handler(signo, info, ptr);
+}
+
static void
init_system(bool notify_syslog)
{
fds_limit = ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
- init_signals();
+ signal_register_crash_handler(logging_crash_handler);
if (notify_syslog) {
syslog(LOG_NOTICE, "NOTE: --- %s Starting ---", appVersionInfo.AppStr);
syslog(LOG_NOTICE, "NOTE: %s Version: %s", appVersionInfo.AppStr,
appVersionInfo.FullVersionInfoStr);
@@ -133,15 +141,6 @@ initialize_process_manager()
// RECP_NON_PERSISTENT);
}
-/*-------------------------------------------------------------------------
- shutdown_system
- -------------------------------------------------------------------------*/
-
-void
-shutdown_system()
-{
-}
-
/*-------------------------------------------------------------------------
check_lockfile
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/sac.cc
----------------------------------------------------------------------
diff --git a/proxy/sac.cc b/proxy/sac.cc
index 0d11c55..d98fa23 100644
--- a/proxy/sac.cc
+++ b/proxy/sac.cc
@@ -65,6 +65,17 @@ ArgumentDescription argument_descriptions[] = {
main
-------------------------------------------------------------------------*/
+static void
+sac_signal_handler(int signo, siginfo_t * info, void *)
+{
+ if (signo == SIGHUP) {
+ return;
+ }
+
+ signal_format_siginfo(signo, info, appVersionInfo.AppStr);
+ _exit(signo);
+}
+
int
main(int /* argc ATS_UNUSED */, char *argv[])
{
@@ -88,6 +99,8 @@ main(int /* argc ATS_UNUSED */, char *argv[])
bool one_copy = true;
init_log_standalone(PROGRAM_NAME, one_copy);
+ signal_register_default_handler(sac_signal_handler);
+
// set up IO Buffers
//
int config_max_iobuffer_size = DEFAULT_MAX_BUFFER_SIZE;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/shared/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/shared/Makefile.am b/proxy/shared/Makefile.am
index ca79f60..0e16f00 100644
--- a/proxy/shared/Makefile.am
+++ b/proxy/shared/Makefile.am
@@ -21,7 +21,6 @@ noinst_LIBRARIES = \
liberror.a \
libdiagsconfig.a \
libUglyLogStubs.a \
- libsignals.a \
libxml.a
AM_CPPFLAGS = \
@@ -53,7 +52,3 @@ libUglyLogStubs_a_SOURCES = \
libxml_a_SOURCES = \
InkXml.cc \
InkXml.h
-
-libsignals_a_SOURCES = \
- signals.cc \
- signals.h
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/shared/signals.cc
----------------------------------------------------------------------
diff --git a/proxy/shared/signals.cc b/proxy/shared/signals.cc
deleted file mode 100644
index aa623bd..0000000
--- a/proxy/shared/signals.cc
+++ /dev/null
@@ -1,416 +0,0 @@
-/** @file
-
- A brief file description
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/**************************************************************************
- Signal functions and handlers.
-
-**************************************************************************/
-
-#include "libts.h"
-#include "signals.h"
-#include "ProxyConfig.h"
-#include "P_EventSystem.h"
-#include "StatSystem.h"
-#include "proxy/Main.h"
-
-// For backtraces on crash
-#include "ink_stack_trace.h"
-
-#if TS_HAS_PROFILER
-#include <google/profiler.h>
-#endif
-
-#if !defined(linux) && !defined(freebsd)
-typedef void (*SigActionFunc_t) (int sig, siginfo_t * t, void *f);
-#else
-typedef void (*SigActionFunc_t) (int sig);
-#endif
-
-int exited_children = 0;
-
-static volatile int sigusr1_received = 0;
-extern int fastmemtotal;
-
-class SignalContinuation:public Continuation
-{
-public:
- char *end;
- char *snap;
- int fastmemsnap;
- SignalContinuation()
- : Continuation(new_ProxyMutex())
- {
- end = snap = 0;
- fastmemsnap = 0;
- SET_HANDLER(&SignalContinuation::periodic);
- }
-
- int periodic(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
- {
- if (sigusr1_received) {
- sigusr1_received = 0;
- // TODO: TS-567 Integrate with debugging allocators "dump" features?
- ink_freelists_dump(stderr);
- ResourceTracker::dump(stderr);
- if (!end)
- end = (char *) sbrk(0);
- if (!snap)
- snap = (char *) sbrk(0);
- char *now = (char *) sbrk(0);
- // TODO: Use logging instead directly writing to stderr
- // This is not error condition at the first place
- // so why stderr?
- //
- fprintf(stderr, "sbrk 0x%" PRIu64 "x from first %" PRIu64 " from last %"
PRIu64 "\n",
- (uint64_t) ((ptrdiff_t) now), (uint64_t) ((ptrdiff_t) (now -
end)),
- (uint64_t) ((ptrdiff_t) (now - snap)));
-#ifdef DEBUG
- int fmdelta = fastmemtotal - fastmemsnap;
- fprintf(stderr, "fastmem %" PRId64 " from last %" PRId64 "\n", (int64_t)
fastmemtotal, (int64_t) fmdelta);
- fastmemsnap += fmdelta;
-#endif
- snap = now;
- }
-
- return EVENT_CONT;
- }
-};
-
-class TrackerContinuation:public Continuation
-{
-public:
- int baseline_taken;
- int use_baseline;
- TrackerContinuation()
- : Continuation(new_ProxyMutex())
- {
- SET_HANDLER(&TrackerContinuation::periodic);
- use_baseline = 0;
- // TODO: ATS prefix all those environment struff or
- // even better use config since env can be
- // different for parent and child process users.
- //
- if (getenv("MEMTRACK_BASELINE"))
- {
- use_baseline = 1;
- }
- baseline_taken = 0;
- }
-
- int periodic(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
- {
- if (use_baseline) {
- // TODO: TS-567 Integrate with debugging allocators "dump" features?
- ink_freelists_dump_baselinerel(stderr);
- } else {
- // TODO: TS-567 Integrate with debugging allocators "dump" features?
- ink_freelists_dump(stderr);
- ResourceTracker::dump(stderr);
- }
- if (!baseline_taken && use_baseline) {
- ink_freelists_snap_baseline();
- // TODO: TS-567 Integrate with debugging allocators "dump" features?
- baseline_taken = 1;
- }
- return EVENT_CONT;
- }
-};
-
-
-static void
-interrupt_handler(int sig)
-{
- (void) sig;
- fprintf(stderr, "interrupt caught...exit\n");
- shutdown_system();
- _exit(1);
-}
-
-#if defined(linux)
-static void
-signal_handler(int sig)
-#else
-static void
-signal_handler(int sig, siginfo_t * t, void *c)
-#endif
-{
- if (sig == SIGUSR1) {
- sigusr1_received = 1;
- return;
- }
-
- char sig_msg[2048];
-#if !defined(linux) && !defined(freebsd)
- // Print out information about where the signal came from
- // so that we can debug signal related problems
- //
- // I'm avoiding use of the Diags stuff since it is more
- // likely to deadlock from a signal handler. The syslog
- // if questionable and probably should be eventually be
- // turned off but should be helpful through Rator alpha
- //
- // lomew adds on May 03, 2002: don't call syslog here because it
- // calls malloc and can deadlock you if the SEGV happened in free after
- // the heap-mutex has been taken, like if free was called with garbage.
- //
- if (t) {
- if (t->si_code <= 0) {
- // TODO: Use UID_FMT_T instead duplicating code
-#if defined(solaris)
- snprintf(sig_msg, sizeof(sig_msg), "NOTE: Traffic Server received User
Sig %d from pid: %d uid: %d\n",
- sig, (int)t->si_pid, (int)t->si_uid);
-#else
- snprintf(sig_msg, sizeof(sig_msg), "NOTE: Traffic Server received User
Sig %d from pid: %d uid: %d\n",
- sig, t->si_pid, t->si_uid);
-#endif
- } else {
- snprintf(sig_msg, sizeof(sig_msg), "NOTE: Traffic Server received Kernel
Sig %d, Reason: %d\n", sig, t->si_code);
- }
-
- write(2, sig_msg, strlen(sig_msg));
- //syslog(LOG_ERR, sig_msg);
- }
-#else
- snprintf(sig_msg, sizeof(sig_msg), "NOTE: Traffic Server received Sig %d:
%s\n", sig, strsignal(sig));
- ATS_UNUSED_RETURN(write(2, sig_msg, strlen(sig_msg)));
- //syslog(LOG_ERR, sig_msg);
-#endif
-
-#if TS_HAS_PROFILER
- ProfilerStop();
-#endif
- shutdown_system();
-
- // Make sure to drop a core for signals that normally
- // would do so.
- switch (sig) {
- case SIGQUIT:
- case SIGILL:
- case SIGTRAP:
-#if !defined(linux)
- case SIGEMT:
- case SIGSYS:
-#endif
- case SIGFPE:
- case SIGBUS:
- case SIGXCPU:
- case SIGXFSZ:
- case SIGSEGV:
- ink_stack_trace_dump();
- signal(sig, SIG_DFL);
- return;
- case SIGUSR2:
- ink_stack_trace_dump();
- return;
- case SIGABRT:
- case SIGUSR1:
- default:
- _exit(sig);
- }
-}
-
-static void
-child_signal_handler(int sig)
-{
- (void) sig;
- int pid;
- int saved_errno = errno;
- while ((pid = waitpid(-1, 0, WNOHANG)) > 0) {
- fprintf(stderr, "child %d exited\n", pid);
- ++exited_children;
- }
- errno = saved_errno;
-}
-
-static void
-set_signal(int signal, SigActionFunc_t action_func)
-{
- struct sigaction action;
- struct sigaction o_action;
-
-#if !defined(linux) && !defined(freebsd)
- action.sa_handler = NULL;
- action.sa_sigaction = action_func;
-#else
- action.sa_handler = action_func;
-#endif
- // action.sa_mask = 0; // changed 10/17/97 to make portable
- sigemptyset(&(action.sa_mask)); // changed 10/17/97 to make portable
- action.sa_flags = 0;
-
- int res = sigaction(signal, &action, &o_action);
- ink_release_assert(res == 0);
-}
-
-static void
-check_signal(int signal, SigActionFunc_t action_func)
-{
- struct sigaction action;
- struct sigaction o_action;
-
-#if !defined(linux) && !defined(freebsd)
- action.sa_handler = NULL;
- action.sa_sigaction = action_func;
- action.sa_flags = SA_SIGINFO;
-#else
- action.sa_handler = action_func;
- action.sa_flags = 0;
-#endif
- // action.sa_mask = 0; // changed 10/17/97 to make portable
- sigemptyset(&(action.sa_mask)); // changed 10/17/97 to make portable
-
- int res = sigaction(signal, &action, &o_action);
- ink_release_assert(res == 0);
-
-#if !defined(linux) && !defined(freebsd)
- if (o_action.sa_sigaction != action_func) {
- fprintf(stderr, "Handler for signal %d was %p, not %p as expected\n",
signal, o_action.sa_sigaction, action_func);
- }
-#endif
-}
-
-//
-// This is used during debugging to insure that the signals
-// don't change from under us, as they did on the DEC alpha
-// with a specific version of pthreads.
-//
-
-void
-check_signals()
-{
- check_signal(SIGPIPE, (SigActionFunc_t) SIG_IGN);
- check_signal(SIGQUIT, (SigActionFunc_t) signal_handler);
- check_signal(SIGHUP, (SigActionFunc_t) interrupt_handler);
- check_signal(SIGTERM, (SigActionFunc_t) signal_handler);
- check_signal(SIGINT, (SigActionFunc_t) signal_handler);
- check_signal(SIGUSR1, (SigActionFunc_t) signal_handler);
-}
-
-
-//
-// This thread checks the signals every 2 seconds to make
-// certain the DEC pthreads SIGPIPE bug isn't back..
-//
-#if !defined(linux) && !defined(freebsd) && defined(DEBUG)
-static void *
-check_signal_thread(void *)
-{
- for (;;) {
- check_signals();
- sleep(2);
- }
- return NULL;
-}
-#endif
-
-void
-init_signals(bool do_stackdump)
-{
- sigset_t sigsToBlock;
-
- sigemptyset(&sigsToBlock);
- ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
-
- set_signal(SIGPIPE, (SigActionFunc_t) SIG_IGN);
- set_signal(SIGQUIT, (SigActionFunc_t) signal_handler);
- set_signal(SIGTERM, (SigActionFunc_t) signal_handler);
- set_signal(SIGINT, (SigActionFunc_t) signal_handler);
- set_signal(SIGHUP, (SigActionFunc_t) interrupt_handler);
- set_signal(SIGILL, (SigActionFunc_t) signal_handler);
- if(do_stackdump) {
- set_signal(SIGBUS, (SigActionFunc_t) signal_handler);
- set_signal(SIGSEGV, (SigActionFunc_t) signal_handler);
- }
-
-//
-// Presviously the following lines were #if 0
-//
-// set_signal(SIGILL,(SigActionFunc_t)signal_handler);
-// set_signal(SIGBUS,(SigActionFunc_t)signal_handler);
-// set_signal(SIGSEGV,(SigActionFunc_t)signal_handler);
-//
-// There was an an addtional #if 0 w/ a note about SIGABRT
-// // Do not catch, results in recursive
-// // SIGABRT loop on solaris assert() failures
-// set_signal(SIGABRT,(SigActionFunc_t)signal_handler);
-//
-#if !defined(freebsd)
- set_signal(SIGUSR1, (SigActionFunc_t) signal_handler);
-#endif
-
-#if defined(linux)
- set_signal(SIGUSR2, (SigActionFunc_t) signal_handler);
-#endif
-
-#if !defined(linux) && !defined(freebsd) && defined(DEBUG)
- ink_thread_create(check_signal_thread, NULL);
-#endif
-
- // do not handle these
- // ink_assert(signal(SIGINT,(SigActionFunc_t)interrupt_handler) != SIG_ERR);
-}
-
-
-int
-init_tracker(const char *config_var, RecDataT /* type ATS_UNUSED */, RecData
data, void * /* cookie ATS_UNUSED */)
-{
- static Event *tracker_event = NULL;
- int dump_mem_info_frequency = 0;
-
- if (config_var)
- dump_mem_info_frequency = data.rec_int;
- else
- dump_mem_info_frequency =
REC_ConfigReadInteger("proxy.config.dump_mem_info_frequency");
- Debug("tracker", "init_tracker called [%d]\n", dump_mem_info_frequency);
- if (tracker_event) {
- tracker_event->cancel();
- tracker_event = NULL;
- }
- if (dump_mem_info_frequency > 0) {
- tracker_event = eventProcessor.schedule_every(new TrackerContinuation,
-
HRTIME_SECONDS(dump_mem_info_frequency), ET_CALL);
- }
- return 1;
-}
-
-void
-init_signals2()
-{
- eventProcessor.schedule_every(new SignalContinuation, HRTIME_MSECOND * 500,
ET_CALL);
- REC_RegisterConfigUpdateFunc("proxy.config.dump_mem_info_frequency",
init_tracker, NULL);
- RecData data;
- data.rec_int = 0; // Shouldn't be used now anyways
- init_tracker(NULL, RECD_INT, data, NULL);
-}
-
-
-void
-init_daemon_signals()
-{
- struct sigaction act;
- ink_assert(signal(SIGCHLD, (VI_PFN) child_signal_handler) != SIG_ERR);
- act.sa_handler = (VI_PFN) child_signal_handler;
- ink_assert(!sigemptyset(&act.sa_mask));
- act.sa_flags = SA_NOCLDSTOP;
- ink_assert(!sigaction(SIGCHLD, &act, NULL));
-}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ecea9413/proxy/shared/signals.h
----------------------------------------------------------------------
diff --git a/proxy/shared/signals.h b/proxy/shared/signals.h
deleted file mode 100644
index 9734ff6..0000000
--- a/proxy/shared/signals.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** @file
-
- A brief file description
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/**************************************************************************
- Signal functions and handlers.
-
-**************************************************************************/
-
-#ifndef _signals_h_
-#define _signals_h_
-
-/*
- * Global data
- */
-
-extern int exited_children;
-typedef void (*sig_callback_fptr) (int signo);
-/*
-* plugins use this to attach clean up handlers
-* for SIGSEGV and SIGBUS
-* Return value: 0 on success, -1 on failure
-*/
-int register_signal_callback(sig_callback_fptr f);
-
-/*
- * Function prototypes
- */
-
-void init_signals(bool do_stackdump=true);
-void init_signals2();
-void init_daemon_signals();
-
-#endif /* _signals_h_ */