493 lines
11 KiB
C++
493 lines
11 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <folly/lang/SafeAssert.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <folly/Conv.h>
|
|
#include <folly/FileUtil.h>
|
|
|
|
namespace folly {
|
|
namespace detail {
|
|
|
|
namespace {
|
|
|
|
// script (centos):
|
|
//
|
|
// for e in $(
|
|
// cat /usr/include/asm*/errno*.h | awk '{print $2}' | grep -P '^E' | sort
|
|
// ) ; do
|
|
// echo "#if defined($e)"
|
|
// echo " FOLLY_DETAIL_ERROR($e),"
|
|
// echo "#endif"
|
|
// done
|
|
|
|
#define FOLLY_DETAIL_ERROR(name) \
|
|
{ name, #name }
|
|
constexpr std::pair<int, const char*> errors[] = {
|
|
#if defined(E2BIG)
|
|
FOLLY_DETAIL_ERROR(E2BIG),
|
|
#endif
|
|
#if defined(EACCES)
|
|
FOLLY_DETAIL_ERROR(EACCES),
|
|
#endif
|
|
#if defined(EADDRINUSE)
|
|
FOLLY_DETAIL_ERROR(EADDRINUSE),
|
|
#endif
|
|
#if defined(EADDRNOTAVAIL)
|
|
FOLLY_DETAIL_ERROR(EADDRNOTAVAIL),
|
|
#endif
|
|
#if defined(EADV)
|
|
FOLLY_DETAIL_ERROR(EADV),
|
|
#endif
|
|
#if defined(EAFNOSUPPORT)
|
|
FOLLY_DETAIL_ERROR(EAFNOSUPPORT),
|
|
#endif
|
|
#if defined(EAGAIN)
|
|
FOLLY_DETAIL_ERROR(EAGAIN),
|
|
#endif
|
|
#if defined(EALREADY)
|
|
FOLLY_DETAIL_ERROR(EALREADY),
|
|
#endif
|
|
#if defined(EBADE)
|
|
FOLLY_DETAIL_ERROR(EBADE),
|
|
#endif
|
|
#if defined(EBADF)
|
|
FOLLY_DETAIL_ERROR(EBADF),
|
|
#endif
|
|
#if defined(EBADFD)
|
|
FOLLY_DETAIL_ERROR(EBADFD),
|
|
#endif
|
|
#if defined(EBADMSG)
|
|
FOLLY_DETAIL_ERROR(EBADMSG),
|
|
#endif
|
|
#if defined(EBADR)
|
|
FOLLY_DETAIL_ERROR(EBADR),
|
|
#endif
|
|
#if defined(EBADRQC)
|
|
FOLLY_DETAIL_ERROR(EBADRQC),
|
|
#endif
|
|
#if defined(EBADSLT)
|
|
FOLLY_DETAIL_ERROR(EBADSLT),
|
|
#endif
|
|
#if defined(EBFONT)
|
|
FOLLY_DETAIL_ERROR(EBFONT),
|
|
#endif
|
|
#if defined(EBUSY)
|
|
FOLLY_DETAIL_ERROR(EBUSY),
|
|
#endif
|
|
#if defined(ECANCELED)
|
|
FOLLY_DETAIL_ERROR(ECANCELED),
|
|
#endif
|
|
#if defined(ECHILD)
|
|
FOLLY_DETAIL_ERROR(ECHILD),
|
|
#endif
|
|
#if defined(ECHRNG)
|
|
FOLLY_DETAIL_ERROR(ECHRNG),
|
|
#endif
|
|
#if defined(ECOMM)
|
|
FOLLY_DETAIL_ERROR(ECOMM),
|
|
#endif
|
|
#if defined(ECONNABORTED)
|
|
FOLLY_DETAIL_ERROR(ECONNABORTED),
|
|
#endif
|
|
#if defined(ECONNREFUSED)
|
|
FOLLY_DETAIL_ERROR(ECONNREFUSED),
|
|
#endif
|
|
#if defined(ECONNRESET)
|
|
FOLLY_DETAIL_ERROR(ECONNRESET),
|
|
#endif
|
|
#if defined(EDEADLK)
|
|
FOLLY_DETAIL_ERROR(EDEADLK),
|
|
#endif
|
|
#if defined(EDEADLOCK)
|
|
FOLLY_DETAIL_ERROR(EDEADLOCK),
|
|
#endif
|
|
#if defined(EDESTADDRREQ)
|
|
FOLLY_DETAIL_ERROR(EDESTADDRREQ),
|
|
#endif
|
|
#if defined(EDOM)
|
|
FOLLY_DETAIL_ERROR(EDOM),
|
|
#endif
|
|
#if defined(EDOTDOT)
|
|
FOLLY_DETAIL_ERROR(EDOTDOT),
|
|
#endif
|
|
#if defined(EDQUOT)
|
|
FOLLY_DETAIL_ERROR(EDQUOT),
|
|
#endif
|
|
#if defined(EEXIST)
|
|
FOLLY_DETAIL_ERROR(EEXIST),
|
|
#endif
|
|
#if defined(EFAULT)
|
|
FOLLY_DETAIL_ERROR(EFAULT),
|
|
#endif
|
|
#if defined(EFBIG)
|
|
FOLLY_DETAIL_ERROR(EFBIG),
|
|
#endif
|
|
#if defined(EHOSTDOWN)
|
|
FOLLY_DETAIL_ERROR(EHOSTDOWN),
|
|
#endif
|
|
#if defined(EHOSTUNREACH)
|
|
FOLLY_DETAIL_ERROR(EHOSTUNREACH),
|
|
#endif
|
|
#if defined(EHWPOISON)
|
|
FOLLY_DETAIL_ERROR(EHWPOISON),
|
|
#endif
|
|
#if defined(EIDRM)
|
|
FOLLY_DETAIL_ERROR(EIDRM),
|
|
#endif
|
|
#if defined(EILSEQ)
|
|
FOLLY_DETAIL_ERROR(EILSEQ),
|
|
#endif
|
|
#if defined(EINPROGRESS)
|
|
FOLLY_DETAIL_ERROR(EINPROGRESS),
|
|
#endif
|
|
#if defined(EINTR)
|
|
FOLLY_DETAIL_ERROR(EINTR),
|
|
#endif
|
|
#if defined(EINVAL)
|
|
FOLLY_DETAIL_ERROR(EINVAL),
|
|
#endif
|
|
#if defined(EIO)
|
|
FOLLY_DETAIL_ERROR(EIO),
|
|
#endif
|
|
#if defined(EISCONN)
|
|
FOLLY_DETAIL_ERROR(EISCONN),
|
|
#endif
|
|
#if defined(EISDIR)
|
|
FOLLY_DETAIL_ERROR(EISDIR),
|
|
#endif
|
|
#if defined(EISNAM)
|
|
FOLLY_DETAIL_ERROR(EISNAM),
|
|
#endif
|
|
#if defined(EKEYEXPIRED)
|
|
FOLLY_DETAIL_ERROR(EKEYEXPIRED),
|
|
#endif
|
|
#if defined(EKEYREJECTED)
|
|
FOLLY_DETAIL_ERROR(EKEYREJECTED),
|
|
#endif
|
|
#if defined(EKEYREVOKED)
|
|
FOLLY_DETAIL_ERROR(EKEYREVOKED),
|
|
#endif
|
|
#if defined(EL2HLT)
|
|
FOLLY_DETAIL_ERROR(EL2HLT),
|
|
#endif
|
|
#if defined(EL2NSYNC)
|
|
FOLLY_DETAIL_ERROR(EL2NSYNC),
|
|
#endif
|
|
#if defined(EL3HLT)
|
|
FOLLY_DETAIL_ERROR(EL3HLT),
|
|
#endif
|
|
#if defined(EL3RST)
|
|
FOLLY_DETAIL_ERROR(EL3RST),
|
|
#endif
|
|
#if defined(ELIBACC)
|
|
FOLLY_DETAIL_ERROR(ELIBACC),
|
|
#endif
|
|
#if defined(ELIBBAD)
|
|
FOLLY_DETAIL_ERROR(ELIBBAD),
|
|
#endif
|
|
#if defined(ELIBEXEC)
|
|
FOLLY_DETAIL_ERROR(ELIBEXEC),
|
|
#endif
|
|
#if defined(ELIBMAX)
|
|
FOLLY_DETAIL_ERROR(ELIBMAX),
|
|
#endif
|
|
#if defined(ELIBSCN)
|
|
FOLLY_DETAIL_ERROR(ELIBSCN),
|
|
#endif
|
|
#if defined(ELNRNG)
|
|
FOLLY_DETAIL_ERROR(ELNRNG),
|
|
#endif
|
|
#if defined(ELOOP)
|
|
FOLLY_DETAIL_ERROR(ELOOP),
|
|
#endif
|
|
#if defined(EMEDIUMTYPE)
|
|
FOLLY_DETAIL_ERROR(EMEDIUMTYPE),
|
|
#endif
|
|
#if defined(EMFILE)
|
|
FOLLY_DETAIL_ERROR(EMFILE),
|
|
#endif
|
|
#if defined(EMLINK)
|
|
FOLLY_DETAIL_ERROR(EMLINK),
|
|
#endif
|
|
#if defined(EMSGSIZE)
|
|
FOLLY_DETAIL_ERROR(EMSGSIZE),
|
|
#endif
|
|
#if defined(EMULTIHOP)
|
|
FOLLY_DETAIL_ERROR(EMULTIHOP),
|
|
#endif
|
|
#if defined(ENAMETOOLONG)
|
|
FOLLY_DETAIL_ERROR(ENAMETOOLONG),
|
|
#endif
|
|
#if defined(ENAVAIL)
|
|
FOLLY_DETAIL_ERROR(ENAVAIL),
|
|
#endif
|
|
#if defined(ENETDOWN)
|
|
FOLLY_DETAIL_ERROR(ENETDOWN),
|
|
#endif
|
|
#if defined(ENETRESET)
|
|
FOLLY_DETAIL_ERROR(ENETRESET),
|
|
#endif
|
|
#if defined(ENETUNREACH)
|
|
FOLLY_DETAIL_ERROR(ENETUNREACH),
|
|
#endif
|
|
#if defined(ENFILE)
|
|
FOLLY_DETAIL_ERROR(ENFILE),
|
|
#endif
|
|
#if defined(ENOANO)
|
|
FOLLY_DETAIL_ERROR(ENOANO),
|
|
#endif
|
|
#if defined(ENOBUFS)
|
|
FOLLY_DETAIL_ERROR(ENOBUFS),
|
|
#endif
|
|
#if defined(ENOCSI)
|
|
FOLLY_DETAIL_ERROR(ENOCSI),
|
|
#endif
|
|
#if defined(ENODATA)
|
|
FOLLY_DETAIL_ERROR(ENODATA),
|
|
#endif
|
|
#if defined(ENODEV)
|
|
FOLLY_DETAIL_ERROR(ENODEV),
|
|
#endif
|
|
#if defined(ENOENT)
|
|
FOLLY_DETAIL_ERROR(ENOENT),
|
|
#endif
|
|
#if defined(ENOEXEC)
|
|
FOLLY_DETAIL_ERROR(ENOEXEC),
|
|
#endif
|
|
#if defined(ENOKEY)
|
|
FOLLY_DETAIL_ERROR(ENOKEY),
|
|
#endif
|
|
#if defined(ENOLCK)
|
|
FOLLY_DETAIL_ERROR(ENOLCK),
|
|
#endif
|
|
#if defined(ENOLINK)
|
|
FOLLY_DETAIL_ERROR(ENOLINK),
|
|
#endif
|
|
#if defined(ENOMEDIUM)
|
|
FOLLY_DETAIL_ERROR(ENOMEDIUM),
|
|
#endif
|
|
#if defined(ENOMEM)
|
|
FOLLY_DETAIL_ERROR(ENOMEM),
|
|
#endif
|
|
#if defined(ENOMSG)
|
|
FOLLY_DETAIL_ERROR(ENOMSG),
|
|
#endif
|
|
#if defined(ENONET)
|
|
FOLLY_DETAIL_ERROR(ENONET),
|
|
#endif
|
|
#if defined(ENOPKG)
|
|
FOLLY_DETAIL_ERROR(ENOPKG),
|
|
#endif
|
|
#if defined(ENOPROTOOPT)
|
|
FOLLY_DETAIL_ERROR(ENOPROTOOPT),
|
|
#endif
|
|
#if defined(ENOSPC)
|
|
FOLLY_DETAIL_ERROR(ENOSPC),
|
|
#endif
|
|
#if defined(ENOSR)
|
|
FOLLY_DETAIL_ERROR(ENOSR),
|
|
#endif
|
|
#if defined(ENOSTR)
|
|
FOLLY_DETAIL_ERROR(ENOSTR),
|
|
#endif
|
|
#if defined(ENOSYS)
|
|
FOLLY_DETAIL_ERROR(ENOSYS),
|
|
#endif
|
|
#if defined(ENOTBLK)
|
|
FOLLY_DETAIL_ERROR(ENOTBLK),
|
|
#endif
|
|
#if defined(ENOTCONN)
|
|
FOLLY_DETAIL_ERROR(ENOTCONN),
|
|
#endif
|
|
#if defined(ENOTDIR)
|
|
FOLLY_DETAIL_ERROR(ENOTDIR),
|
|
#endif
|
|
#if defined(ENOTEMPTY)
|
|
FOLLY_DETAIL_ERROR(ENOTEMPTY),
|
|
#endif
|
|
#if defined(ENOTNAM)
|
|
FOLLY_DETAIL_ERROR(ENOTNAM),
|
|
#endif
|
|
#if defined(ENOTRECOVERABLE)
|
|
FOLLY_DETAIL_ERROR(ENOTRECOVERABLE),
|
|
#endif
|
|
#if defined(ENOTSOCK)
|
|
FOLLY_DETAIL_ERROR(ENOTSOCK),
|
|
#endif
|
|
#if defined(ENOTTY)
|
|
FOLLY_DETAIL_ERROR(ENOTTY),
|
|
#endif
|
|
#if defined(ENOTUNIQ)
|
|
FOLLY_DETAIL_ERROR(ENOTUNIQ),
|
|
#endif
|
|
#if defined(ENXIO)
|
|
FOLLY_DETAIL_ERROR(ENXIO),
|
|
#endif
|
|
#if defined(EOPNOTSUPP)
|
|
FOLLY_DETAIL_ERROR(EOPNOTSUPP),
|
|
#endif
|
|
#if defined(EOVERFLOW)
|
|
FOLLY_DETAIL_ERROR(EOVERFLOW),
|
|
#endif
|
|
#if defined(EOWNERDEAD)
|
|
FOLLY_DETAIL_ERROR(EOWNERDEAD),
|
|
#endif
|
|
#if defined(EPERM)
|
|
FOLLY_DETAIL_ERROR(EPERM),
|
|
#endif
|
|
#if defined(EPFNOSUPPORT)
|
|
FOLLY_DETAIL_ERROR(EPFNOSUPPORT),
|
|
#endif
|
|
#if defined(EPIPE)
|
|
FOLLY_DETAIL_ERROR(EPIPE),
|
|
#endif
|
|
#if defined(EPROTO)
|
|
FOLLY_DETAIL_ERROR(EPROTO),
|
|
#endif
|
|
#if defined(EPROTONOSUPPORT)
|
|
FOLLY_DETAIL_ERROR(EPROTONOSUPPORT),
|
|
#endif
|
|
#if defined(EPROTOTYPE)
|
|
FOLLY_DETAIL_ERROR(EPROTOTYPE),
|
|
#endif
|
|
#if defined(ERANGE)
|
|
FOLLY_DETAIL_ERROR(ERANGE),
|
|
#endif
|
|
#if defined(EREMCHG)
|
|
FOLLY_DETAIL_ERROR(EREMCHG),
|
|
#endif
|
|
#if defined(EREMOTE)
|
|
FOLLY_DETAIL_ERROR(EREMOTE),
|
|
#endif
|
|
#if defined(EREMOTEIO)
|
|
FOLLY_DETAIL_ERROR(EREMOTEIO),
|
|
#endif
|
|
#if defined(ERESTART)
|
|
FOLLY_DETAIL_ERROR(ERESTART),
|
|
#endif
|
|
#if defined(ERFKILL)
|
|
FOLLY_DETAIL_ERROR(ERFKILL),
|
|
#endif
|
|
#if defined(EROFS)
|
|
FOLLY_DETAIL_ERROR(EROFS),
|
|
#endif
|
|
#if defined(ESHUTDOWN)
|
|
FOLLY_DETAIL_ERROR(ESHUTDOWN),
|
|
#endif
|
|
#if defined(ESOCKTNOSUPPORT)
|
|
FOLLY_DETAIL_ERROR(ESOCKTNOSUPPORT),
|
|
#endif
|
|
#if defined(ESPIPE)
|
|
FOLLY_DETAIL_ERROR(ESPIPE),
|
|
#endif
|
|
#if defined(ESRCH)
|
|
FOLLY_DETAIL_ERROR(ESRCH),
|
|
#endif
|
|
#if defined(ESRMNT)
|
|
FOLLY_DETAIL_ERROR(ESRMNT),
|
|
#endif
|
|
#if defined(ESTALE)
|
|
FOLLY_DETAIL_ERROR(ESTALE),
|
|
#endif
|
|
#if defined(ESTRPIPE)
|
|
FOLLY_DETAIL_ERROR(ESTRPIPE),
|
|
#endif
|
|
#if defined(ETIME)
|
|
FOLLY_DETAIL_ERROR(ETIME),
|
|
#endif
|
|
#if defined(ETIMEDOUT)
|
|
FOLLY_DETAIL_ERROR(ETIMEDOUT),
|
|
#endif
|
|
#if defined(ETOOMANYREFS)
|
|
FOLLY_DETAIL_ERROR(ETOOMANYREFS),
|
|
#endif
|
|
#if defined(ETXTBSY)
|
|
FOLLY_DETAIL_ERROR(ETXTBSY),
|
|
#endif
|
|
#if defined(EUCLEAN)
|
|
FOLLY_DETAIL_ERROR(EUCLEAN),
|
|
#endif
|
|
#if defined(EUNATCH)
|
|
FOLLY_DETAIL_ERROR(EUNATCH),
|
|
#endif
|
|
#if defined(EUSERS)
|
|
FOLLY_DETAIL_ERROR(EUSERS),
|
|
#endif
|
|
#if defined(EWOULDBLOCK)
|
|
FOLLY_DETAIL_ERROR(EWOULDBLOCK),
|
|
#endif
|
|
#if defined(EXDEV)
|
|
FOLLY_DETAIL_ERROR(EXDEV),
|
|
#endif
|
|
#if defined(EXFULL)
|
|
FOLLY_DETAIL_ERROR(EXFULL),
|
|
#endif
|
|
};
|
|
#undef FOLLY_DETAIL_ERROR
|
|
|
|
void writeStderr(const char* s, size_t len) {
|
|
writeFull(STDERR_FILENO, s, len);
|
|
}
|
|
void writeStderr(const char* s) {
|
|
writeStderr(s, strlen(s));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void assertionFailure(
|
|
const char* expr,
|
|
const char* msg,
|
|
const char* file,
|
|
unsigned int line,
|
|
const char* function,
|
|
int error) {
|
|
writeStderr("\n\nAssertion failure: ");
|
|
writeStderr(expr + 1, strlen(expr) - 2);
|
|
writeStderr("\nMessage: ");
|
|
writeStderr(msg);
|
|
writeStderr("\nFile: ");
|
|
writeStderr(file);
|
|
writeStderr("\nLine: ");
|
|
char buf[20];
|
|
uint32_t n = uint64ToBufferUnsafe(line, buf);
|
|
writeFull(STDERR_FILENO, buf, n);
|
|
writeStderr("\nFunction: ");
|
|
writeStderr(function);
|
|
if (error) {
|
|
// if errno is set, print the number and the symbolic constant
|
|
// the symbolic constant is necessary since actual numbers may vary
|
|
// for simplicity, do not attempt to mimic strerror printing descriptions
|
|
writeStderr("\nError: ");
|
|
n = uint64ToBufferUnsafe(error, buf);
|
|
writeFull(STDERR_FILENO, buf, n);
|
|
writeStderr(" (");
|
|
// the list is not required to be sorted; but the program is about to die
|
|
auto const pred = [=](auto const e) { return e.first == error; };
|
|
auto const it = std::find_if(std::begin(errors), std::end(errors), pred);
|
|
writeStderr(it != std::end(errors) ? it->second : "<unknown>");
|
|
writeStderr(")");
|
|
}
|
|
writeStderr("\n");
|
|
fsyncNoInt(STDERR_FILENO);
|
|
abort();
|
|
}
|
|
|
|
} // namespace detail
|
|
} // namespace folly
|