mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-26 04:20:30 +00:00
Make some systemic improvements
- add vdso dump utility - tests now log stack usage - rename g_ftrace to __ftrace - make internal spinlocks go faster - add conformant c11 atomics library - function tracing now logs stack usage - make function call tracing thread safe - add -X unsecure (no ssl) mode to redbean - munmap() has more consistent behavior now - pacify fsync() calls on python unit tests - make --strace flag work better in redbean - start minimizing and documenting compiler flags
This commit is contained in:
parent
c6bbca55e9
commit
9208c83f7a
141 changed files with 1948 additions and 1411 deletions
|
@ -21,6 +21,7 @@
|
|||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -86,6 +87,11 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (IsLinux() && !__is_linux_2_6_23()) {
|
||||
// we need the `addr2line -a` option
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
argv[i++] = "addr2line";
|
||||
|
@ -177,12 +183,12 @@ static int PrintBacktrace(int fd, const struct StackFrame *bp) {
|
|||
void ShowBacktrace(int fd, const struct StackFrame *bp) {
|
||||
#ifdef __FNO_OMIT_FRAME_POINTER__
|
||||
/* asan runtime depends on this function */
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED);
|
||||
__atomic_fetch_sub(&__strace, 1, __ATOMIC_RELAXED);
|
||||
--__ftrace;
|
||||
--__strace;
|
||||
if (!bp) bp = __builtin_frame_address(0);
|
||||
PrintBacktrace(fd, bp);
|
||||
__atomic_fetch_add(&__strace, 1, __ATOMIC_RELAXED);
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED);
|
||||
++__strace;
|
||||
++__ftrace;
|
||||
#else
|
||||
(fprintf)(stderr, "ShowBacktrace() needs these flags to show C backtrace:\n"
|
||||
"\t-D__FNO_OMIT_FRAME_POINTER__\n"
|
||||
|
|
|
@ -45,8 +45,8 @@ relegated void __check_fail(const char *suffix, const char *opstr,
|
|||
size_t i;
|
||||
va_list va;
|
||||
char hostname[32];
|
||||
__strace = 0;
|
||||
g_ftrace = 0;
|
||||
--__strace;
|
||||
--__ftrace;
|
||||
e = errno;
|
||||
__start_fatal(file, line);
|
||||
__stpcpy(hostname, "unknown");
|
||||
|
|
|
@ -78,15 +78,15 @@ extern unsigned __log_level; /* log level for runtime check */
|
|||
// log a message with the specified log level (not checking if LOGGABLE)
|
||||
#define LOGF(LEVEL, FMT, ...) \
|
||||
do { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(LEVEL, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} while (0)
|
||||
|
||||
// die with an error message without backtrace and debugger invocation
|
||||
#define DIEF(FMT, ...) \
|
||||
do { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
if (weaken(__die)) weaken(__die)(); \
|
||||
exit(1); \
|
||||
|
@ -95,7 +95,7 @@ extern unsigned __log_level; /* log level for runtime check */
|
|||
|
||||
#define FATALF(FMT, ...) \
|
||||
do { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
ffatalf(kLogFatal, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
unreachable; \
|
||||
} while (0)
|
||||
|
@ -103,78 +103,78 @@ extern unsigned __log_level; /* log level for runtime check */
|
|||
#define ERRORF(FMT, ...) \
|
||||
do { \
|
||||
if (LOGGABLE(kLogError)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WARNF(FMT, ...) \
|
||||
do { \
|
||||
if (LOGGABLE(kLogWarn)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define INFOF(FMT, ...) \
|
||||
do { \
|
||||
if (LOGGABLE(kLogInfo)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define VERBOSEF(FMT, ...) \
|
||||
do { \
|
||||
if (LOGGABLE(kLogVerbose)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DEBUGF(FMT, ...) \
|
||||
do { \
|
||||
if (UNLIKELY(LOGGABLE(kLogDebug))) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define NOISEF(FMT, ...) \
|
||||
do { \
|
||||
if (UNLIKELY(LOGGABLE(kLogNoise))) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
fnoisef(kLogNoise, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FLOGF(F, FMT, ...) \
|
||||
do { \
|
||||
if (LOGGABLE(kLogInfo)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FWARNF(F, FMT, ...) \
|
||||
do { \
|
||||
if (LOGGABLE(kLogWarn)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FFATALF(F, FMT, ...) \
|
||||
do { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
ffatalf(kLogFatal, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
||||
unreachable; \
|
||||
} while (0)
|
||||
|
@ -182,18 +182,18 @@ extern unsigned __log_level; /* log level for runtime check */
|
|||
#define FDEBUGF(F, FMT, ...) \
|
||||
do { \
|
||||
if (UNLIKELY(LOGGABLE(kLogDebug))) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FNOISEF(F, FMT, ...) \
|
||||
do { \
|
||||
if (UNLIKELY(LOGGABLE(kLogNoise))) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
fnoisef(kLogNoise, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -206,25 +206,25 @@ extern unsigned __log_level; /* log level for runtime check */
|
|||
int e = errno; \
|
||||
autotype(FORM) Ax = (FORM); \
|
||||
if (UNLIKELY(Ax == (typeof(Ax))(-1)) && LOGGABLE(kLogWarn)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
--__ftrace; \
|
||||
__logerrno(__FILE__, __LINE__, #FORM); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
++__ftrace; \
|
||||
errno = e; \
|
||||
} \
|
||||
Ax; \
|
||||
})
|
||||
|
||||
#define LOGIFNULL(FORM) \
|
||||
({ \
|
||||
int e = errno; \
|
||||
autotype(FORM) Ax = (FORM); \
|
||||
if (Ax == NULL && LOGGABLE(kLogWarn)) { \
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
__logerrno(__FILE__, __LINE__, #FORM); \
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED); \
|
||||
errno = e; \
|
||||
} \
|
||||
Ax; \
|
||||
#define LOGIFNULL(FORM) \
|
||||
({ \
|
||||
int e = errno; \
|
||||
autotype(FORM) Ax = (FORM); \
|
||||
if (Ax == NULL && LOGGABLE(kLogWarn)) { \
|
||||
--__ftrace; \
|
||||
__logerrno(__FILE__, __LINE__, #FORM); \
|
||||
++__ftrace; \
|
||||
errno = e; \
|
||||
} \
|
||||
Ax; \
|
||||
})
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
|
|
|
@ -75,7 +75,6 @@ o/$(MODE)/libc/log/backtrace3.o \
|
|||
o/$(MODE)/libc/log/checkaligned.o \
|
||||
o/$(MODE)/libc/log/checkfail.o \
|
||||
o/$(MODE)/libc/log/checkfail_ndebug.o \
|
||||
o/$(MODE)/libc/log/getsymboltable.o \
|
||||
o/$(MODE)/libc/log/restoretty.o \
|
||||
o/$(MODE)/libc/log/oncrash.o \
|
||||
o/$(MODE)/libc/log/onkill.o \
|
||||
|
|
|
@ -206,8 +206,9 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
|
|||
" %m\n"
|
||||
" %s %s %s %s\n",
|
||||
!__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig,
|
||||
(ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) &&
|
||||
ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE))
|
||||
(ctx &&
|
||||
(ctx->uc_mcontext.rsp >= (intptr_t)GetStaticStackAddr(0) &&
|
||||
ctx->uc_mcontext.rsp <= (intptr_t)GetStaticStackAddr(0) + PAGESIZE))
|
||||
? "Stack Overflow"
|
||||
: GetSiCodeName(sig, si->si_code),
|
||||
host, getpid(), gettid(), program_invocation_name, names.sysname,
|
||||
|
@ -278,8 +279,8 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
|||
int gdbpid, err;
|
||||
static bool noreentry, notpossible;
|
||||
STRACE("__oncrash rip %x", ctx->uc_mcontext.rip);
|
||||
__atomic_fetch_sub(&g_ftrace, 1, __ATOMIC_RELAXED);
|
||||
__atomic_fetch_sub(&__strace, 1, __ATOMIC_RELAXED);
|
||||
--__ftrace;
|
||||
--__strace;
|
||||
if (_lockcmpxchg(&noreentry, false, true)) {
|
||||
if (!__vforked) {
|
||||
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
||||
|
@ -317,6 +318,6 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
|||
}
|
||||
noreentry = false;
|
||||
ItsATrap:
|
||||
__atomic_fetch_add(&__strace, 1, __ATOMIC_RELAXED);
|
||||
__atomic_fetch_add(&g_ftrace, 1, __ATOMIC_RELAXED);
|
||||
++__strace;
|
||||
++__ftrace;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,14 @@ STATIC_YOINK("__die"); /* for backtracing */
|
|||
STATIC_YOINK("malloc_inspect_all"); /* for asan memory origin */
|
||||
STATIC_YOINK("__get_symbol_by_addr"); /* for asan memory origin */
|
||||
|
||||
static struct sigaltstack oldsigaltstack;
|
||||
extern const unsigned char __oncrash_thunks[8][11];
|
||||
|
||||
static void FreeSigAltStack(void *p) {
|
||||
sigaltstack(&oldsigaltstack, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs crash signal handlers.
|
||||
*
|
||||
|
@ -63,17 +69,24 @@ void ShowCrashReports(void) {
|
|||
kCrashSigs[5] = SIGABRT; /* abort() called */
|
||||
kCrashSigs[6] = SIGBUS; /* misaligned, noncanonical ptr, etc. */
|
||||
/* </SYNC-LIST>: showcrashreports.c, oncrashthunks.S, oncrash.c */
|
||||
if (!IsWindows()) {
|
||||
bzero(&ss, sizeof(ss));
|
||||
ss.ss_flags = 0;
|
||||
ss.ss_size = SIGSTKSZ;
|
||||
if ((ss.ss_sp = malloc(SIGSTKSZ))) {
|
||||
if (!sigaltstack(&ss, &oldsigaltstack)) {
|
||||
__cxa_atexit(FreeSigAltStack, ss.ss_sp, 0);
|
||||
} else {
|
||||
free(ss.ss_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
bzero(&sa, sizeof(sa));
|
||||
ss.ss_flags = 0;
|
||||
ss.ss_size = SIGSTKSZ;
|
||||
ss.ss_sp = malloc(SIGSTKSZ);
|
||||
__cxa_atexit(free, ss.ss_sp, 0);
|
||||
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
||||
sigfillset(&sa.sa_mask);
|
||||
for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) {
|
||||
sigdelset(&sa.sa_mask, kCrashSigs[i]);
|
||||
}
|
||||
if (!IsWindows()) sigaltstack(&ss, 0);
|
||||
for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) {
|
||||
if (kCrashSigs[i]) {
|
||||
sa.sa_sigaction = (sigaction_f)__oncrash_thunks[i];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue