Apache Mesos
abort.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_ABORT_HPP__
14 #define __STOUT_ABORT_HPP__
15 
16 #include <errno.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #ifdef __WINDOWS__
22 #include <stout/windows.hpp>
23 #else
24 #include <unistd.h>
25 #endif // __WINDOWS__
26 
27 #include <string>
28 
29 #include <stout/attributes.hpp>
30 
31 // NOTE: These macros are already defined in Visual Studio (Windows) headers.
32 #ifndef __WINDOWS__
33 #define __STRINGIZE(x) #x
34 #define _STRINGIZE(x) __STRINGIZE(x)
35 #endif // __WINDOWS__
36 
37 // Signal safe abort which prints a message.
38 #define _ABORT_PREFIX "ABORT: (" __FILE__ ":" _STRINGIZE(__LINE__) "): "
39 
40 #define ABORT(...) _Abort(_ABORT_PREFIX, __VA_ARGS__)
41 
42 
43 inline NORETURN void _Abort(const char* prefix, const char* message)
44 {
45  // NOTE: On Windows, `_write` takes an `unsigned int`, not `size_t`. We
46  // preform an explicit type conversion here to silence the warning. `strlen`
47  // always returns a positive result, which means it is safe to cast it to an
48  // unsigned value.
49 #ifndef __WINDOWS__
50  const size_t prefix_len = strlen(prefix);
51  const size_t message_len = strlen(message);
52 #else
53  const unsigned int prefix_len = static_cast<unsigned int>(strlen(prefix));
54  const unsigned int message_len = static_cast<unsigned int>(strlen(message));
55 #endif // !__WINDOWS__
56 
57  // Write the failure message in an async-signal safe manner,
58  // assuming strlen is async-signal safe or optimized out.
59  // In fact, it is highly unlikely that strlen would be
60  // implemented in an unsafe manner:
61  // http://austingroupbugs.net/view.php?id=692
62  // NOTE: we can't use `signal_safe::write`, because it's defined in the header
63  // which can't be included due to circular dependency of headers.
64  while (::write(STDERR_FILENO, prefix, prefix_len) == -1 &&
65  errno == EINTR);
66  while (message != nullptr &&
67  ::write(STDERR_FILENO, message, message_len) == -1 &&
68  errno == EINTR);
69 
70  // NOTE: Since `1` can be interpreted as either an `unsigned int` or a
71  // `size_t`, removing the `static_cast` here makes this call ambiguous
72  // between the `write` in windows.hpp and the (deprecated) `write` in the
73  // Windows CRT headers.
74  while (::write(STDERR_FILENO, "\n", static_cast<size_t>(1)) == -1 &&
75  errno == EINTR);
76  abort();
77 }
78 
79 
80 inline NORETURN void _Abort(const char* prefix, const std::string& message)
81 {
82  _Abort(prefix, message.c_str());
83 }
84 
85 
86 #endif // __STOUT_ABORT_HPP__
constexpr const char * prefix
Definition: os.hpp:94
#define STDERR_FILENO
Definition: windows.hpp:161
Protocol< WriteRequest, WriteResponse > write
NORETURN void _Abort(const char *prefix, const char *message)
Definition: abort.hpp:43
#define NORETURN
Definition: attributes.hpp:20