mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-06 11:18:30 +00:00
Make improvements to locking
This change makes pthread_mutex_lock() as fast as _spinlock() by default. Thread instability issues on NetBSD have been resolved. Improvements made to gdtoa thread code. Crash reporting will now synchronize between threads in a slightly better way.
This commit is contained in:
parent
25041b8026
commit
d5312b60f7
60 changed files with 890 additions and 629 deletions
|
@ -103,12 +103,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
|||
garbage = weaken(__garbage);
|
||||
gi = garbage ? garbage->i : 0;
|
||||
for (frame = bp; frame && i < kBacktraceMaxFrames - 1; frame = frame->next) {
|
||||
__mmi_lock();
|
||||
ok = IsValidStackFramePointer(frame);
|
||||
__mmi_unlock();
|
||||
if (!ok) {
|
||||
return -1;
|
||||
}
|
||||
addr = frame->addr;
|
||||
if (addr == weakaddr("__gc")) {
|
||||
do {
|
||||
|
|
|
@ -57,13 +57,6 @@ noinstrument noasan int PrintBacktraceUsingSymbols(int fd,
|
|||
garbage = weaken(__garbage);
|
||||
gi = garbage ? garbage->i : 0;
|
||||
for (i = 0, frame = bp; frame; frame = frame->next) {
|
||||
__mmi_lock();
|
||||
ok = IsValidStackFramePointer(frame);
|
||||
__mmi_unlock();
|
||||
if (!ok) {
|
||||
kprintf("%p corrupt frame pointer\n", frame);
|
||||
break;
|
||||
}
|
||||
if (++i == LIMIT) {
|
||||
kprintf("<truncated backtrace>\n");
|
||||
break;
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/lockcmpxchg.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/lockcmpxchgp.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
|
@ -32,18 +34,30 @@
|
|||
*/
|
||||
relegated wontreturn void __die(void) {
|
||||
/* asan runtime depends on this function */
|
||||
int rc;
|
||||
static bool once;
|
||||
if (_lockcmpxchg(&once, false, true)) {
|
||||
int me, owner;
|
||||
static int sync;
|
||||
owner = 0;
|
||||
me = gettid();
|
||||
if (_lockcmpxchgp(&sync, &owner, me)) {
|
||||
__restore_tty();
|
||||
if (IsDebuggerPresent(false)) {
|
||||
DebugBreak();
|
||||
}
|
||||
ShowBacktrace(2, NULL);
|
||||
rc = 77;
|
||||
if (weaken(ShowBacktrace)) {
|
||||
weaken(ShowBacktrace)(2, __builtin_frame_address(0));
|
||||
} else if (weaken(PrintBacktraceUsingSymbols) && weaken(GetSymbolTable)) {
|
||||
weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0),
|
||||
weaken(GetSymbolTable)());
|
||||
} else {
|
||||
kprintf("can't backtrace b/c `ShowCrashReports` not linked\n");
|
||||
}
|
||||
__restorewintty();
|
||||
_Exit(77);
|
||||
} else if (owner == me) {
|
||||
kprintf("die failed while dying\n");
|
||||
__restorewintty();
|
||||
_Exit(78);
|
||||
} else {
|
||||
rc = 78;
|
||||
_Exit1(79);
|
||||
}
|
||||
__restorewintty();
|
||||
_Exit(rc);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/lockcmpxchg.h"
|
||||
#include "libc/intrin/lockcmpxchgp.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
#include "libc/log/gdb.h"
|
||||
#include "libc/log/internal.h"
|
||||
|
@ -262,15 +263,22 @@ static wontreturn relegated noinstrument void __minicrash(int sig,
|
|||
* simply print addresses which may be cross-referenced using objdump.
|
||||
*
|
||||
* This function never returns, except for traps w/ human supervision.
|
||||
*
|
||||
* @threadsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
relegated void __oncrash(int sig, struct siginfo *si, ucontext_t *ctx) {
|
||||
intptr_t rip;
|
||||
int me, owner;
|
||||
int gdbpid, err;
|
||||
static bool noreentry, notpossible;
|
||||
static int sync;
|
||||
static bool notpossible;
|
||||
STRACE("__oncrash rip %x", ctx->uc_mcontext.rip);
|
||||
--__ftrace;
|
||||
--__strace;
|
||||
if (_lockcmpxchg(&noreentry, false, true)) {
|
||||
owner = 0;
|
||||
me = gettid();
|
||||
if (_lockcmpxchgp(&sync, &owner, me)) {
|
||||
if (!__vforked) {
|
||||
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
||||
err = errno;
|
||||
|
@ -292,20 +300,30 @@ relegated void __oncrash(int sig, struct siginfo *si, ucontext_t *ctx) {
|
|||
__restorewintty();
|
||||
_Exit(128 + sig);
|
||||
}
|
||||
sync = 0;
|
||||
} else {
|
||||
sync = 0;
|
||||
__minicrash(sig, si, ctx, "WHILE VFORKED");
|
||||
}
|
||||
} else if (sig == SIGTRAP) {
|
||||
/* chances are IsDebuggerPresent() confused strace w/ gdb */
|
||||
// chances are IsDebuggerPresent() confused strace w/ gdb
|
||||
goto ItsATrap;
|
||||
} else if (_lockcmpxchg(¬possible, false, true)) {
|
||||
__minicrash(sig, si, ctx, "WHILE CRASHING");
|
||||
} else {
|
||||
for (;;) {
|
||||
asm("ud2");
|
||||
} else if (owner == me) {
|
||||
// we crashed while generating a crash report
|
||||
if (_lockcmpxchg(¬possible, false, true)) {
|
||||
__minicrash(sig, si, ctx, "WHILE CRASHING");
|
||||
} else {
|
||||
// somehow __minicrash() crashed not possible
|
||||
for (;;) {
|
||||
asm("ud2");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// multiple threads have crashed
|
||||
// kill current thread assuming process dies soon
|
||||
// TODO(jart): It'd be nice to report on all threads.
|
||||
_Exit1(8);
|
||||
}
|
||||
noreentry = false;
|
||||
ItsATrap:
|
||||
++__strace;
|
||||
++__ftrace;
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/struct/termios.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/color.internal.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Terminal Restoration Helper for System Five.
|
||||
*
|
||||
* This is used by the crash reporting functions, e.g. __die(), to help
|
||||
* ensure the terminal is in an unborked state after a crash happens.
|
||||
*/
|
||||
|
||||
#define RESET_COLOR "\e[0m"
|
||||
#define SHOW_CURSOR "\e[?25h"
|
||||
#define DISABLE_MOUSE "\e[?1000;1002;1015;1006l"
|
||||
#define ANSI_RESTORE RESET_COLOR SHOW_CURSOR DISABLE_MOUSE
|
||||
|
||||
static bool __isrestorable;
|
||||
static union metatermios __oldtermios;
|
||||
|
||||
static textstartup void __oldtermios_init() {
|
||||
int e;
|
||||
e = errno;
|
||||
if (sys_ioctl(0, TCGETS, &__oldtermios) != -1) {
|
||||
__isrestorable = true;
|
||||
}
|
||||
errno = e;
|
||||
}
|
||||
|
||||
const void *const __oldtermios_ctor[] initarray = {
|
||||
__oldtermios_init,
|
||||
};
|
||||
|
||||
void __restore_tty(void) {
|
||||
int e;
|
||||
if (__isrestorable && !__isworker && !__nocolor) {
|
||||
e = errno;
|
||||
sys_write(0, ANSI_RESTORE, __strlen(ANSI_RESTORE));
|
||||
sys_ioctl(0, TCSETSF, &__oldtermios);
|
||||
errno = e;
|
||||
}
|
||||
}
|
|
@ -30,9 +30,12 @@
|
|||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/ss.h"
|
||||
|
||||
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_YOINK("__die"); // for backtracing
|
||||
STATIC_YOINK("ShowBacktrace"); // for backtracing
|
||||
STATIC_YOINK("GetSymbolTable"); // for backtracing
|
||||
STATIC_YOINK("PrintBacktraceUsingSymbols"); // for backtracing
|
||||
STATIC_YOINK("malloc_inspect_all"); // for asan memory origin
|
||||
STATIC_YOINK("__get_symbol_by_addr"); // for asan memory origin
|
||||
|
||||
extern const unsigned char __oncrash_thunks[8][11];
|
||||
static struct sigaltstack g_oldsigaltstack;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue