diff options
author | Sage Weil <sage@redhat.com> | 2014-09-13 02:18:01 +0200 |
---|---|---|
committer | Sage Weil <sage@redhat.com> | 2014-09-13 02:18:01 +0200 |
commit | a8c943a0e4210aadf96cab4a71e9e7a458e9a422 (patch) | |
tree | 80618dc0ee9e97060d1997dcdcb98847c7a4476e | |
parent | global/signal_handler: do not log if SEGV originated inside log code (diff) | |
download | ceph-a8c943a0e4210aadf96cab4a71e9e7a458e9a422.tar.xz ceph-a8c943a0e4210aadf96cab4a71e9e7a458e9a422.zip |
log: add simple test to verify an internal SEGV doesn't hang
Test that the segv injection works.
Test that a segv while logging something doesn't hang when the signal
handlers are installed. Note that this fails/hangs without the previous
fix.
Signed-off-by: Sage Weil <sage@redhat.com>
-rw-r--r-- | src/log/Log.cc | 11 | ||||
-rw-r--r-- | src/log/Log.h | 5 | ||||
-rw-r--r-- | src/log/test.cc | 22 | ||||
-rw-r--r-- | src/test/signals.cc | 10 |
4 files changed, 47 insertions, 1 deletions
diff --git a/src/log/Log.cc b/src/log/Log.cc index 8da77ef8b77..046774dfce8 100644 --- a/src/log/Log.cc +++ b/src/log/Log.cc @@ -45,7 +45,8 @@ Log::Log(SubsystemMap *s) m_stderr_log(1), m_stderr_crash(-1), m_stop(false), m_max_new(DEFAULT_MAX_NEW), - m_max_recent(DEFAULT_MAX_RECENT) + m_max_recent(DEFAULT_MAX_RECENT), + m_inject_segv(false) { int ret; @@ -145,6 +146,9 @@ void Log::submit_entry(Entry *e) pthread_mutex_lock(&m_queue_mutex); m_queue_mutex_holder = pthread_self(); + if (m_inject_segv) + *(int *)(0) = 0xdead; + // wait for flush to catch up while (m_new.m_len > m_max_new) pthread_cond_wait(&m_cond_loggers, &m_queue_mutex); @@ -353,5 +357,10 @@ bool Log::is_inside_log_lock() pthread_self() == m_flush_mutex_holder; } +void Log::inject_segv() +{ + m_inject_segv = true; +} + } // ceph::log:: } // ceph:: diff --git a/src/log/Log.h b/src/log/Log.h index b77be87e82e..04cadd726f6 100644 --- a/src/log/Log.h +++ b/src/log/Log.h @@ -42,6 +42,8 @@ class Log : private Thread int m_max_new, m_max_recent; + bool m_inject_segv; + void *entry(); void _flush(EntryQueue *q, EntryQueue *requeue, bool crash); @@ -74,6 +76,9 @@ public: /// true if the log lock is held by our thread bool is_inside_log_lock(); + + /// induce a segv on the next log event + void inject_segv(); }; } diff --git a/src/log/test.cc b/src/log/test.cc index 85e9ebc01bd..6e4704befde 100644 --- a/src/log/test.cc +++ b/src/log/test.cc @@ -187,3 +187,25 @@ TEST(Log, ManyGather) log.flush(); log.stop(); } + +void do_segv() +{ + SubsystemMap subs; + subs.add(1, "foo", 20, 1); + Log log(&subs); + log.start(); + log.set_log_file("/tmp/big"); + log.reopen_log_file(); + + log.inject_segv(); + Entry *e = new Entry(ceph_clock_now(NULL), pthread_self(), 10, 1); + log.submit_entry(e); // this should segv + + log.flush(); + log.stop(); +} + +TEST(Log, InternalSegv) +{ + ASSERT_DEATH(do_segv(), ".*"); +} diff --git a/src/test/signals.cc b/src/test/signals.cc index 2c7f4d32a0a..2cae0fab8f9 100644 --- a/src/test/signals.cc +++ b/src/test/signals.cc @@ -1,6 +1,7 @@ #include "common/config.h" #include "common/signal.h" #include "global/signal_handler.h" +#include "common/debug.h" #include "test/unit.h" @@ -9,6 +10,8 @@ #include <stdlib.h> #include <unistd.h> +#include "include/assert.h" + static volatile sig_atomic_t got_sigusr1 = 0; static void handle_sigusr1(int signo) @@ -111,6 +114,13 @@ TEST(SignalHandler, Multiple) shutdown_async_signal_handler(); } +TEST(SignalHandler, LogInternal) +{ + g_ceph_context->_log->inject_segv(); + ASSERT_DEATH(derr << "foo" << dendl, ".*"); +} + + /* TEST(SignalHandler, MultipleBigFd) { |