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>
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;
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);
pthread_self() == m_flush_mutex_holder;
}
+void Log::inject_segv()
+{
+ m_inject_segv = true;
+}
+
} // ceph::log::
} // ceph::
int m_max_new, m_max_recent;
+ bool m_inject_segv;
+
void *entry();
void _flush(EntryQueue *q, EntryQueue *requeue, bool crash);
/// 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();
};
}
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(), ".*");
+}
#include "common/config.h"
#include "common/signal.h"
#include "global/signal_handler.h"
+#include "common/debug.h"
#include "test/unit.h"
#include <stdlib.h>
#include <unistd.h>
+#include "include/assert.h"
+
static volatile sig_atomic_t got_sigusr1 = 0;
static void handle_sigusr1(int signo)
shutdown_async_signal_handler();
}
+TEST(SignalHandler, LogInternal)
+{
+ g_ceph_context->_log->inject_segv();
+ ASSERT_DEATH(derr << "foo" << dendl, ".*");
+}
+
+
/*
TEST(SignalHandler, MultipleBigFd)
{