summaryrefslogtreecommitdiffstats
path: root/Source/cmUVProcessChain.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2023-06-01 15:52:40 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2023-06-05 15:27:45 (GMT)
commit154fe00ca56710d6fced4ab5c51f7edb162ea991 (patch)
treed08d2ce6d426343d2599d0124e94325a955300ea /Source/cmUVProcessChain.cxx
parent17a43ee192116f82b9dae494333f5e14b4553f87 (diff)
downloadCMake-154fe00ca56710d6fced4ab5c51f7edb162ea991.zip
CMake-154fe00ca56710d6fced4ab5c51f7edb162ea991.tar.gz
CMake-154fe00ca56710d6fced4ab5c51f7edb162ea991.tar.bz2
cmUVProcessChain: Add Status::GetException() method
Diffstat (limited to 'Source/cmUVProcessChain.cxx')
-rw-r--r--Source/cmUVProcessChain.cxx248
1 files changed, 248 insertions, 0 deletions
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index c2bb11e..ed5f38b 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -1,10 +1,16 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigure.h"
+
#include "cmUVProcessChain.h"
+#include <array>
#include <cassert>
+#include <csignal>
+#include <cstdio>
#include <istream> // IWYU pragma: keep
#include <iterator>
+#include <type_traits>
#include <utility>
#include <cm/memory>
@@ -425,3 +431,245 @@ bool cmUVProcessChain::Finished() const
{
return this->Data->ProcessesCompleted >= this->Data->Processes.size();
}
+
+std::pair<cmUVProcessChain::ExceptionCode, std::string>
+cmUVProcessChain::Status::GetException() const
+{
+#ifdef _WIN32
+ if ((this->ExitStatus & 0xF0000000) == 0xC0000000) {
+ // Child terminated due to exceptional behavior.
+ switch (this->ExitStatus) {
+ case STATUS_CONTROL_C_EXIT:
+ return std::make_pair(ExceptionCode::Interrupt, "User interrupt");
+
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point exception (denormal operand)");
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ return std::make_pair(ExceptionCode::Numerical, "Divide-by-zero");
+ case STATUS_FLOAT_INEXACT_RESULT:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point exception (inexact result)");
+ case STATUS_FLOAT_INVALID_OPERATION:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Invalid floating-point operation");
+ case STATUS_FLOAT_OVERFLOW:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point overflow");
+ case STATUS_FLOAT_STACK_CHECK:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point stack check failed");
+ case STATUS_FLOAT_UNDERFLOW:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point underflow");
+# ifdef STATUS_FLOAT_MULTIPLE_FAULTS
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point exception (multiple faults)");
+# endif
+# ifdef STATUS_FLOAT_MULTIPLE_TRAPS
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point exception (multiple traps)");
+# endif
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Integer divide-by-zero");
+ case STATUS_INTEGER_OVERFLOW:
+ return std::make_pair(ExceptionCode::Numerical, "Integer overflow");
+
+ case STATUS_DATATYPE_MISALIGNMENT:
+ return std::make_pair(ExceptionCode::Fault, "Datatype misalignment");
+ case STATUS_ACCESS_VIOLATION:
+ return std::make_pair(ExceptionCode::Fault, "Access violation");
+ case STATUS_IN_PAGE_ERROR:
+ return std::make_pair(ExceptionCode::Fault, "In-page error");
+ case STATUS_INVALID_HANDLE:
+ return std::make_pair(ExceptionCode::Fault, "Invalid handle");
+ case STATUS_NONCONTINUABLE_EXCEPTION:
+ return std::make_pair(ExceptionCode::Fault,
+ "Noncontinuable exception");
+ case STATUS_INVALID_DISPOSITION:
+ return std::make_pair(ExceptionCode::Fault, "Invalid disposition");
+ case STATUS_ARRAY_BOUNDS_EXCEEDED:
+ return std::make_pair(ExceptionCode::Fault, "Array bounds exceeded");
+ case STATUS_STACK_OVERFLOW:
+ return std::make_pair(ExceptionCode::Fault, "Stack overflow");
+
+ case STATUS_ILLEGAL_INSTRUCTION:
+ return std::make_pair(ExceptionCode::Illegal, "Illegal instruction");
+ case STATUS_PRIVILEGED_INSTRUCTION:
+ return std::make_pair(ExceptionCode::Illegal,
+ "Privileged instruction");
+
+ case STATUS_NO_MEMORY:
+ default: {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "Exit code 0x%x\n",
+ static_cast<unsigned int>(this->ExitStatus));
+ return std::make_pair(ExceptionCode::Other, buf);
+ }
+ }
+ }
+ return std::make_pair(ExceptionCode::None, "");
+#else
+ if (this->TermSignal) {
+ switch (this->TermSignal) {
+# ifdef SIGSEGV
+ case SIGSEGV:
+ return std::make_pair(ExceptionCode::Fault, "Segmentation fault");
+# endif
+# ifdef SIGBUS
+# if !defined(SIGSEGV) || SIGBUS != SIGSEGV
+ case SIGBUS:
+ return std::make_pair(ExceptionCode::Fault, "Bus error");
+# endif
+# endif
+# ifdef SIGFPE
+ case SIGFPE:
+ return std::make_pair(ExceptionCode::Numerical,
+ "Floating-point exception");
+# endif
+# ifdef SIGILL
+ case SIGILL:
+ return std::make_pair(ExceptionCode::Illegal, "Illegal instruction");
+# endif
+# ifdef SIGINT
+ case SIGINT:
+ return std::make_pair(ExceptionCode::Interrupt, "User interrupt");
+# endif
+# ifdef SIGABRT
+ case SIGABRT:
+ return std::make_pair(ExceptionCode::Other, "Subprocess aborted");
+# endif
+# ifdef SIGKILL
+ case SIGKILL:
+ return std::make_pair(ExceptionCode::Other, "Subprocess killed");
+# endif
+# ifdef SIGTERM
+ case SIGTERM:
+ return std::make_pair(ExceptionCode::Other, "Subprocess terminated");
+# endif
+# ifdef SIGHUP
+ case SIGHUP:
+ return std::make_pair(ExceptionCode::Other, "SIGHUP");
+# endif
+# ifdef SIGQUIT
+ case SIGQUIT:
+ return std::make_pair(ExceptionCode::Other, "SIGQUIT");
+# endif
+# ifdef SIGTRAP
+ case SIGTRAP:
+ return std::make_pair(ExceptionCode::Other, "SIGTRAP");
+# endif
+# ifdef SIGIOT
+# if !defined(SIGABRT) || SIGIOT != SIGABRT
+ case SIGIOT:
+ return std::make_pair(ExceptionCode::Other, "SIGIOT");
+# endif
+# endif
+# ifdef SIGUSR1
+ case SIGUSR1:
+ return std::make_pair(ExceptionCode::Other, "SIGUSR1");
+# endif
+# ifdef SIGUSR2
+ case SIGUSR2:
+ return std::make_pair(ExceptionCode::Other, "SIGUSR2");
+# endif
+# ifdef SIGPIPE
+ case SIGPIPE:
+ return std::make_pair(ExceptionCode::Other, "SIGPIPE");
+# endif
+# ifdef SIGALRM
+ case SIGALRM:
+ return std::make_pair(ExceptionCode::Other, "SIGALRM");
+# endif
+# ifdef SIGSTKFLT
+ case SIGSTKFLT:
+ return std::make_pair(ExceptionCode::Other, "SIGSTKFLT");
+# endif
+# ifdef SIGCHLD
+ case SIGCHLD:
+ return std::make_pair(ExceptionCode::Other, "SIGCHLD");
+# elif defined(SIGCLD)
+ case SIGCLD:
+ return std::make_pair(ExceptionCode::Other, "SIGCLD");
+# endif
+# ifdef SIGCONT
+ case SIGCONT:
+ return std::make_pair(ExceptionCode::Other, "SIGCONT");
+# endif
+# ifdef SIGSTOP
+ case SIGSTOP:
+ return std::make_pair(ExceptionCode::Other, "SIGSTOP");
+# endif
+# ifdef SIGTSTP
+ case SIGTSTP:
+ return std::make_pair(ExceptionCode::Other, "SIGTSTP");
+# endif
+# ifdef SIGTTIN
+ case SIGTTIN:
+ return std::make_pair(ExceptionCode::Other, "SIGTTIN");
+# endif
+# ifdef SIGTTOU
+ case SIGTTOU:
+ return std::make_pair(ExceptionCode::Other, "SIGTTOU");
+# endif
+# ifdef SIGURG
+ case SIGURG:
+ return std::make_pair(ExceptionCode::Other, "SIGURG");
+# endif
+# ifdef SIGXCPU
+ case SIGXCPU:
+ return std::make_pair(ExceptionCode::Other, "SIGXCPU");
+# endif
+# ifdef SIGXFSZ
+ case SIGXFSZ:
+ return std::make_pair(ExceptionCode::Other, "SIGXFSZ");
+# endif
+# ifdef SIGVTALRM
+ case SIGVTALRM:
+ return std::make_pair(ExceptionCode::Other, "SIGVTALRM");
+# endif
+# ifdef SIGPROF
+ case SIGPROF:
+ return std::make_pair(ExceptionCode::Other, "SIGPROF");
+# endif
+# ifdef SIGWINCH
+ case SIGWINCH:
+ return std::make_pair(ExceptionCode::Other, "SIGWINCH");
+# endif
+# ifdef SIGPOLL
+ case SIGPOLL:
+ return std::make_pair(ExceptionCode::Other, "SIGPOLL");
+# endif
+# ifdef SIGIO
+# if !defined(SIGPOLL) || SIGIO != SIGPOLL
+ case SIGIO:
+ return std::make_pair(ExceptionCode::Other, "SIGIO");
+# endif
+# endif
+# ifdef SIGPWR
+ case SIGPWR:
+ return std::make_pair(ExceptionCode::Other, "SIGPWR");
+# endif
+# ifdef SIGSYS
+ case SIGSYS:
+ return std::make_pair(ExceptionCode::Other, "SIGSYS");
+# endif
+# ifdef SIGUNUSED
+# if !defined(SIGSYS) || SIGUNUSED != SIGSYS
+ case SIGUNUSED:
+ return std::make_pair(ExceptionCode::Other, "SIGUNUSED");
+# endif
+# endif
+ default: {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "Signal %d", this->TermSignal);
+ return std::make_pair(ExceptionCode::Other, buf);
+ }
+ }
+ }
+ return std::make_pair(ExceptionCode::None, "");
+#endif
+}