Loading...
--- Libc/Libc-1725.40.4/os/debug_private.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <mach/mach_time.h>
-#include <os/alloc_once_private.h>
-#include <os/assumes.h>
-#include <os/debug_private.h>
-#include <_simple.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <os/log_simple_private.h>
-#include <ptrauth.h>
-
-struct os_debug_log_globals_s {
- uint64_t start;
- os_redirect_t redirect;
- int logfd;
- bool prepend_timestamp : 1;
- bool errors_only : 1;
-};
-
-// If user picked a filename, use it and only it.
-// Otherwise, first try /var/tmp, then $TMPDIR, then give up.
-static inline
-int
-_os_debug_log_open_file(const char *suggestion)
-{
- if (suggestion) {
- return open(suggestion, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW |
- O_EXCL | O_CLOEXEC, 0644);
- }
-
- int fd;
- char filename[PATH_MAX];
- char path[PATH_MAX];
-
- snprintf(filename, sizeof(filename), "os_debug_log.%s.%d.log", getprogname(),
- getpid());
-
- strlcpy(path, "/var/tmp/", sizeof(path));
- if (access(path, W_OK) == 0) {
- strlcat(path, filename, sizeof(path));
- fd = open(path, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW | O_EXCL |
- O_CLOEXEC, 0644);
- if (fd >= 0) {
- return fd;
- }
- }
-
- const char *tmpdir = getenv("TMPDIR");
- if (tmpdir) {
- strlcpy(path, tmpdir, sizeof(path));
- if (access(path, W_OK) == 0) {
- strlcat(path, filename, sizeof(path));
- fd = open(path, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW |
- O_EXCL | O_CLOEXEC, 0644);
- if (fd >= 0) {
- return fd;
- }
- }
- }
-
- return -1;
-}
-
-__attribute__((weak))
-bool
-_os_debug_log_redirect_func(const char *message)
-{
- return false;
-}
-
-extern char __text_start __asm__("section$start$__TEXT$__text");
-extern char __text_end __asm__("section$end$__TEXT$__text");
-
-static
-void
-_os_debug_log_init(void *globals)
-{
- struct os_debug_log_globals_s *g = globals;
- os_redirect_t redirect = &_os_debug_log_redirect_func;
- char *addr = (char *)ptrauth_strip(redirect, ptrauth_key_function_pointer);
-
- g->errors_only = false;
-
- /* check if our weak _os_debug_log_redirect_func was overriden */
- if (addr < &__text_start || &__text_end <= addr) {
- g->redirect = redirect;
- }
-
- // This is a bit of a hack. LIBDISPATCH_LOG is part of dispatch's API.
- // But now all dispatch logging goes through os_debug_log. So we have to
- // recognize this env var here in Libc.
- // rdar://problem/11685359 tracks deprecating LIBDISPATCH_LOG from dispatch.
- char *e = getenv("LIBDISPATCH_LOG");
- if (!e) {
- e = getenv("OS_DEBUG_LOG");
- }
-
- // Default log destination
- if (!e || strcmp(e, "YES") == 0) {
-#if DEBUG
- e = "file";
-#else
- e = "syslog";
-#endif
- }
-
- if (strcmp(e, "NO") == 0) {
- g->logfd = -1;
- g->errors_only = true;
- } else if (strcmp(e, "syslog") == 0) {
- g->logfd = -1;
- } else if (strcmp(e, "stderr") == 0) {
- g->logfd = STDERR_FILENO;
- } else if (strcmp(e, "stdout") == 0) {
- g->logfd = STDOUT_FILENO;
- } else if (strcmp(e, "file") == 0) {
- g->logfd = _os_debug_log_open_file(NULL);
- if (g->logfd == -1) {
- g->errors_only = true;
- }
- } else {
- g->logfd = _os_debug_log_open_file(e);
- if (g->logfd == -1) {
- g->errors_only = true;
- }
- }
-
- // From now on, g->logfd == -1 means syslog; anything >= 0 is the
- // fd to use. Remember that file descriptor 0 is a perfectly valid
- // value for open() to return if you closed (or never had) stdin.
-
- // Timestamp every log message if logging directly to file and no
- // redirector is set up.
- if (g->logfd >= 0 && !g->redirect) {
- g->prepend_timestamp = true;
-
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- g->start = mach_absolute_time();
-
- dprintf(g->logfd,
- "=== os_debug_log log file opened for %s[%u] at %ld.%06u",
- getprogname(), getpid(),
- tv.tv_sec, tv.tv_usec);
- if (g->prepend_timestamp) {
- mach_timebase_info_data_t tbi;
- if (mach_timebase_info(&tbi) == 0) {
- dprintf(g->logfd, " [ns=ticks*%u/%u]",
- tbi.numer, tbi.denom);
- }
- }
- dprintf(g->logfd, " ===\n");
- }
-}
-
-#ifndef OS_ALLOC_ONCE_KEY_OS_DEBUG_LOG
-#define OS_ALLOC_ONCE_KEY_OS_DEBUG_LOG OS_ALLOC_ONCE_KEY_OS_TRACE
-#endif
-
-static inline OS_CONST
-struct os_debug_log_globals_s *
-os_debug_log_globals(void)
-{
- return (struct os_debug_log_globals_s *)
- os_alloc_once(OS_ALLOC_ONCE_KEY_OS_DEBUG_LOG,
- sizeof(struct os_debug_log_globals_s),
- _os_debug_log_init);
-}
-
-static __attribute__((always_inline))
-uint64_t
-_os_debug_log_ticks_since_start(void)
-{
- return mach_absolute_time() - os_debug_log_globals()->start;
-}
-
-// False on error writing to file
-static inline
-bool
-_os_debug_log_write_fd(int level __attribute__((__unused__)),
- char *str, int fd)
-{
- size_t len = strlen(str);
-
- str[len++] = '\n'; // overwrite null - don't use str*() anymore
-
- ssize_t rc, wlen = 0;
- do {
- rc = write(fd, &str[wlen], len - wlen);
- if (os_slowpath(rc == -1)) {
- if(errno == EINTR) {
- rc = 0;
- } else {
- return false;
- }
- }
- wlen += rc;
- } while (wlen < len);
-
- return true;
-}
-
-static __attribute__((__noinline__))
-void
-_os_debug_log_write_error(void)
-{
- char err_str[256];
- const char *pfx = "os_debug_log() :";
- size_t pfxlen = strlen(pfx);
-
- strlcpy(err_str, pfx, sizeof(err_str));
- strerror_r(errno, err_str+pfxlen, sizeof(err_str)-pfxlen);
- _simple_asl_log(LOG_ERR, "com.apple.os_debug_log", err_str);
-}
-
-static inline
-void
-_os_debug_log_write(int level, char *str, uint64_t offset)
-{
- int fd = os_debug_log_globals()->logfd;
- os_redirect_t rdr = os_debug_log_globals()->redirect;
- // true = redirect has fully handled, don't log
- if (os_slowpath(rdr) && os_fastpath(rdr(str))) {
- return;
- }
- if (os_slowpath(fd >= 0)) {
- if (os_fastpath(_os_debug_log_write_fd(level, str, fd))) {
- return;
- } else {
- _os_debug_log_write_error();
- os_debug_log_globals()->logfd = -1;
- // Don't return, fall out to syslog().
- }
- }
-#if TARGET_OS_SIMULATOR
- // Old hosts don't have libplatform support for os_log_simple, so we need
- // to use legacy shims on simulator
- _simple_asl_log(level, "com.apple.os_debug_log", str);
-#else // TARGET_OS_SIMULATOR
- _os_log_simple_offset(os_log_simple_type_from_asl(level),
- "com.apple.os_debug_log", offset, str);
-#endif // TARGET_OS_SIMULATOR
-}
-
-static __attribute__((always_inline))
-void
-_os_debug_logv(int level, const char *msg, va_list ap)
-{
- if (os_slowpath((bool)os_debug_log_globals()->errors_only) && level > LOG_ERR) {
- // more important = lower integer
- return;
- }
- char *buf, *freebuf;
- size_t len;
-
- len = vasprintf(&buf, msg, ap);
- if (!buf) {
- return;
- }
- freebuf = buf;
-
- // The os_debug_log macros prepend many spaces to the format string.
- // Overwrite them with a timestamp, *or* skip them.
- const size_t pfxlen = strlen(_OS_DEBUG_LOG_PREFIX);
- const size_t timelen = 16;
- __OS_COMPILETIME_ASSERT__(pfxlen >= timelen);
-
- if (os_fastpath(len > pfxlen)) {
- if (os_slowpath((bool)os_debug_log_globals()->prepend_timestamp)) {
- char tmp = buf[timelen];
- snprintf(buf, timelen + 1, "%16llu", _os_debug_log_ticks_since_start());
- buf[timelen] = tmp; // snprintf's null
- } else {
- buf += pfxlen;
- }
- }
-
- _os_debug_log_write(level, buf, (uint64_t)(uintptr_t)__builtin_return_address(0));
- free(freebuf);
-}
-
-void
-_os_debug_log_error_str(char *msg)
-{
- _os_debug_log_write(LOG_ERR, msg, (uint64_t)(uintptr_t)__builtin_return_address(0));
-}
-
-void
-_os_debug_log_error_offset(char *msg, uint64_t offset)
-{
- _os_debug_log_write(LOG_ERR, msg, offset);
-}
-
-OS_FORMAT_PRINTF(1, 2)
-void
-_os_debug_log(const char *msg, ...)
-{
- va_list ap;
- va_start(ap, msg);
- _os_debug_logv(LOG_DEBUG, msg, ap);
- va_end(ap);
-}