104 lines · cpp
1//===-- lib/runtime/terminator.cpp ------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang-rt/runtime/terminator.h"10#include <cstdio>11#include <cstdlib>12 13namespace Fortran::runtime {14 15#if !defined(RT_DEVICE_COMPILATION)16[[maybe_unused]] static void (*crashHandler)(17 const char *, int, const char *, va_list &){nullptr};18 19void Terminator::RegisterCrashHandler(20 void (*handler)(const char *, int, const char *, va_list &)) {21 crashHandler = handler;22}23 24void Terminator::InvokeCrashHandler(const char *message, ...) const {25 if (crashHandler) {26 va_list ap;27 va_start(ap, message);28 crashHandler(sourceFileName_, sourceLine_, message, ap);29 va_end(ap);30 }31}32 33[[noreturn]] void Terminator::CrashArgs(34 const char *message, va_list &ap) const {35 CrashHeader();36 std::vfprintf(stderr, message, ap);37 va_end(ap);38 CrashFooter();39}40#endif41 42RT_OFFLOAD_API_GROUP_BEGIN43 44RT_API_ATTRS void Terminator::CrashHeader() const {45#if defined(RT_DEVICE_COMPILATION)46 std::printf("\nfatal Fortran runtime error");47 if (sourceFileName_) {48 std::printf("(%s", sourceFileName_);49 if (sourceLine_) {50 std::printf(":%d", sourceLine_);51 }52 std::printf(")");53 }54 std::printf(": ");55#else56 std::fputs("\nfatal Fortran runtime error", stderr);57 if (sourceFileName_) {58 std::fprintf(stderr, "(%s", sourceFileName_);59 if (sourceLine_) {60 std::fprintf(stderr, ":%d", sourceLine_);61 }62 fputc(')', stderr);63 }64 std::fputs(": ", stderr);65#endif66}67 68[[noreturn]] RT_API_ATTRS void Terminator::CrashFooter() const {69#if defined(RT_DEVICE_COMPILATION)70 std::printf("\n");71#else72 fputc('\n', stderr);73 // FIXME: re-enable the flush along with the IO enabling.74 io::FlushOutputOnCrash(*this);75#endif76 NotifyOtherImagesOfErrorTermination();77#if defined(RT_DEVICE_COMPILATION)78 DeviceTrap();79#else80 std::abort();81#endif82}83 84[[noreturn]] RT_API_ATTRS void Terminator::CheckFailed(85 const char *predicate, const char *file, int line) const {86 Crash("Internal error: RUNTIME_CHECK(%s) failed at %s(%d)", predicate, file,87 line);88}89 90[[noreturn]] RT_API_ATTRS void Terminator::CheckFailed(91 const char *predicate) const {92 Crash("Internal error: RUNTIME_CHECK(%s) failed at %s(%d)", predicate,93 sourceFileName_, sourceLine_);94}95 96// TODO: These will be defined in the coarray runtime library97RT_API_ATTRS void NotifyOtherImagesOfNormalEnd() {}98RT_API_ATTRS void NotifyOtherImagesOfFailImageStatement() {}99RT_API_ATTRS void NotifyOtherImagesOfErrorTermination() {}100 101RT_OFFLOAD_API_GROUP_END102 103} // namespace Fortran::runtime104