xref: /oneTBB/src/tbb/assert_impl.h (revision fa3268c3)
1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 #ifndef __TBB_assert_impl_H
18 #define __TBB_assert_impl_H
19 
20 #include "oneapi/tbb/detail/_config.h"
21 #include "oneapi/tbb/detail/_utils.h"
22 
23 #include <cstdio>
24 #include <cstdlib>
25 #include <cstring>
26 #include <cstdarg>
27 #if _MSC_VER && _DEBUG
28 #include <crtdbg.h>
29 #endif
30 
31 #include <mutex>
32 
33 namespace tbb {
34 namespace detail {
35 namespace r1 {
36 
37 // TODO: consider extension for formatted error description string
38 static void assertion_failure_impl(const char* location, int line, const char* expression, const char* comment) {
39 
40     std::fprintf(stderr, "Assertion %s failed (located in the %s function, line in file: %d)\n",
41         expression, location, line);
42 
43     if (comment) {
44         std::fprintf(stderr, "Detailed description: %s\n", comment);
45     }
46 #if _MSC_VER && _DEBUG
47     if (1 == _CrtDbgReport(_CRT_ASSERT, location, line, "tbb_debug.dll", "%s\r\n%s", expression, comment?comment:"")) {
48         _CrtDbgBreak();
49     } else
50 #endif
51     {
52         std::fflush(stderr);
53         std::abort();
54     }
55 }
56 
57 // Do not move the definition into the assertion_failure function because it will require "magic statics".
58 // It will bring a dependency on C++ runtime on some platforms while assert_impl.h is reused in tbbmalloc
59 // that should not depend on C++ runtime
60 static std::atomic<do_once_state> assertion_state;
61 
62 void __TBB_EXPORTED_FUNC assertion_failure(const char* location, int line, const char* expression, const char* comment) {
63 #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
64     // Workaround for erroneous "unreachable code" during assertion throwing using call_once
65     #pragma warning (push)
66     #pragma warning (disable: 4702)
67 #endif
68     // We cannot use std::call_once because it brings a dependency on C++ runtime on some platforms
69     // while assert_impl.h is reused in tbbmalloc that should not depend on C++ runtime
70     atomic_do_once([&](){ assertion_failure_impl(location, line, expression, comment); }, assertion_state);
71 #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
72     #pragma warning (pop)
73 #endif
74 }
75 
76 //! Report a runtime warning.
77 void runtime_warning( const char* format, ... ) {
78     char str[1024]; std::memset(str, 0, 1024);
79     va_list args; va_start(args, format);
80     vsnprintf( str, 1024-1, format, args);
81     va_end(args);
82     fprintf(stderr, "TBB Warning: %s\n", str);
83 }
84 
85 } // namespace r1
86 } // namespace detail
87 } // namespace tbb
88 
89 #endif // __TBB_assert_impl_H
90 
91