mirror of
https://github.com/ceph/ceph
synced 2024-12-17 17:05:42 +00:00
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>
This commit is contained in:
parent
e3fe18aabe
commit
a8c943a0e4
@ -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::
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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(), ".*");
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user