summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/assert.cc125
-rw-r--r--src/include/assert.h21
-rw-r--r--src/kv/RocksDBStore.cc8
3 files changed, 117 insertions, 37 deletions
diff --git a/src/common/assert.cc b/src/common/assert.cc
index 623b3150b49..239bd6db0af 100644
--- a/src/common/assert.cc
+++ b/src/common/assert.cc
@@ -79,6 +79,35 @@ namespace ceph {
__ceph_assert_fail(ctx.assertion, ctx.file, ctx.line, ctx.function);
}
+ class BufAppender {
+ public:
+ BufAppender(char* buf, int size) : bufptr(buf), remaining(size) {}
+
+ void printf(const char * format, ...) {
+ va_list args;
+ va_start(args, format);
+ this->vprintf(format, args);
+ va_end(args);
+ }
+
+ void vprintf(const char * format, va_list args) {
+ int n = vsnprintf(bufptr, remaining, format, args);
+ if (n >= 0) {
+ if (n < remaining) {
+ remaining -= n;
+ bufptr += n;
+ } else {
+ remaining = 0;
+ }
+ }
+ }
+
+ private:
+ char* bufptr;
+ int remaining;
+ };
+
+
[[gnu::cold]] void __ceph_assertf_fail(const char *assertion,
const char *file, int line,
const char *func, const char* msg,
@@ -95,43 +124,85 @@ namespace ceph {
ceph_pthread_getname(pthread_self(), g_assert_thread_name,
sizeof(g_assert_thread_name));
- class BufAppender {
- public:
- BufAppender(char* buf, int size) : bufptr(buf), remaining(size) {
- }
+ char buf[8096];
+ BufAppender ba(buf, sizeof(buf));
+ BackTrace *bt = new BackTrace(1);
+ ba.printf("%s: In function '%s' thread %llx time %s\n"
+ "%s: %d: FAILED ceph_assert(%s)\n",
+ file, func, (unsigned long long)pthread_self(), tss.str().c_str(),
+ file, line, assertion);
+ ba.printf("Assertion details: ");
+ va_list args;
+ va_start(args, msg);
+ ba.vprintf(msg, args);
+ va_end(args);
+ ba.printf("\n");
+ dout_emergency(buf);
- void printf(const char * format, ...) {
- va_list args;
- va_start(args, format);
- this->vprintf(format, args);
- va_end(args);
+ // TODO: get rid of this memory allocation.
+ ostringstream oss;
+ oss << *bt;
+ dout_emergency(oss.str());
+
+ if (g_assert_context) {
+ lderr(g_assert_context) << buf << std::endl;
+ *_dout << oss.str() << dendl;
+
+ // dump recent only if the abort signal handler won't do it for us
+ if (!g_assert_context->_conf->fatal_signal_handlers) {
+ g_assert_context->_log->dump_recent();
}
+ }
- void vprintf(const char * format, va_list args) {
- int n = vsnprintf(bufptr, remaining, format, args);
- if (n >= 0) {
- if (n < remaining) {
- remaining -= n;
- bufptr += n;
- } else {
- remaining = 0;
- }
- }
+ abort();
+ }
+
+ [[gnu::cold]] void __ceph_abort(const char *file, int line,
+ const char *func, const string& msg)
+ {
+ ostringstream tss;
+ tss << ceph_clock_now();
+
+ BackTrace *bt = new BackTrace(1);
+ ba.printf("%s: In function '%s' thread %llx time %s\n"
+ "%s: %d: abort()\n",
+ file, func, (unsigned long long)pthread_self(), tss.str().c_str(),
+ file, line);
+ dout_emergency(msg);
+
+ // TODO: get rid of this memory allocation.
+ ostringstream oss;
+ oss << *bt;
+ dout_emergency(oss.str());
+
+ if (g_assert_context) {
+ lderr(g_assert_context) << buf << std::endl;
+ *_dout << oss.str() << dendl;
+
+ // dump recent only if the abort signal handler won't do it for us
+ if (!g_assert_context->_conf->fatal_signal_handlers) {
+ g_assert_context->_log->dump_recent();
}
+ }
- private:
- char* bufptr;
- int remaining;
- };
+ abort();
+ }
+
+ [[gnu::cold]] void __ceph_abortf(const char *file, int line,
+ const char *func, const char* msg,
+ ...)
+ {
+ ostringstream tss;
+ tss << ceph_clock_now();
char buf[8096];
BufAppender ba(buf, sizeof(buf));
BackTrace *bt = new BackTrace(1);
ba.printf("%s: In function '%s' thread %llx time %s\n"
- "%s: %d: FAILED ceph_assert(%s)\n",
- file, func, (unsigned long long)pthread_self(), tss.str().c_str(),
- file, line, assertion);
- ba.printf("Assertion details: ");
+ "%s: %d: abort()\n",
+ file, func, (unsigned long long)pthread_self(), tss.str().c_str(),
+ file, line);
+ ba.printf("Abort details: ");
va_list args;
va_start(args, msg);
ba.vprintf(msg, args);
diff --git a/src/include/assert.h b/src/include/assert.h
index 93a45e85dbb..5fb985503ad 100644
--- a/src/include/assert.h
+++ b/src/include/assert.h
@@ -1,7 +1,8 @@
#ifndef CEPH_ASSERT_H
#define CEPH_ASSERT_H
-#include <stdlib.h>
+#include <cstdlib>
+#include <string>
#if defined(__linux__)
#include <features.h>
@@ -78,6 +79,12 @@ extern void __ceph_assertf_fail(const char *assertion, const char *file, int lin
__attribute__ ((__noreturn__));
extern void __ceph_assert_warn(const char *assertion, const char *file, int line, const char *function);
+[[noreturn]] void __ceph_abort(const char *file, int line, const char *func,
+ const std::string& msg);
+
+[[noreturn]] void __ceph_abortf(const char *file, int line, const char *func,
+ const char* msg, ...);
+
#define _CEPH_ASSERT_VOID_CAST static_cast<void>
#define assert_warn(expr) \
@@ -96,12 +103,14 @@ using namespace ceph;
* Currently, it's the same as assert(0), but we may one day make assert a
* debug-only thing, like it is in many projects.
*/
-#define ceph_abort() abort()
+#define ceph_abort(msg, ...) \
+ __ceph_abort( __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION, "abort() called")
+
+#define ceph_abort_msg(msg) \
+ __ceph_abort( __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION, msg)
-#define ceph_abort_msg(cct, msg) { \
- lgeneric_derr(cct) << "abort: " << msg << dendl; \
- abort(); \
- }
+#define ceph_abort_msgf(...) \
+ __ceph_abortf( __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION, __VA_ARGS__)
#define ceph_assert(expr) \
do { static const ceph::assert_data assert_data_ctx = \
diff --git a/src/kv/RocksDBStore.cc b/src/kv/RocksDBStore.cc
index fd02b8315c9..f484fb20c5f 100644
--- a/src/kv/RocksDBStore.cc
+++ b/src/kv/RocksDBStore.cc
@@ -1056,7 +1056,7 @@ int RocksDBStore::get(
if (status.ok()) {
(*out)[key].append(value);
} else if (status.IsIOError()) {
- ceph_abort_msg(cct, status.ToString());
+ ceph_abort_msg(status.getState());
}
}
} else {
@@ -1070,7 +1070,7 @@ int RocksDBStore::get(
if (status.ok()) {
(*out)[key].append(value);
} else if (status.IsIOError()) {
- ceph_abort_msg(cct, status.ToString());
+ ceph_abort_msg(status.getState());
}
}
}
@@ -1108,7 +1108,7 @@ int RocksDBStore::get(
} else if (s.IsNotFound()) {
r = -ENOENT;
} else {
- ceph_abort_msg(cct, s.ToString());
+ ceph_abort_msg(s.getState());
}
utime_t lat = ceph_clock_now() - start;
logger->inc(l_rocksdb_gets);
@@ -1146,7 +1146,7 @@ int RocksDBStore::get(
} else if (s.IsNotFound()) {
r = -ENOENT;
} else {
- ceph_abort_msg(cct, s.ToString());
+ ceph_abort_msg(s.getState());
}
utime_t lat = ceph_clock_now() - start;
logger->inc(l_rocksdb_gets);