| /* |
| * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license |
| * that can be found in the LICENSE file. |
| */ |
| |
| #include "KAssert.h" |
| |
| #include <array> |
| #include <cinttypes> |
| #include <cstdarg> |
| #include <cstdlib> |
| |
| #include "std_support/Span.hpp" |
| #include "CallsChecker.hpp" |
| #include "Format.h" |
| #include "Porting.h" |
| #include "StackTrace.hpp" |
| #include "CrashHandler.hpp" |
| |
| using namespace kotlin; |
| |
| namespace { |
| |
| THREAD_LOCAL_VARIABLE bool assertionReportInProgress = false; |
| |
| void PrintAssert(bool allowStacktrace, const char* location, const char* format, std::va_list args) noexcept { |
| CallsCheckerIgnoreGuard ignoreCallsChecker; |
| |
| if (assertionReportInProgress) { |
| // WARNING: avoid anything that can assert ar panic here |
| konan::consoleErrorf("An attempt to report an assertion lead to another failure:\n"); |
| // now try to print the information we have in the simplest way possible |
| if (location != nullptr) { |
| konan::consoleErrorf("%s: ", location); |
| } |
| // do not bother with format string expansion |
| konan::consoleErrorf("%s\n", format); |
| return; |
| } |
| AutoReset recursionGuard(&assertionReportInProgress, true); |
| |
| std::array<char, 1024> bufferStorage; |
| std_support::span<char> buffer(bufferStorage); |
| |
| buffer = FormatToSpan(buffer, "[tid#%" PRIuPTR "] ", konan::currentThreadId()); |
| |
| // Write the title with a source location. |
| if (location != nullptr) { |
| buffer = FormatToSpan(buffer, "%s: runtime assert: ", location); |
| } else { |
| buffer = FormatToSpan(buffer, "runtime assert: "); |
| } |
| |
| // Write the message. |
| buffer = VFormatToSpan(buffer, format, args); |
| |
| konan::consoleErrorUtf8(bufferStorage.data(), bufferStorage.size() - buffer.size()); |
| konan::consoleErrorf("\n"); |
| if (allowStacktrace) { |
| kotlin::PrintStackTraceStderr(); |
| } |
| } |
| |
| } // namespace |
| |
| void internal::RuntimeAssertFailedLog(bool allowStacktrace, const char* location, const char* format, ...) { |
| std::va_list args; |
| va_start(args, format); |
| PrintAssert(allowStacktrace, location, format, args); |
| va_end(args); |
| } |
| |
| RUNTIME_NORETURN void internal::RuntimeAssertFailedPanic(bool allowStacktrace, const char* location, const char* format, ...) { |
| std::va_list args; |
| va_start(args, format); |
| PrintAssert(allowStacktrace, location, format, args); |
| va_end(args); |
| kotlin::writeMinidump(); |
| std::abort(); |
| } |