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:
Justine Tunney 2022-05-18 16:41:29 -07:00
parent c6bbca55e9
commit 9208c83f7a
141 changed files with 1948 additions and 1411 deletions

View file

@ -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"

View file

@ -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");

View file

@ -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; \
})
/*───────────────────────────────────────────────────────────────────────────│─╗

View file

@ -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 \

View file

@ -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;
}

View file

@ -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];