]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
log: add simple test to verify an internal SEGV doesn't hang 2478/head
authorSage Weil <sage@redhat.com>
Sat, 13 Sep 2014 00:18:01 +0000 (17:18 -0700)
committerSage Weil <sage@redhat.com>
Sat, 13 Sep 2014 00:18:01 +0000 (17:18 -0700)
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>
src/log/Log.cc
src/log/Log.h
src/log/test.cc
src/test/signals.cc

index 8da77ef8b77ed3be8ad348b4e73917713d58240f..046774dfce83212898fbe337edfd6f12ad6bf934 100644 (file)
@@ -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::
index b77be87e82e431f25e1d1448db0a4a525fa2520f..04cadd726f68db344568288f652f7224c98f7556 100644 (file)
@@ -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();
 };
 
 }
index 85e9ebc01bdff9120a56ef09758e805d01fb93b5..6e4704befde0ed59563b8bdf6d147b6414890199 100644 (file)
@@ -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(), ".*");
+}
index 2c7f4d32a0af85fcee62e270d3120d0f93452afe..2cae0fab8f9b2296a59c91ac1dd82c7a351f7973 100644 (file)
@@ -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)
 {