mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-06 03:08:31 +00:00
Make improvements
- Get threads working on NetBSD - Get threads working on OpenBSD - Fix Emacs config for Emacs v28 - Improve --strace logging of sigset_t - Improve --strace logging of struct stat - Improve memory safety of DescribeThing functions - Refactor auto stack allocation into LIBC_RUNTIME - Introduce shell.com example which works on Windows - Refactor __strace_thing into DescribeThing functions - Document the CHECK macros and improve them in NDEBUG mode - Rewrite MAP_STACK so it uses FreeBSD behavior across platforms - Deprecate and discourage the use of MAP_GROWSDOWN (it's weird)
This commit is contained in:
parent
dd9ab01d25
commit
e7611a8476
101 changed files with 967 additions and 464 deletions
|
@ -24,19 +24,20 @@ COSMOPOLITAN_C_START_
|
|||
#define DCHECK_NOTNULL(X, ...) \
|
||||
__DCHK(ne, !=, NULL, "NULL", X, #X, "" __VA_ARGS__)
|
||||
|
||||
#define CHECK_ALIGNED(BYTES, VAR) \
|
||||
do { \
|
||||
if (((uintptr_t)VAR & ((BYTES)-1u))) { \
|
||||
__check_fail_aligned(BYTES, (uintptr_t)VAR); \
|
||||
unreachable; \
|
||||
} \
|
||||
VAR = (typeof(VAR))__builtin_assume_aligned(VAR, BYTES); \
|
||||
#define CHECK_ALIGNED(BYTES, VAR, ...) \
|
||||
do { \
|
||||
if (((uintptr_t)VAR & ((BYTES)-1u))) { \
|
||||
__check_fail_aligned(BYTES, (uintptr_t)VAR, __FILE__, __LINE__, \
|
||||
"" __VA_ARGS__); \
|
||||
unreachable; \
|
||||
} \
|
||||
VAR = (typeof(VAR))__builtin_assume_aligned(VAR, BYTES); \
|
||||
} while (0)
|
||||
|
||||
#define DCHECK_ALIGNED(BYTES, VAR) \
|
||||
#define DCHECK_ALIGNED(BYTES, VAR, ...) \
|
||||
do { \
|
||||
if (((uintptr_t)VAR & ((BYTES)-1u))) { \
|
||||
__DCHK_ALIGNED(BYTES, (uintptr_t)VAR); \
|
||||
__DCHK_ALIGNED(BYTES, (uintptr_t)VAR, "" __VA_ARGS__); \
|
||||
unreachable; \
|
||||
} \
|
||||
VAR = (typeof(VAR))__builtin_assume_aligned(VAR, BYTES); \
|
||||
|
@ -51,7 +52,8 @@ COSMOPOLITAN_C_START_
|
|||
__check_fail(#SUFFIX, #OP, (uint64_t)Want, (WANTSTR), (uint64_t)Got, \
|
||||
(GOTSTR), __FILE__, __LINE__, __VA_ARGS__); \
|
||||
} else { \
|
||||
__check_fail_##SUFFIX((uint64_t)Want, (uint64_t)Got); \
|
||||
__check_fail_##SUFFIX((uint64_t)Want, (uint64_t)Got, __FILE__, \
|
||||
__LINE__, 0, __VA_ARGS__); \
|
||||
} \
|
||||
unreachable; \
|
||||
} \
|
||||
|
@ -72,22 +74,30 @@ COSMOPOLITAN_C_START_
|
|||
#endif /* NDEBUG */
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define __DCHK_ALIGNED(BYTES, VAR)
|
||||
#define __DCHK_ALIGNED(BYTES, VAR, ...)
|
||||
#else
|
||||
#define __DCHK_ALIGNED(BYTES, VAR) __check_fail_aligned(BYTES, VAR)
|
||||
#define __DCHK_ALIGNED(BYTES, VAR, ...) \
|
||||
__check_fail_aligned(BYTES, VAR, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
void __check_fail(const char *, const char *, uint64_t, const char *, uint64_t,
|
||||
const char *, const char *, int, const char *,
|
||||
...) relegated wontreturn;
|
||||
|
||||
void __check_fail_eq(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_ne(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_le(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_lt(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_ge(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_gt(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_aligned(unsigned, uint64_t) relegated wontreturn;
|
||||
void __check_fail_eq(uint64_t, uint64_t, const char *, int, const char *,
|
||||
const char *, ...) relegated wontreturn;
|
||||
void __check_fail_ne(uint64_t, uint64_t, const char *, int, const char *,
|
||||
const char *, ...) relegated wontreturn;
|
||||
void __check_fail_le(uint64_t, uint64_t, const char *, int, const char *,
|
||||
const char *, ...) relegated wontreturn;
|
||||
void __check_fail_lt(uint64_t, uint64_t, const char *, int, const char *,
|
||||
const char *, ...) relegated wontreturn;
|
||||
void __check_fail_ge(uint64_t, uint64_t, const char *, int, const char *,
|
||||
const char *, ...) relegated wontreturn;
|
||||
void __check_fail_gt(uint64_t, uint64_t, const char *, int, const char *,
|
||||
const char *, ...) relegated wontreturn;
|
||||
void __check_fail_aligned(unsigned, uint64_t, const char *, int, const char *,
|
||||
...) relegated wontreturn;
|
||||
|
||||
#ifdef __VSCODE_INTELLISENSE__
|
||||
#undef __CHK
|
||||
|
|
|
@ -18,14 +18,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
void __check_fail_aligned(unsigned bytes, uint64_t ptr) {
|
||||
void __check_fail_aligned(unsigned bytes, uint64_t ptr, const char *file,
|
||||
int line, const char *fmt, ...) {
|
||||
fflush(stderr);
|
||||
if (!IsTiny()) memsummary(fileno(stderr));
|
||||
(dprintf)(fileno(stderr), "%s%d%s%#p\n", "error: pointer not ", bytes,
|
||||
"-byte aligned: ", ptr);
|
||||
kprintf("%s:%d: error: pointer not %d-byte aligned: %p\n", file, line, bytes,
|
||||
ptr);
|
||||
__die();
|
||||
}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Handles failure of CHECK_xx() macros in -DNDEBUG mode.
|
||||
|
@ -33,12 +33,22 @@
|
|||
*
|
||||
* @see libc/log/thunks/__check_fail_ndebug.S
|
||||
*/
|
||||
relegated void ___check_fail_ndebug(uint64_t want, uint64_t got,
|
||||
const char *opchar) {
|
||||
relegated wontreturn void __check_fail_ndebug(uint64_t want, uint64_t got,
|
||||
const char *file, int line,
|
||||
const char *opchar,
|
||||
const char *fmt, ...) {
|
||||
va_list va;
|
||||
__restore_tty();
|
||||
(fprintf)(stderr, "\n%serror: %s: check failed: 0x%x %s 0x%x (%s)\n",
|
||||
!__nocolor ? "\e[J" : "", program_invocation_name, want, opchar,
|
||||
got, strerror(errno));
|
||||
kprintf("%rerror:%s:%d: check failed: %'ld %s %'ld% m", file, line, want,
|
||||
opchar, got);
|
||||
if (*fmt) {
|
||||
kprintf(": ");
|
||||
va_start(va, fmt);
|
||||
kvprintf(fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
kprintf("\n");
|
||||
if (weaken(__die)) weaken(__die)();
|
||||
__restorewintty();
|
||||
_Exit(68);
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
|
|||
uname(&names);
|
||||
p = buf;
|
||||
errno = err;
|
||||
kprintf("\n%serror%s: Uncaught %G (%s) on %s pid %d\n"
|
||||
kprintf("\n%serror%s: Uncaught %G (%s) on %s pid %d tid %d\n"
|
||||
" %s\n"
|
||||
" %m\n"
|
||||
" %s %s %s %s\n",
|
||||
|
@ -210,8 +210,8 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
|
|||
ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE))
|
||||
? "Stack Overflow"
|
||||
: GetSiCodeName(sig, si->si_code),
|
||||
host, getpid(), program_invocation_name, names.sysname, names.version,
|
||||
names.nodename, names.release);
|
||||
host, getpid(), gettid(), program_invocation_name, names.sysname,
|
||||
names.version, names.nodename, names.release);
|
||||
if (ctx) {
|
||||
kprintf("\n");
|
||||
ShowFunctionCalls(ctx);
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigaltstack.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -33,6 +35,10 @@ STATIC_YOINK("__get_symbol_by_addr"); /* for asan memory origin */
|
|||
|
||||
extern const unsigned char __oncrash_thunks[8][11];
|
||||
|
||||
static void FreeSigaltstack(void *p) {
|
||||
free(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs crash signal handlers.
|
||||
*
|
||||
|
@ -67,7 +73,7 @@ void ShowCrashReports(void) {
|
|||
ss.ss_flags = 0;
|
||||
ss.ss_size = SIGSTKSZ;
|
||||
ss.ss_sp = malloc(SIGSTKSZ);
|
||||
__cxa_atexit(free, ss.ss_sp, 0);
|
||||
__cxa_atexit(FreeSigaltstack, ss.ss_sp, 0);
|
||||
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
||||
sigfillset(&sa.sa_mask);
|
||||
for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) {
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
// Code-size saving thunk for CHECK_EQ() in NDEBUG mode.
|
||||
__check_fail_eq:
|
||||
loadstr "==",dx
|
||||
lea .Lop(%rip),%r8
|
||||
jmp __check_fail_ndebug
|
||||
.endfn __check_fail_eq,globl
|
||||
|
||||
.rodata.str1.1
|
||||
.Lop: .asciz "=="
|
||||
.previous
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
// Code-size saving thunk for CHECK_GE() in NDEBUG mode.
|
||||
__check_fail_ge:
|
||||
loadstr ">=",dx
|
||||
lea .Lop(%rip),%r8
|
||||
jmp __check_fail_ndebug
|
||||
.endfn __check_fail_ge,globl
|
||||
|
||||
.rodata.str1.1
|
||||
.Lop: .asciz ">="
|
||||
.previous
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
// Code-size saving thunk for CHECK_GT() in NDEBUG mode.
|
||||
__check_fail_gt:
|
||||
loadstr ">",dx
|
||||
lea .Lop(%rip),%r8
|
||||
jmp __check_fail_ndebug
|
||||
.endfn __check_fail_gt,globl
|
||||
|
||||
.rodata.str1.1
|
||||
.Lop: .asciz ">"
|
||||
.previous
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
// Code-size saving thunk for CHECK_LE() in NDEBUG mode.
|
||||
__check_fail_le:
|
||||
loadstr "<=",dx
|
||||
lea .Lop(%rip),%r8
|
||||
jmp __check_fail_ndebug
|
||||
.endfn __check_fail_le,globl
|
||||
|
||||
.rodata.str1.1
|
||||
.Lop: .asciz "<="
|
||||
.previous
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
// Code-size saving thunk for CHECK_LT() in NDEBUG mode.
|
||||
__check_fail_lt:
|
||||
loadstr "<",dx
|
||||
lea .Lop(%rip),%r8
|
||||
jmp __check_fail_ndebug
|
||||
.endfn __check_fail_lt,globl
|
||||
|
||||
.rodata.str1.1
|
||||
.Lop: .asciz "<"
|
||||
.previous
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 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/macros.internal.h"
|
||||
|
||||
__check_fail_ndebug:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
call ___check_fail_ndebug
|
||||
pop %rbp
|
||||
jmp __die # fewer elements in backtrace
|
||||
.endfn __check_fail_ndebug,globl
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
// Code-size saving thunk for CHECK_NE() in NDEBUG mode.
|
||||
__check_fail_ne:
|
||||
loadstr "!=",dx
|
||||
lea .Lop(%rip),%r8
|
||||
jmp __check_fail_ndebug
|
||||
.endfn __check_fail_ne,globl
|
||||
|
||||
.rodata.str1.1
|
||||
.Lop: .asciz "!="
|
||||
.previous
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue