1//===- Unix/Process.cpp - Unix Process Implementation --------- -*- 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-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file provides the generic Unix implementation of the Process class. 10// 11//===----------------------------------------------------------------------===// 12 13#include "Unix.h" 14#include "llvm/ADT/Hashing.h" 15#include "llvm/ADT/StringRef.h" 16#include "llvm/Config/config.h" 17#include <mutex> 18#include <optional> 19#if HAVE_FCNTL_H 20#include <fcntl.h> 21#endif 22#ifdef HAVE_SYS_TIME_H 23#include <sys/time.h> 24#endif 25#ifdef HAVE_SYS_RESOURCE_H 26#include <sys/resource.h> 27#endif 28#ifdef HAVE_SYS_STAT_H 29#include <sys/stat.h> 30#endif 31#if HAVE_SIGNAL_H 32#include <signal.h> 33#endif 34#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2) 35#include <malloc.h> 36#endif 37#if defined(HAVE_MALLCTL) 38#include <malloc_np.h> 39#endif 40#ifdef HAVE_MALLOC_MALLOC_H 41#include <malloc/malloc.h> 42#endif 43#ifdef HAVE_SYS_IOCTL_H 44#include <sys/ioctl.h> 45#endif 46#ifdef HAVE_TERMIOS_H 47#include <termios.h> 48#endif 49 50//===----------------------------------------------------------------------===// 51//=== WARNING: Implementation here must contain only generic UNIX code that 52//=== is guaranteed to work on *all* UNIX variants. 53//===----------------------------------------------------------------------===// 54 55using namespace llvm; 56using namespace sys; 57 58static std::pair<std::chrono::microseconds, std::chrono::microseconds> 59getRUsageTimes() { 60#if defined(HAVE_GETRUSAGE) 61 struct rusage RU; 62 ::getrusage(RUSAGE_SELF, &RU); 63 return {toDuration(RU.ru_utime), toDuration(RU.ru_stime)}; 64#else 65#ifndef __MVS__ // Exclude for MVS in case -pedantic is used 66#warning Cannot get usage times on this platform 67#endif 68 return {std::chrono::microseconds::zero(), std::chrono::microseconds::zero()}; 69#endif 70} 71 72Process::Pid Process::getProcessId() { 73 static_assert(sizeof(Pid) >= sizeof(pid_t), 74 "Process::Pid should be big enough to store pid_t"); 75 return Pid(::getpid()); 76} 77 78// On Cygwin, getpagesize() returns 64k(AllocationGranularity) and 79// offset in mmap(3) should be aligned to the AllocationGranularity. 80Expected<unsigned> Process::getPageSize() { 81#if defined(HAVE_GETPAGESIZE) 82 static const int page_size = ::getpagesize(); 83#elif defined(HAVE_SYSCONF) 84 static long page_size = ::sysconf(_SC_PAGE_SIZE); 85#else 86#error Cannot get the page size on this machine 87#endif 88 if (page_size == -1) 89 return errorCodeToError(errnoAsErrorCode()); 90 91 return static_cast<unsigned>(page_size); 92} 93 94size_t Process::GetMallocUsage() { 95#if defined(HAVE_MALLINFO2) 96 struct mallinfo2 mi; 97 mi = ::mallinfo2(); 98 return mi.uordblks; 99#elif defined(HAVE_MALLINFO) 100 struct mallinfo mi; 101 mi = ::mallinfo(); 102 return mi.uordblks; 103#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) 104 malloc_statistics_t Stats; 105 malloc_zone_statistics(malloc_default_zone(), &Stats); 106 return Stats.size_in_use; // darwin 107#elif defined(HAVE_MALLCTL) 108 size_t alloc, sz; 109 sz = sizeof(size_t); 110 if (mallctl("stats.allocated", &alloc, &sz, NULL, 0) == 0) 111 return alloc; 112 return 0; 113#elif defined(HAVE_SBRK) 114 // Note this is only an approximation and more closely resembles 115 // the value returned by mallinfo in the arena field. 116 static char *StartOfMemory = reinterpret_cast<char *>(::sbrk(0)); 117 char *EndOfMemory = (char *)sbrk(0); 118 if (EndOfMemory != ((char *)-1) && StartOfMemory != ((char *)-1)) 119 return EndOfMemory - StartOfMemory; 120 return 0; 121#else 122#ifndef __MVS__ // Exclude for MVS in case -pedantic is used 123#warning Cannot get malloc info on this platform 124#endif 125 return 0; 126#endif 127} 128 129void Process::GetTimeUsage(TimePoint<> &elapsed, 130 std::chrono::nanoseconds &user_time, 131 std::chrono::nanoseconds &sys_time) { 132 elapsed = std::chrono::system_clock::now(); 133 std::tie(user_time, sys_time) = getRUsageTimes(); 134} 135 136#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__) 137#include <mach/mach.h> 138#endif 139 140// Some LLVM programs such as bugpoint produce core files as a normal part of 141// their operation. To prevent the disk from filling up, this function 142// does what's necessary to prevent their generation. 143void Process::PreventCoreFiles() { 144#if HAVE_SETRLIMIT 145 struct rlimit rlim; 146 getrlimit(RLIMIT_CORE, &rlim); 147#ifdef __linux__ 148 // On Linux, if the kernel.core_pattern sysctl starts with a '|' (i.e. it 149 // is being piped to a coredump handler such as systemd-coredumpd), the 150 // kernel ignores RLIMIT_CORE (since we aren't creating a file in the file 151 // system) except for the magic value of 1, which disables coredumps when 152 // piping. 1 byte is too small for any kind of valid core dump, so it 153 // also disables coredumps if kernel.core_pattern creates files directly. 154 // While most piped coredump handlers do respect the crashing processes' 155 // RLIMIT_CORE, this is notable not the case for Debian's systemd-coredump 156 // due to a local patch that changes sysctl.d/50-coredump.conf to ignore 157 // the specified limit and instead use RLIM_INFINITY. 158 // 159 // The alternative to using RLIMIT_CORE=1 would be to use prctl() with the 160 // PR_SET_DUMPABLE flag, however that also prevents ptrace(), so makes it 161 // impossible to attach a debugger. 162 rlim.rlim_cur = std::min<rlim_t>(1, rlim.rlim_max); 163#else 164 rlim.rlim_cur = 0; 165#endif 166 setrlimit(RLIMIT_CORE, &rlim); 167#endif 168 169#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__) 170 // Disable crash reporting on Mac OS X 10.0-10.4 171 172 // get information about the original set of exception ports for the task 173 mach_msg_type_number_t Count = 0; 174 exception_mask_t OriginalMasks[EXC_TYPES_COUNT]; 175 exception_port_t OriginalPorts[EXC_TYPES_COUNT]; 176 exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT]; 177 thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT]; 178 kern_return_t err = task_get_exception_ports( 179 mach_task_self(), EXC_MASK_ALL, OriginalMasks, &Count, OriginalPorts, 180 OriginalBehaviors, OriginalFlavors); 181 if (err == KERN_SUCCESS) { 182 // replace each with MACH_PORT_NULL. 183 for (unsigned i = 0; i != Count; ++i) 184 task_set_exception_ports(mach_task_self(), OriginalMasks[i], 185 MACH_PORT_NULL, OriginalBehaviors[i], 186 OriginalFlavors[i]); 187 } 188 189 // Disable crash reporting on Mac OS X 10.5 190 signal(SIGABRT, _exit); 191 signal(SIGILL, _exit); 192 signal(SIGFPE, _exit); 193 signal(SIGSEGV, _exit); 194 signal(SIGBUS, _exit); 195#endif 196 197 coreFilesPrevented = true; 198} 199 200std::optional<std::string> Process::GetEnv(StringRef Name) { 201 std::string NameStr = Name.str(); 202 const char *Val = ::getenv(NameStr.c_str()); 203 if (!Val) 204 return std::nullopt; 205 return std::string(Val); 206} 207 208namespace { 209class FDCloser { 210public: 211 FDCloser(int &FD) : FD(FD), KeepOpen(false) {} 212 void keepOpen() { KeepOpen = true; } 213 ~FDCloser() { 214 if (!KeepOpen && FD >= 0) 215 ::close(FD); 216 } 217 218private: 219 FDCloser(const FDCloser &) = delete; 220 void operator=(const FDCloser &) = delete; 221 222 int &FD; 223 bool KeepOpen; 224}; 225} // namespace 226 227std::error_code Process::FixupStandardFileDescriptors() { 228 int NullFD = -1; 229 FDCloser FDC(NullFD); 230 const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}; 231 for (int StandardFD : StandardFDs) { 232 struct stat st; 233 errno = 0; 234 if (RetryAfterSignal(-1, ::fstat, StandardFD, &st) < 0) { 235 assert(errno && "expected errno to be set if fstat failed!"); 236 // fstat should return EBADF if the file descriptor is closed. 237 if (errno != EBADF) 238 return errnoAsErrorCode(); 239 } 240 // if fstat succeeds, move on to the next FD. 241 if (!errno) 242 continue; 243 assert(errno == EBADF && "expected errno to have EBADF at this point!"); 244 245 if (NullFD < 0) { 246 // Call ::open in a lambda to avoid overload resolution in 247 // RetryAfterSignal when open is overloaded, such as in Bionic. 248 auto Open = [&]() { return ::open("/dev/null", O_RDWR); }; 249 if ((NullFD = RetryAfterSignal(-1, Open)) < 0) 250 return errnoAsErrorCode(); 251 } 252 253 if (NullFD == StandardFD) 254 FDC.keepOpen(); 255 else if (dup2(NullFD, StandardFD) < 0) 256 return errnoAsErrorCode(); 257 } 258 return std::error_code(); 259} 260 261// Close a file descriptor while being mindful of EINTR. 262// 263// On Unix systems closing a file descriptor usually starts with removing it 264// from the fd table (or an equivalent structure). This means any error 265// generated past that point will still result in the entry being cleared. 266// 267// Make sure to not bubble up EINTR as there is nothing to do in that case. 268// XXX what about other errors? 269#if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || \ 270 defined(__NetBSD__) || defined(__OpenBSD__) 271std::error_code Process::SafelyCloseFileDescriptor(int FD) { 272 int EC = 0; 273 if (::close(FD) < 0) { 274 if (errno != EINTR) 275 EC = errno; 276 } 277 return std::error_code(EC, std::generic_category()); 278} 279#else 280std::error_code Process::SafelyCloseFileDescriptor(int FD) { 281 // Create a signal set filled with *all* signals. 282 sigset_t FullSet, SavedSet; 283 if (sigfillset(&FullSet) < 0 || sigfillset(&SavedSet) < 0) 284 return errnoAsErrorCode(); 285 286 // Atomically swap our current signal mask with a full mask. 287#if LLVM_ENABLE_THREADS 288 if (int EC = pthread_sigmask(SIG_SETMASK, &FullSet, &SavedSet)) 289 return std::error_code(EC, std::generic_category()); 290#else 291 if (sigprocmask(SIG_SETMASK, &FullSet, &SavedSet) < 0) 292 return errnoAsErrorCode(); 293#endif 294 // Attempt to close the file descriptor. 295 // We need to save the error, if one occurs, because our subsequent call to 296 // pthread_sigmask might tamper with errno. 297 int ErrnoFromClose = 0; 298 if (::close(FD) < 0) 299 ErrnoFromClose = errno; 300 // Restore the signal mask back to what we saved earlier. 301 int EC = 0; 302#if LLVM_ENABLE_THREADS 303 EC = pthread_sigmask(SIG_SETMASK, &SavedSet, nullptr); 304#else 305 if (sigprocmask(SIG_SETMASK, &SavedSet, nullptr) < 0) 306 EC = errno; 307#endif 308 // The error code from close takes precedence over the one from 309 // pthread_sigmask. 310 if (ErrnoFromClose) 311 return std::error_code(ErrnoFromClose, std::generic_category()); 312 return std::error_code(EC, std::generic_category()); 313} 314#endif 315 316bool Process::StandardInIsUserInput() { 317 return FileDescriptorIsDisplayed(STDIN_FILENO); 318} 319 320bool Process::StandardOutIsDisplayed() { 321 return FileDescriptorIsDisplayed(STDOUT_FILENO); 322} 323 324bool Process::StandardErrIsDisplayed() { 325 return FileDescriptorIsDisplayed(STDERR_FILENO); 326} 327 328bool Process::FileDescriptorIsDisplayed(int fd) { 329#if HAVE_ISATTY 330 return isatty(fd); 331#else 332 // If we don't have isatty, just return false. 333 return false; 334#endif 335} 336 337static unsigned getColumns() { 338 // If COLUMNS is defined in the environment, wrap to that many columns. 339 if (const char *ColumnsStr = std::getenv("COLUMNS")) { 340 int Columns = std::atoi(ColumnsStr); 341 if (Columns > 0) 342 return Columns; 343 } 344 345 // We used to call ioctl TIOCGWINSZ to determine the width. It is considered 346 // unuseful. 347 return 0; 348} 349 350unsigned Process::StandardOutColumns() { 351 if (!StandardOutIsDisplayed()) 352 return 0; 353 354 return getColumns(); 355} 356 357unsigned Process::StandardErrColumns() { 358 if (!StandardErrIsDisplayed()) 359 return 0; 360 361 return getColumns(); 362} 363 364static bool terminalHasColors() { 365 // Check if the current terminal is one of terminals that are known to support 366 // ANSI color escape codes. 367 if (const char *TermStr = std::getenv("TERM")) { 368 return StringSwitch<bool>(TermStr) 369 .Case("ansi", true) 370 .Case("cygwin", true) 371 .Case("linux", true) 372 .StartsWith("screen", true) 373 .StartsWith("xterm", true) 374 .StartsWith("vt100", true) 375 .StartsWith("rxvt", true) 376 .EndsWith("color", true) 377 .Default(false); 378 } 379 380 return false; 381} 382 383bool Process::FileDescriptorHasColors(int fd) { 384 // A file descriptor has colors if it is displayed and the terminal has 385 // colors. 386 return FileDescriptorIsDisplayed(fd) && terminalHasColors(); 387} 388 389bool Process::StandardOutHasColors() { 390 return FileDescriptorHasColors(STDOUT_FILENO); 391} 392 393bool Process::StandardErrHasColors() { 394 return FileDescriptorHasColors(STDERR_FILENO); 395} 396 397void Process::UseANSIEscapeCodes(bool /*enable*/) { 398 // No effect. 399} 400 401bool Process::ColorNeedsFlush() { 402 // No, we use ANSI escape sequences. 403 return false; 404} 405 406const char *Process::OutputColor(char code, bool bold, bool bg) { 407 return colorcodes[bg ? 1 : 0][bold ? 1 : 0][code & 15]; 408} 409 410const char *Process::OutputBold(bool bg) { return "\033[1m"; } 411 412const char *Process::OutputReverse() { return "\033[7m"; } 413 414const char *Process::ResetColor() { return "\033[0m"; } 415 416#if !HAVE_DECL_ARC4RANDOM 417static unsigned GetRandomNumberSeed() { 418 // Attempt to get the initial seed from /dev/urandom, if possible. 419 int urandomFD = open("/dev/urandom", O_RDONLY); 420 421 if (urandomFD != -1) { 422 unsigned seed; 423 // Don't use a buffered read to avoid reading more data 424 // from /dev/urandom than we need. 425 int count = read(urandomFD, (void *)&seed, sizeof(seed)); 426 427 close(urandomFD); 428 429 // Return the seed if the read was successful. 430 if (count == sizeof(seed)) 431 return seed; 432 } 433 434 // Otherwise, swizzle the current time and the process ID to form a reasonable 435 // seed. 436 const auto Now = std::chrono::high_resolution_clock::now(); 437 return hash_combine(Now.time_since_epoch().count(), ::getpid()); 438} 439#endif 440 441unsigned llvm::sys::Process::GetRandomNumber() { 442#if HAVE_DECL_ARC4RANDOM 443 return arc4random(); 444#else 445 static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0); 446 (void)x; 447 return ::rand(); 448#endif 449} 450 451[[noreturn]] void Process::ExitNoCleanup(int RetCode) { _Exit(RetCode); } 452