]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/assert.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2008-2011 New Dream Network
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "include/compat.h"
16 #include "common/debug.h"
18 using std::ostringstream
;
21 static CephContext
*g_assert_context
= NULL
;
23 /* If you register an assert context, ceph_assert() will try to lock the dout
24 * stream of that context before starting an assert. This is nice because the
25 * output looks better. Your assert will not be interleaved with other dout
28 * However, this is strictly optional and library code currently does not
29 * register an assert context. The extra complexity of supporting this
30 * wouldn't really be worth it.
32 void register_assert_context(CephContext
*cct
)
34 ceph_assert(!g_assert_context
);
35 g_assert_context
= cct
;
38 [[gnu::cold
]] void __ceph_assert_fail(const char *assertion
,
39 const char *file
, int line
,
42 g_assert_condition
= assertion
;
46 g_assert_thread
= (unsigned long long)pthread_self();
47 ceph_pthread_getname(pthread_self(), g_assert_thread_name
,
48 sizeof(g_assert_thread_name
));
51 tss
<< ceph_clock_now();
53 snprintf(g_assert_msg
, sizeof(g_assert_msg
),
54 "%s: In function '%s' thread %llx time %s\n"
55 "%s: %d: FAILED ceph_assert(%s)\n",
56 file
, func
, (unsigned long long)pthread_self(), tss
.str().c_str(),
57 file
, line
, assertion
);
58 dout_emergency(g_assert_msg
);
60 // TODO: get rid of this memory allocation.
62 oss
<< ClibBackTrace(1);
63 dout_emergency(oss
.str());
65 if (g_assert_context
) {
66 lderr(g_assert_context
) << g_assert_msg
<< std::endl
;
67 *_dout
<< oss
.str() << dendl
;
69 // dump recent only if the abort signal handler won't do it for us
70 if (!g_assert_context
->_conf
->fatal_signal_handlers
) {
71 g_assert_context
->_log
->dump_recent();
78 [[gnu::cold
]] void __ceph_assert_fail(const assert_data
&ctx
)
80 __ceph_assert_fail(ctx
.assertion
, ctx
.file
, ctx
.line
, ctx
.function
);
85 BufAppender(char* buf
, int size
) : bufptr(buf
), remaining(size
) {}
87 void printf(const char * format
, ...) {
89 va_start(args
, format
);
90 this->vprintf(format
, args
);
94 void vprintf(const char * format
, va_list args
) {
95 int n
= vsnprintf(bufptr
, remaining
, format
, args
);
112 [[gnu::cold
]] void __ceph_assertf_fail(const char *assertion
,
113 const char *file
, int line
,
114 const char *func
, const char* msg
,
118 tss
<< ceph_clock_now();
120 g_assert_condition
= assertion
;
121 g_assert_file
= file
;
122 g_assert_line
= line
;
123 g_assert_func
= func
;
124 g_assert_thread
= (unsigned long long)pthread_self();
125 ceph_pthread_getname(pthread_self(), g_assert_thread_name
,
126 sizeof(g_assert_thread_name
));
128 BufAppender
ba(g_assert_msg
, sizeof(g_assert_msg
));
129 BackTrace
*bt
= new ClibBackTrace(1);
130 ba
.printf("%s: In function '%s' thread %llx time %s\n"
131 "%s: %d: FAILED ceph_assert(%s)\n",
132 file
, func
, (unsigned long long)pthread_self(), tss
.str().c_str(),
133 file
, line
, assertion
);
134 ba
.printf("Assertion details: ");
137 ba
.vprintf(msg
, args
);
140 dout_emergency(g_assert_msg
);
142 // TODO: get rid of this memory allocation.
145 dout_emergency(oss
.str());
147 if (g_assert_context
) {
148 lderr(g_assert_context
) << g_assert_msg
<< std::endl
;
149 *_dout
<< oss
.str() << dendl
;
151 // dump recent only if the abort signal handler won't do it for us
152 if (!g_assert_context
->_conf
->fatal_signal_handlers
) {
153 g_assert_context
->_log
->dump_recent();
160 [[gnu::cold
]] void __ceph_abort(const char *file
, int line
,
161 const char *func
, const std::string
& msg
)
164 tss
<< ceph_clock_now();
166 g_assert_condition
= "abort";
167 g_assert_file
= file
;
168 g_assert_line
= line
;
169 g_assert_func
= func
;
170 g_assert_thread
= (unsigned long long)pthread_self();
171 ceph_pthread_getname(pthread_self(), g_assert_thread_name
,
172 sizeof(g_assert_thread_name
));
174 BackTrace
*bt
= new ClibBackTrace(1);
175 snprintf(g_assert_msg
, sizeof(g_assert_msg
),
176 "%s: In function '%s' thread %llx time %s\n"
177 "%s: %d: ceph_abort_msg(\"%s\")\n", file
, func
,
178 (unsigned long long)pthread_self(),
179 tss
.str().c_str(), file
, line
,
181 dout_emergency(g_assert_msg
);
183 // TODO: get rid of this memory allocation.
186 dout_emergency(oss
.str());
188 if (g_assert_context
) {
189 lderr(g_assert_context
) << g_assert_msg
<< std::endl
;
190 *_dout
<< oss
.str() << dendl
;
192 // dump recent only if the abort signal handler won't do it for us
193 if (!g_assert_context
->_conf
->fatal_signal_handlers
) {
194 g_assert_context
->_log
->dump_recent();
201 [[gnu::cold
]] void __ceph_abortf(const char *file
, int line
,
202 const char *func
, const char* msg
,
206 tss
<< ceph_clock_now();
208 g_assert_condition
= "abort";
209 g_assert_file
= file
;
210 g_assert_line
= line
;
211 g_assert_func
= func
;
212 g_assert_thread
= (unsigned long long)pthread_self();
213 ceph_pthread_getname(pthread_self(), g_assert_thread_name
,
214 sizeof(g_assert_thread_name
));
216 BufAppender
ba(g_assert_msg
, sizeof(g_assert_msg
));
217 BackTrace
*bt
= new ClibBackTrace(1);
218 ba
.printf("%s: In function '%s' thread %llx time %s\n"
220 file
, func
, (unsigned long long)pthread_self(), tss
.str().c_str(),
222 ba
.printf("Abort details: ");
225 ba
.vprintf(msg
, args
);
228 dout_emergency(g_assert_msg
);
230 // TODO: get rid of this memory allocation.
233 dout_emergency(oss
.str());
235 if (g_assert_context
) {
236 lderr(g_assert_context
) << g_assert_msg
<< std::endl
;
237 *_dout
<< oss
.str() << dendl
;
239 // dump recent only if the abort signal handler won't do it for us
240 if (!g_assert_context
->_conf
->fatal_signal_handlers
) {
241 g_assert_context
->_log
->dump_recent();
248 [[gnu::cold
]] void __ceph_assert_warn(const char *assertion
,
250 int line
, const char *func
)
253 snprintf(buf
, sizeof(buf
),
254 "WARNING: ceph_assert(%s) at: %s: %d: %s()\n",
255 assertion
, file
, line
, func
);