Restart CI for New Technology and UBSAN hunting

Continuous Integration (via runit and runitd) is now re-enabled on win7
and win10. The `make test` command, which runs the tests on all systems
is now the fastest and most stable it's been since the project started.

UBSAN is now enabled in MODE=dbg in addition to ASAN. Many instances of
undefined behavior have been removed. Mostly things like passing a NULL
argument to memcpy(), which works fine with Cosmopolitan Libc, but that
doesn't prevents the compiler from being unhappy. There was an issue w/
GNU make where static analysis claims a sprintf() call can overflow. We
also now have nicer looking crash reports on Windows since uname should
now be supported and msys64 addr2line works reliably.
This commit is contained in:
Justine Tunney 2022-03-21 03:46:16 -07:00
parent d5ff2c3fb9
commit 5e8ae2d5bc
80 changed files with 506 additions and 249 deletions

View file

@ -60,7 +60,7 @@
# build/config.mk # build/config.mk
SHELL = /bin/sh SHELL = /bin/sh
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu #win7 win10 HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win7 win10
SANITY := $(shell build/sanitycheck $$PPID) SANITY := $(shell build/sanitycheck $$PPID)
.SUFFIXES: .SUFFIXES:
@ -69,7 +69,10 @@ SANITY := $(shell build/sanitycheck $$PPID)
.PHONY: all o bins check test depend tags .PHONY: all o bins check test depend tags
all: o all: o
o: o/$(MODE)/ape \ o: o/$(MODE)
o/$(MODE): \
o/$(MODE)/ape \
o/$(MODE)/dsp \ o/$(MODE)/dsp \
o/$(MODE)/net \ o/$(MODE)/net \
o/$(MODE)/libc \ o/$(MODE)/libc \

Binary file not shown.

View file

@ -131,7 +131,8 @@ CONFIG_CCFLAGS += \
-O2 \ -O2 \
-fno-inline -fno-inline
CONFIG_COPTS += \ CONFIG_COPTS += \
-fsanitize=address -fsanitize=address \
-fsanitize=undefined
TARGET_ARCH ?= \ TARGET_ARCH ?= \
-msse3 -msse3
OVERRIDE_CCFLAGS += \ OVERRIDE_CCFLAGS += \

View file

@ -40,7 +40,7 @@
*/ */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
asm("int3"); /* cf. __die(), perror("msg"), abort(), exit(1), _Exit(1) */ asm("int3"); /* cf. __die(), perror("msg"), abort(), exit(1), _Exit(1) */
return 0; return 0;
} }

View file

@ -14,7 +14,7 @@
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
if (IsDebuggerPresent(false)) { if (IsDebuggerPresent(false)) {
printf("debugger found!\r\n"); printf("debugger found!\r\n");
DebugBreak(); DebugBreak();

View file

@ -24,6 +24,6 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
volatile int64_t x; volatile int64_t x;
showcrashreports(); ShowCrashReports();
return 1 / (x = 0); return 1 / (x = 0);
} }

View file

@ -121,7 +121,7 @@ static wontreturn void PrintUsage(FILE *f, int rc) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (!NoDebug()) showcrashreports(); if (!NoDebug()) ShowCrashReports();
/* /*
* Read flags. * Read flags.

View file

@ -43,7 +43,7 @@ void PrintUri(const char *path) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
int i; int i;
while ((i = getopt(argc, argv, "?h")) != -1) { while ((i = getopt(argc, argv, "?h")) != -1) {
switch (i) { switch (i) {

View file

@ -67,7 +67,7 @@ void PrintImg(const char *path) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
int i; int i;
while ((i = getopt(argc, argv, "?huas01234")) != -1) { while ((i = getopt(argc, argv, "?huas01234")) != -1) {
switch (i) { switch (i) {

View file

@ -153,7 +153,7 @@ void LoadWords(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
LoadWords(); LoadWords();
SpellChecker(); SpellChecker();
return 0; return 0;

View file

@ -152,7 +152,7 @@ void Draw(void) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
struct sigaction sa[2] = {{.sa_handler = OnShutdown}, struct sigaction sa[2] = {{.sa_handler = OnShutdown},
{.sa_handler = OnInvalidate}}; {.sa_handler = OnInvalidate}};
showcrashreports(); ShowCrashReports();
Setup(); Setup();
Enter(); Enter();
GetTtySize(); GetTtySize();

24
examples/uname.c Normal file
View file

@ -0,0 +1,24 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
To the extent possible under law, Justine Tunney has waived
all copyright and related or neighboring rights to this file,
as it is written in the following disclaimers:
http://unlicense.org/ │
http://creativecommons.org/publicdomain/zero/1.0/ │
*/
#endif
#include "libc/calls/calls.h"
#include "libc/calls/struct/utsname.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
struct utsname names;
if (uname(&names)) return 1;
printf("%-10s %s\n", "sysname", names.sysname);
printf("%-10s %s\n", "nodename", names.nodename);
printf("%-10s %s\n", "release", names.release);
printf("%-10s %s\n", "version", names.version);
printf("%-10s %s\n", "machine", names.machine);
printf("%-10s %s\n", "domainname", names.domainname);
return 0;
}

View file

@ -22,11 +22,11 @@
#include "libc/nt/systeminfo.h" #include "libc/nt/systeminfo.h"
#include "libc/str/str.h" #include "libc/str/str.h"
textwindows int gethostname_nt(char *name, size_t len) { textwindows int gethostname_nt(char *name, size_t len, int kind) {
uint32_t nSize; uint32_t nSize;
char16_t name16[256]; char16_t name16[256];
nSize = ARRAYLEN(name16); nSize = ARRAYLEN(name16);
if (GetComputerNameEx(kNtComputerNamePhysicalDnsHostname, name16, &nSize)) { if (GetComputerNameEx(kind, name16, &nSize)) {
tprecode16to8(name, len, name16); tprecode16to8(name, len, name16);
return 0; return 0;
} else { } else {

View file

@ -19,6 +19,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/nt/enum/computernameformat.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
/** /**
@ -37,6 +38,6 @@ int gethostname(char *name, size_t len) {
return gethostname_bsd(name, len); return gethostname_bsd(name, len);
} }
} else { } else {
return gethostname_nt(name, len); return gethostname_nt(name, len, kNtComputerNamePhysicalDnsHostname);
} }
} }

View file

@ -234,7 +234,7 @@ void __sigenter_xnu(void *, i32, i32, struct __darwin_siginfo *,
struct __darwin_ucontext *) hidden; struct __darwin_ucontext *) hidden;
int gethostname_linux(char *, size_t) hidden; int gethostname_linux(char *, size_t) hidden;
int gethostname_bsd(char *, size_t) hidden; int gethostname_bsd(char *, size_t) hidden;
int gethostname_nt(char *, size_t) hidden; int gethostname_nt(char *, size_t, int) hidden;
size_t __iovec_size(const struct iovec *, size_t) hidden; size_t __iovec_size(const struct iovec *, size_t) hidden;
void __rusage2linux(struct rusage *) hidden; void __rusage2linux(struct rusage *) hidden;
int __notziposat(int, const char *); int __notziposat(int, const char *);

View file

@ -24,6 +24,7 @@
textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) { textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
if (!cr) return; if (!cr) return;
ctx->uc_flags = cr->EFlags; ctx->uc_flags = cr->EFlags;
ctx->uc_mcontext.gregs[REG_EFL] = cr->EFlags;
ctx->uc_mcontext.rax = cr->Rax; ctx->uc_mcontext.rax = cr->Rax;
ctx->uc_mcontext.rbx = cr->Rbx; ctx->uc_mcontext.rbx = cr->Rbx;
ctx->uc_mcontext.rcx = cr->Rcx; ctx->uc_mcontext.rcx = cr->Rcx;

View file

@ -18,23 +18,47 @@
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/utsname.h" #include "libc/calls/struct/utsname.h"
#include "libc/dce.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/asan.internal.h"
#include "libc/nt/enum/computernameformat.h"
#include "libc/nt/struct/teb.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
static inline textwindows noasan int NtGetMajorVersion(void) {
return NtGetPeb()->OSMajorVersion;
}
static inline textwindows noasan int NtGetMinorVersion(void) {
return NtGetPeb()->OSMinorVersion;
}
static inline textwindows noasan int NtGetBuildNumber(void) {
return NtGetPeb()->OSBuildNumber;
}
/** /**
* Asks kernel to give us the `uname -a` data. * Asks kernel to give us the `uname -a` data.
* @return 0 on success, or -1 w/ errno * @return 0 on success, or -1 w/ errno
*/ */
int uname(struct utsname *lool) { int uname(struct utsname *lool) {
char *out; int rc, v;
char *out, *p;
size_t i, j, len; size_t i, j, len;
char tmp[sizeof(struct utsname)]; char tmp[sizeof(struct utsname)];
if (!lool) return efault();
if (!lool || (IsAsan() && !__asan_is_valid(lool, sizeof(*lool)))) {
rc = efault();
} else {
bzero(tmp, sizeof(tmp)); bzero(tmp, sizeof(tmp));
if (sys_uname(tmp) != -1) { if (!IsWindows()) {
if ((rc = sys_uname(tmp)) != -1) {
out = (char *)lool; out = (char *)lool;
i = 0; for (i = j = 0;;) {
j = 0;
for (;;) {
len = strlen(&tmp[j]); len = strlen(&tmp[j]);
if (len >= sizeof(struct utsname) - i) break; if (len >= sizeof(struct utsname) - i) break;
memcpy(&out[i], &tmp[j], len + 1); memcpy(&out[i], &tmp[j], len + 1);
@ -43,9 +67,23 @@ int uname(struct utsname *lool) {
while (j < sizeof(tmp) && tmp[j] == '\0') ++j; while (j < sizeof(tmp) && tmp[j] == '\0') ++j;
if (j == sizeof(tmp)) break; if (j == sizeof(tmp)) break;
} }
return 0;
} else {
bzero(lool, sizeof(struct utsname));
return -1;
} }
} else {
v = NtGetVersion();
p = lool->version;
p = FormatUint32(p, NtGetMajorVersion()), *p++ = '.';
p = FormatUint32(p, NtGetMinorVersion()), *p++ = '-';
p = FormatUint32(p, NtGetBuildNumber());
strcpy(lool->sysname, "The New Technology");
strcpy(lool->machine, "x86_64");
rc = gethostname_nt(lool->nodename, sizeof(lool->nodename),
kNtComputerNamePhysicalDnsHostname);
rc |= gethostname_nt(lool->domainname, sizeof(lool->domainname),
kNtComputerNamePhysicalDnsDomain);
}
}
STRACE("uname([%s, %s, %s, %s, %s, %s]) → %d% m", lool->sysname,
lool->nodename, lool->release, lool->version, lool->machine,
lool->domainname, rc);
return rc;
} }

View file

@ -24,9 +24,10 @@
#include "libc/nt/enum/signal.h" #include "libc/nt/enum/signal.h"
#include "libc/nt/struct/ntexceptionpointers.h" #include "libc/nt/struct/ntexceptionpointers.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/sicode.h"
textwindows unsigned __wincrash(struct NtExceptionPointers *ep) { textwindows unsigned __wincrash(struct NtExceptionPointers *ep) {
int sig, rva; int sig, rva, code;
struct Goodies { struct Goodies {
ucontext_t ctx; ucontext_t ctx;
struct siginfo si; struct siginfo si;
@ -34,44 +35,69 @@ textwindows unsigned __wincrash(struct NtExceptionPointers *ep) {
STRACE("__wincrash"); STRACE("__wincrash");
switch (ep->ExceptionRecord->ExceptionCode) { switch (ep->ExceptionRecord->ExceptionCode) {
case kNtSignalBreakpoint: case kNtSignalBreakpoint:
code = TRAP_BRKPT;
sig = SIGTRAP; sig = SIGTRAP;
break; break;
case kNtSignalIllegalInstruction: case kNtSignalIllegalInstruction:
code = ILL_ILLOPC;
sig = SIGILL;
break;
case kNtSignalPrivInstruction: case kNtSignalPrivInstruction:
code = ILL_PRVOPC;
sig = SIGILL; sig = SIGILL;
break; break;
case kNtSignalGuardPage: case kNtSignalGuardPage:
case kNtSignalAccessViolation:
case kNtSignalInPageError: case kNtSignalInPageError:
code = SEGV_MAPERR;
sig = SIGSEGV;
break;
case kNtSignalAccessViolation:
code = SEGV_ACCERR;
sig = SIGSEGV; sig = SIGSEGV;
break; break;
case kNtSignalInvalidHandle: case kNtSignalInvalidHandle:
case kNtSignalInvalidParameter: case kNtSignalInvalidParameter:
case kNtSignalAssertionFailure: case kNtSignalAssertionFailure:
code = SI_USER;
sig = SIGABRT; sig = SIGABRT;
break; break;
case kNtSignalFltDenormalOperand:
case kNtSignalFltDivideByZero: case kNtSignalFltDivideByZero:
case kNtSignalFltInexactResult: code = FPE_FLTDIV;
case kNtSignalFltInvalidOperation: sig = SIGFPE;
break;
case kNtSignalFltOverflow: case kNtSignalFltOverflow:
case kNtSignalFltStackCheck: code = FPE_FLTOVF;
sig = SIGFPE;
break;
case kNtSignalFltUnderflow: case kNtSignalFltUnderflow:
code = FPE_FLTUND;
sig = SIGFPE;
break;
case kNtSignalFltInexactResult:
code = FPE_FLTRES;
sig = SIGFPE;
break;
case kNtSignalFltDenormalOperand:
case kNtSignalFltInvalidOperation:
case kNtSignalFltStackCheck:
case kNtSignalIntegerDivideByZero: case kNtSignalIntegerDivideByZero:
case kNtSignalFloatMultipleFaults: case kNtSignalFloatMultipleFaults:
case kNtSignalFloatMultipleTraps: case kNtSignalFloatMultipleTraps:
code = FPE_FLTINV;
sig = SIGFPE; sig = SIGFPE;
break; break;
case kNtSignalDllNotFound: case kNtSignalDllNotFound:
case kNtSignalOrdinalNotFound: case kNtSignalOrdinalNotFound:
case kNtSignalEntrypointNotFound: case kNtSignalEntrypointNotFound:
case kNtSignalDllInitFailed: case kNtSignalDllInitFailed:
code = SI_KERNEL;
sig = SIGSYS; sig = SIGSYS;
break; break;
default: default:
return kNtExceptionContinueSearch; return kNtExceptionContinueSearch;
} }
bzero(&g, sizeof(g)); bzero(&g, sizeof(g));
g.si.si_code = code;
rva = __sighandrvas[sig]; rva = __sighandrvas[sig];
if (rva >= kSigactionMinRva) { if (rva >= kSigactionMinRva) {
ntcontext2linux(&g.ctx, ep->ContextRecord); ntcontext2linux(&g.ctx, ep->ContextRecord);

View file

@ -57,7 +57,7 @@
#define IsOptimized() 0 #define IsOptimized() 0
#endif #endif
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
#define IsAsan() 1 #define IsAsan() 1
#else #else
#define IsAsan() 0 #define IsAsan() 0

View file

@ -43,9 +43,6 @@
#include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/nr.h"
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
#define MAXT (24 * 60 * 60 * 1000000000ull)
#define WRAP ((MAXT + 1) / 10 * 33)
struct Timestamps { struct Timestamps {
unsigned long long birth; unsigned long long birth;
unsigned long long start; unsigned long long start;
@ -56,6 +53,13 @@ extern bool __replmode;
extern bool __nomultics; extern bool __nomultics;
volatile unsigned long long __kbirth; volatile unsigned long long __kbirth;
static inline uint64_t ClocksToNanos(uint64_t x, uint64_t y) {
// approximation of round(x*.323018) which is usually
// the ratio between inva rdtsc ticks and nanoseconds
uint128_t difference = x - y;
return (difference * 338709) >> 20;
}
privileged static struct Timestamps kenter(void) { privileged static struct Timestamps kenter(void) {
struct Timestamps ts; struct Timestamps ts;
ts.start = rdtsc(); ts.start = rdtsc();
@ -336,7 +340,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
} }
continue; continue;
case 'T': case 'T':
x = unsignedsubtract(ts.start, ts.birth) % WRAP * 10 / 33; x = ClocksToNanos(ts.start, ts.birth) % 86400000000000;
goto FormatUnsigned; goto FormatUnsigned;
case 'P': case 'P':
if (!__vforked) { if (!__vforked) {

View file

@ -22,6 +22,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/log/color.internal.h"
#include "libc/log/internal.h" #include "libc/log/internal.h"
#include "libc/log/libfatal.internal.h" #include "libc/log/libfatal.internal.h"
#include "libc/log/log.h" #include "libc/log/log.h"
@ -37,6 +38,8 @@
#define kUbsanKindFloat 1 #define kUbsanKindFloat 1
#define kUbsanKindUnknown 0xffff #define kUbsanKindUnknown 0xffff
typedef void __ubsan_die_f(void);
struct UbsanSourceLocation { struct UbsanSourceLocation {
const char *file; const char *file;
uint32_t line; uint32_t line;
@ -188,17 +191,42 @@ static uintptr_t __ubsan_extend(struct UbsanTypeDescriptor *t, uintptr_t x) {
return x; return x;
} }
void __ubsan_abort(const struct UbsanSourceLocation *loc, static wontreturn void __ubsan_unreachable(void) {
for (;;) __builtin_trap();
}
static void __ubsan_exit(void) {
kprintf("your ubsan runtime needs%n"
"\tSTATIC_YOINK(\"__die\");%n"
"in order to show you backtraces%n");
_Exit(99);
}
nodiscard static __ubsan_die_f *__ubsan_die(void) {
if (weaken(__die)) {
return weaken(__die);
} else {
return __ubsan_exit;
}
}
static void __ubsan_warning(const struct UbsanSourceLocation *loc,
const char *description) { const char *description) {
kprintf("%n%s:%d: ubsan error: %s%n", loc->file, loc->line, description); kprintf("%s:%d: %subsan warning: %s is undefined behavior%s%n", loc->file,
if (weaken(__die)) weaken(__die)(); loc->line, SUBTLE, description, RESET);
_Exit(134); }
nodiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("%n%s:%d: %subsan error%s: %s%n", loc->file, loc->line, RED2, RESET,
description);
return __ubsan_die();
} }
static const char *__ubsan_describe_shift( static const char *__ubsan_describe_shift(
struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) { struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) {
if (__ubsan_negative(info->rhs_type, rhs)) { if (__ubsan_negative(info->rhs_type, rhs)) {
return "shift exponent is negative"; return "negative shift exponent";
} else if (rhs >= __ubsan_bits(info->lhs_type)) { } else if (rhs >= __ubsan_bits(info->lhs_type)) {
return "shift exponent too large for type"; return "shift exponent too large for type";
} else if (__ubsan_negative(info->lhs_type, lhs)) { } else if (__ubsan_negative(info->lhs_type, lhs)) {
@ -210,9 +238,10 @@ static const char *__ubsan_describe_shift(
} }
} }
void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, static char *__ubsan_describe_shift_out_of_bounds(
uintptr_t lhs, uintptr_t rhs) { char buf[512], struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs,
char buf[512], *p = buf; uintptr_t rhs) {
char *p = buf;
lhs = __ubsan_extend(info->lhs_type, lhs); lhs = __ubsan_extend(info->lhs_type, lhs);
rhs = __ubsan_extend(info->rhs_type, rhs); rhs = __ubsan_extend(info->rhs_type, rhs);
p = __stpcpy(p, __ubsan_describe_shift(info, lhs, rhs)), *p++ = ' '; p = __stpcpy(p, __ubsan_describe_shift(info, lhs, rhs)), *p++ = ' ';
@ -220,12 +249,22 @@ void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info,
p = __stpcpy(p, info->lhs_type->name), *p++ = ' '; p = __stpcpy(p, info->lhs_type->name), *p++ = ' ';
p = __ubsan_itpcpy(p, info->rhs_type, rhs), *p++ = ' '; p = __ubsan_itpcpy(p, info->rhs_type, rhs), *p++ = ' ';
p = __stpcpy(p, info->rhs_type->name); p = __stpcpy(p, info->rhs_type->name);
__ubsan_abort(&info->location, buf); return buf;
}
void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info,
uintptr_t lhs, uintptr_t rhs) {
char buf[512];
__ubsan_warning(&info->location,
__ubsan_describe_shift_out_of_bounds(buf, info, lhs, rhs));
} }
void __ubsan_handle_shift_out_of_bounds_abort( void __ubsan_handle_shift_out_of_bounds_abort(
struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) { struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) {
__ubsan_handle_shift_out_of_bounds(info, lhs, rhs); char buf[512];
__ubsan_abort(&info->location,
__ubsan_describe_shift_out_of_bounds(buf, info, lhs, rhs))();
__ubsan_unreachable();
} }
void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info, void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info,
@ -237,7 +276,8 @@ void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info,
p = __stpcpy(p, " into "); p = __stpcpy(p, " into ");
p = __stpcpy(p, info->array_type->name); p = __stpcpy(p, info->array_type->name);
p = __stpcpy(p, " out of bounds"); p = __stpcpy(p, " out of bounds");
__ubsan_abort(&info->location, buf); __ubsan_abort(&info->location, buf)();
__ubsan_unreachable();
} }
void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info, void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info,
@ -245,11 +285,11 @@ void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info,
__ubsan_handle_out_of_bounds(info, index); __ubsan_handle_out_of_bounds(info, index);
} }
void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, static __ubsan_die_f *__ubsan_type_mismatch_handler(
uintptr_t pointer) { struct UbsanTypeMismatchInfo *info, uintptr_t pointer) {
const char *kind; const char *kind;
char buf[512], *p = buf; char buf[512], *p = buf;
if (!pointer) __ubsan_abort(&info->location, "null pointer access"); if (!pointer) return __ubsan_abort(&info->location, "null pointer access");
kind = __ubsan_dubnul(kUbsanTypeCheckKinds, info->type_check_kind); kind = __ubsan_dubnul(kUbsanTypeCheckKinds, info->type_check_kind);
if (info->alignment && (pointer & (info->alignment - 1))) { if (info->alignment && (pointer & (info->alignment - 1))) {
p = __stpcpy(p, "unaligned "); p = __stpcpy(p, "unaligned ");
@ -266,41 +306,57 @@ void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info,
p = __stpcpy(p, " with insufficient space for object of type "); p = __stpcpy(p, " with insufficient space for object of type ");
p = __stpcpy(p, info->type->name); p = __stpcpy(p, info->type->name);
} }
__ubsan_abort(&info->location, buf); return __ubsan_abort(&info->location, buf);
}
void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info,
uintptr_t pointer) {
__ubsan_type_mismatch_handler(info, pointer)();
__ubsan_unreachable();
} }
void __ubsan_handle_type_mismatch_abort(struct UbsanTypeMismatchInfo *info, void __ubsan_handle_type_mismatch_abort(struct UbsanTypeMismatchInfo *info,
uintptr_t pointer) { uintptr_t pointer) {
__ubsan_handle_type_mismatch(info, pointer); __ubsan_type_mismatch_handler(info, pointer)();
__ubsan_unreachable();
} }
void __ubsan_handle_type_mismatch_v1( static __ubsan_die_f *__ubsan_type_mismatch_v1_handler(
struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) {
struct UbsanTypeMismatchInfo mm; struct UbsanTypeMismatchInfo mm;
mm.location = type_mismatch->location; mm.location = type_mismatch->location;
mm.type = type_mismatch->type; mm.type = type_mismatch->type;
mm.alignment = 1u << type_mismatch->log_alignment; mm.alignment = 1u << type_mismatch->log_alignment;
mm.type_check_kind = type_mismatch->type_check_kind; mm.type_check_kind = type_mismatch->type_check_kind;
__ubsan_handle_type_mismatch(&mm, pointer); return __ubsan_type_mismatch_handler(&mm, pointer);
}
void __ubsan_handle_type_mismatch_v1(
struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) {
__ubsan_type_mismatch_v1_handler(type_mismatch, pointer)();
__ubsan_unreachable();
} }
void __ubsan_handle_type_mismatch_v1_abort( void __ubsan_handle_type_mismatch_v1_abort(
struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) {
__ubsan_handle_type_mismatch_v1(type_mismatch, pointer); __ubsan_type_mismatch_v1_handler(type_mismatch, pointer)();
__ubsan_unreachable();
} }
void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) { void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) {
struct UbsanFloatCastOverflowData *data = struct UbsanFloatCastOverflowData *data =
(struct UbsanFloatCastOverflowData *)data_raw; (struct UbsanFloatCastOverflowData *)data_raw;
#if __GNUC__ + 0 >= 6 #if __GNUC__ + 0 >= 6
__ubsan_abort(&data->location, "float cast overflow"); __ubsan_abort(&data->location, "float cast overflow")();
__ubsan_unreachable();
#else #else
const struct UbsanSourceLocation kUnknownLocation = { const struct UbsanSourceLocation kUnknownLocation = {
"<unknown file>", "<unknown file>",
pushpop(0), pushpop(0),
pushpop(0), pushpop(0),
}; };
__ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow"); __ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow")();
__ubsan_unreachable();
#endif #endif
} }
@ -309,7 +365,8 @@ void __ubsan_handle_float_cast_overflow_abort(void *data_raw, void *from_raw) {
} }
void __ubsan_handle_add_overflow(const struct UbsanSourceLocation *loc) { void __ubsan_handle_add_overflow(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "add overflow"); __ubsan_abort(loc, "add overflow")();
__ubsan_unreachable();
} }
void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) {
@ -318,7 +375,8 @@ void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) {
void __ubsan_handle_alignment_assumption( void __ubsan_handle_alignment_assumption(
const struct UbsanSourceLocation *loc) { const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "alignment assumption"); __ubsan_abort(loc, "alignment assumption")();
__ubsan_unreachable();
} }
void __ubsan_handle_alignment_assumption_abort( void __ubsan_handle_alignment_assumption_abort(
@ -327,7 +385,8 @@ void __ubsan_handle_alignment_assumption_abort(
} }
void __ubsan_handle_builtin_unreachable(const struct UbsanSourceLocation *loc) { void __ubsan_handle_builtin_unreachable(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "builtin unreachable"); __ubsan_abort(loc, "builtin unreachable")();
__ubsan_unreachable();
} }
void __ubsan_handle_builtin_unreachable_abort( void __ubsan_handle_builtin_unreachable_abort(
@ -336,7 +395,8 @@ void __ubsan_handle_builtin_unreachable_abort(
} }
void __ubsan_handle_cfi_bad_type(const struct UbsanSourceLocation *loc) { void __ubsan_handle_cfi_bad_type(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "cfi bad type"); __ubsan_abort(loc, "cfi bad type")();
__ubsan_unreachable();
} }
void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) {
@ -344,7 +404,8 @@ void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) {
} }
void __ubsan_handle_cfi_check_fail(const struct UbsanSourceLocation *loc) { void __ubsan_handle_cfi_check_fail(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "cfi check fail"); __ubsan_abort(loc, "cfi check fail")();
__ubsan_unreachable();
} }
void __ubsan_handle_cfi_check_fail_abort( void __ubsan_handle_cfi_check_fail_abort(
@ -353,7 +414,8 @@ void __ubsan_handle_cfi_check_fail_abort(
} }
void __ubsan_handle_divrem_overflow(const struct UbsanSourceLocation *loc) { void __ubsan_handle_divrem_overflow(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "divrem overflow"); __ubsan_abort(loc, "divrem overflow")();
__ubsan_unreachable();
} }
void __ubsan_handle_divrem_overflow_abort( void __ubsan_handle_divrem_overflow_abort(
@ -363,7 +425,8 @@ void __ubsan_handle_divrem_overflow_abort(
void __ubsan_handle_dynamic_type_cache_miss( void __ubsan_handle_dynamic_type_cache_miss(
const struct UbsanSourceLocation *loc) { const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "dynamic type cache miss"); __ubsan_abort(loc, "dynamic type cache miss")();
__ubsan_unreachable();
} }
void __ubsan_handle_dynamic_type_cache_miss_abort( void __ubsan_handle_dynamic_type_cache_miss_abort(
@ -373,7 +436,8 @@ void __ubsan_handle_dynamic_type_cache_miss_abort(
void __ubsan_handle_function_type_mismatch( void __ubsan_handle_function_type_mismatch(
const struct UbsanSourceLocation *loc) { const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "function type mismatch"); __ubsan_abort(loc, "function type mismatch")();
__ubsan_unreachable();
} }
void __ubsan_handle_function_type_mismatch_abort( void __ubsan_handle_function_type_mismatch_abort(
@ -382,7 +446,8 @@ void __ubsan_handle_function_type_mismatch_abort(
} }
void __ubsan_handle_implicit_conversion(const struct UbsanSourceLocation *loc) { void __ubsan_handle_implicit_conversion(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "implicit conversion"); __ubsan_abort(loc, "implicit conversion")();
__ubsan_unreachable();
} }
void __ubsan_handle_implicit_conversion_abort( void __ubsan_handle_implicit_conversion_abort(
@ -391,7 +456,8 @@ void __ubsan_handle_implicit_conversion_abort(
} }
void __ubsan_handle_invalid_builtin(const struct UbsanSourceLocation *loc) { void __ubsan_handle_invalid_builtin(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "invalid builtin"); __ubsan_abort(loc, "invalid builtin")();
__ubsan_unreachable();
} }
void __ubsan_handle_invalid_builtin_abort( void __ubsan_handle_invalid_builtin_abort(
@ -400,7 +466,8 @@ void __ubsan_handle_invalid_builtin_abort(
} }
void __ubsan_handle_load_invalid_value(const struct UbsanSourceLocation *loc) { void __ubsan_handle_load_invalid_value(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "load invalid value (uninitialized? bool∌[01]?)"); __ubsan_abort(loc, "load invalid value (uninitialized? bool∌[01]?)")();
__ubsan_unreachable();
} }
void __ubsan_handle_load_invalid_value_abort( void __ubsan_handle_load_invalid_value_abort(
@ -409,7 +476,8 @@ void __ubsan_handle_load_invalid_value_abort(
} }
void __ubsan_handle_missing_return(const struct UbsanSourceLocation *loc) { void __ubsan_handle_missing_return(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "missing return"); __ubsan_abort(loc, "missing return")();
__ubsan_unreachable();
} }
void __ubsan_handle_missing_return_abort( void __ubsan_handle_missing_return_abort(
@ -418,7 +486,8 @@ void __ubsan_handle_missing_return_abort(
} }
void __ubsan_handle_mul_overflow(const struct UbsanSourceLocation *loc) { void __ubsan_handle_mul_overflow(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "multiply overflow"); __ubsan_abort(loc, "multiply overflow")();
__ubsan_unreachable();
} }
void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) {
@ -426,7 +495,8 @@ void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) {
} }
void __ubsan_handle_negate_overflow(const struct UbsanSourceLocation *loc) { void __ubsan_handle_negate_overflow(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "negate overflow"); __ubsan_abort(loc, "negate overflow")();
__ubsan_unreachable();
} }
void __ubsan_handle_negate_overflow_abort( void __ubsan_handle_negate_overflow_abort(
@ -435,24 +505,28 @@ void __ubsan_handle_negate_overflow_abort(
} }
void __ubsan_handle_nonnull_arg(const struct UbsanSourceLocation *loc) { void __ubsan_handle_nonnull_arg(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "nonnull argument"); __ubsan_warning(loc, "null argument here");
} }
void __ubsan_handle_nonnull_arg_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_nonnull_arg_abort(const struct UbsanSourceLocation *loc) {
__ubsan_handle_nonnull_arg(loc); __ubsan_abort(loc, "nonnull argument")();
__ubsan_unreachable();
} }
void __ubsan_handle_nonnull_return_v1(const struct UbsanSourceLocation *loc) { void __ubsan_handle_nonnull_return_v1(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "non-null return (v1)"); __ubsan_abort(loc, "non-null return (v1)")();
__ubsan_unreachable();
} }
void __ubsan_handle_nonnull_return_v1_abort( void __ubsan_handle_nonnull_return_v1_abort(
const struct UbsanSourceLocation *loc) { const struct UbsanSourceLocation *loc) {
__ubsan_handle_nonnull_return_v1(loc); __ubsan_abort(loc, "non-null return (v1)")();
__ubsan_unreachable();
} }
void __ubsan_handle_nullability_arg(const struct UbsanSourceLocation *loc) { void __ubsan_handle_nullability_arg(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "nullability arg"); __ubsan_abort(loc, "nullability arg")();
__ubsan_unreachable();
} }
void __ubsan_handle_nullability_arg_abort( void __ubsan_handle_nullability_arg_abort(
@ -462,7 +536,8 @@ void __ubsan_handle_nullability_arg_abort(
void __ubsan_handle_nullability_return_v1( void __ubsan_handle_nullability_return_v1(
const struct UbsanSourceLocation *loc) { const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "nullability return (v1)"); __ubsan_abort(loc, "nullability return (v1)")();
__ubsan_unreachable();
} }
void __ubsan_handle_nullability_return_v1_abort( void __ubsan_handle_nullability_return_v1_abort(
@ -471,7 +546,8 @@ void __ubsan_handle_nullability_return_v1_abort(
} }
void __ubsan_handle_pointer_overflow(const struct UbsanSourceLocation *loc) { void __ubsan_handle_pointer_overflow(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "pointer overflow"); __ubsan_abort(loc, "pointer overflow")();
__ubsan_unreachable();
} }
void __ubsan_handle_pointer_overflow_abort( void __ubsan_handle_pointer_overflow_abort(
@ -480,7 +556,8 @@ void __ubsan_handle_pointer_overflow_abort(
} }
void __ubsan_handle_sub_overflow(const struct UbsanSourceLocation *loc) { void __ubsan_handle_sub_overflow(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "subtract overflow"); __ubsan_abort(loc, "subtract overflow")();
__ubsan_unreachable();
} }
void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) {
@ -489,7 +566,8 @@ void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) {
void __ubsan_handle_vla_bound_not_positive( void __ubsan_handle_vla_bound_not_positive(
const struct UbsanSourceLocation *loc) { const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "vla bound not positive"); __ubsan_abort(loc, "vla bound not positive")();
__ubsan_unreachable();
} }
void __ubsan_handle_vla_bound_not_positive_abort( void __ubsan_handle_vla_bound_not_positive_abort(
@ -498,7 +576,8 @@ void __ubsan_handle_vla_bound_not_positive_abort(
} }
void __ubsan_handle_nonnull_return(const struct UbsanSourceLocation *loc) { void __ubsan_handle_nonnull_return(const struct UbsanSourceLocation *loc) {
__ubsan_abort(loc, "nonnull return"); __ubsan_abort(loc, "nonnull return")();
__ubsan_unreachable();
} }
void __ubsan_handle_nonnull_return_abort( void __ubsan_handle_nonnull_return_abort(

View file

@ -42,7 +42,7 @@
* possible UX for debugging your app, for varying levels of available * possible UX for debugging your app, for varying levels of available
* information, on most of the various platforms. * information, on most of the various platforms.
* *
* Before calling this function, consider placing showcrashreports() in * Before calling this function, consider placing ShowCrashReports() in
* your main function and calling DebugBreak() wherever you want; it's * your main function and calling DebugBreak() wherever you want; it's
* safer. Also note the "GDB" environment variable can be set to empty * safer. Also note the "GDB" environment variable can be set to empty
* string, as a fail-safe for disabling this behavior. * string, as a fail-safe for disabling this behavior.

View file

@ -79,7 +79,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
* DWARF is a weak standard. Platforms that use LLVM or old GNU * DWARF is a weak standard. Platforms that use LLVM or old GNU
* usually can't be counted upon to print backtraces correctly. * usually can't be counted upon to print backtraces correctly.
*/ */
if (!IsLinux() /* && !IsWindows() */) { if (!IsLinux() && !IsWindows()) {
ShowHint("won't print addr2line backtrace because probably llvm"); ShowHint("won't print addr2line backtrace because probably llvm");
return -1; return -1;
} }

View file

@ -231,7 +231,7 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
? "Stack Overflow" ? "Stack Overflow"
: GetSiCodeName(sig, si->si_code), : GetSiCodeName(sig, si->si_code),
host, __getpid(), program_invocation_name, names.sysname, host, __getpid(), program_invocation_name, names.sysname,
names.nodename, names.release, names.version); names.version, names.nodename, names.release);
if (ctx) { if (ctx) {
kprintf("%n"); kprintf("%n");
ShowFunctionCalls(ctx); ShowFunctionCalls(ctx);

View file

@ -51,7 +51,7 @@ textexit static void __onkill(int sig, struct siginfo *si,
/** /**
* Installs default handlers for friendly kill signals. * Installs default handlers for friendly kill signals.
* @see showcrashreports() * @see ShowCrashReports()
*/ */
void callexitontermination(sigset_t *opt_out_exitsigs) { void callexitontermination(sigset_t *opt_out_exitsigs) {
struct sigaction sa; struct sigaction sa;

View file

@ -195,7 +195,7 @@
.endm .endm
.macro .poison name:req kind:req .macro .poison name:req kind:req
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
2323: .quad 0 2323: .quad 0
.init.start 304,"_init_\name\()_poison_\@" .init.start 304,"_init_\name\()_poison_\@"
push %rdi push %rdi
@ -211,13 +211,13 @@
.endm .endm
.macro .underrun .macro .underrun
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
.poison __BASE_FILE__, kAsanGlobalUnderrun .poison __BASE_FILE__, kAsanGlobalUnderrun
#endif #endif
.endm .endm
.macro .overrun .macro .overrun
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
.poison __BASE_FILE__, kAsanGlobalUnderrun .poison __BASE_FILE__, kAsanGlobalUnderrun
#endif #endif
.endm .endm

View file

@ -16,45 +16,30 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h"
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/ntspawn.h" #include "libc/calls/ntspawn.h"
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/alloca.h" #include "libc/mem/alloca.h"
#include "libc/nexgen32e/nt2sysv.h" #include "libc/nexgen32e/nt2sysv.h"
#include "libc/nt/dll.h"
#include "libc/nt/enum/exceptionhandleractions.h"
#include "libc/nt/enum/filemapflags.h" #include "libc/nt/enum/filemapflags.h"
#include "libc/nt/enum/memflags.h"
#include "libc/nt/enum/pageflags.h" #include "libc/nt/enum/pageflags.h"
#include "libc/nt/enum/startf.h" #include "libc/nt/enum/startf.h"
#include "libc/nt/enum/wt.h"
#include "libc/nt/files.h"
#include "libc/nt/ipc.h" #include "libc/nt/ipc.h"
#include "libc/nt/memory.h" #include "libc/nt/memory.h"
#include "libc/nt/process.h" #include "libc/nt/process.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/nt/signals.h" #include "libc/nt/signals.h"
#include "libc/nt/struct/context.h"
#include "libc/nt/struct/ntexceptionpointers.h" #include "libc/nt/struct/ntexceptionpointers.h"
#include "libc/nt/synchronization.h"
#include "libc/nt/thread.h"
#include "libc/runtime/directmap.internal.h" #include "libc/runtime/directmap.internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/map.h" #include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
extern int __pid; extern int __pid;
extern unsigned long long __kbirth; extern unsigned long long __kbirth;

View file

@ -102,15 +102,15 @@ textstartup void __printargs(int argc, char **argv, char **envp,
} }
} }
STRACE("SPECIALS"); STRACE("SPECIALS");
STRACE(" ☼ %21s = %#s", "kTmpPath", kTmpPath); STRACE(" ☼ %30s = %#s", "kTmpPath", kTmpPath);
STRACE(" ☼ %21s = %#s", "kNtSystemDirectory", kNtSystemDirectory); STRACE(" ☼ %30s = %#s", "kNtSystemDirectory", kNtSystemDirectory);
STRACE(" ☼ %21s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory); STRACE(" ☼ %30s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory);
STRACE(" ☼ %21s = %#s", "program_executable_name", program_executable_name); STRACE(" ☼ %30s = %#s", "program_executable_name", program_executable_name);
STRACE(" ☼ %21s = %#s", "GetInterpreterExecutableName()", STRACE(" ☼ %30s = %#s", "GetInterpreterExecutableName()",
GetInterpreterExecutableName(path, sizeof(path))); GetInterpreterExecutableName(path, sizeof(path)));
STRACE(" ☼ %21s = %p", "RSP", __builtin_frame_address(0)); STRACE(" ☼ %30s = %p", "RSP", __builtin_frame_address(0));
STRACE(" ☼ %21s = %p", "GetStackAddr()", GetStackAddr(0)); STRACE(" ☼ %30s = %p", "GetStackAddr()", GetStackAddr(0));
STRACE(" ☼ %21s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0)); STRACE(" ☼ %30s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0));
STRACE(" ☼ %21s = %p", "GetStackSize()", GetStackSize()); STRACE(" ☼ %30s = %p", "GetStackSize()", GetStackSize());
#endif #endif
} }

View file

@ -36,7 +36,7 @@
// @returnstwice // @returnstwice
// @vforksafe // @vforksafe
vfork: vfork:
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
jmp fork # TODO: asan and vfork don't mix? jmp fork # TODO: asan and vfork don't mix?
.endfn vfork,globl .endfn vfork,globl
#else #else
@ -98,4 +98,4 @@ vfork.bsd:
.previous .previous
#endif /* DEBUGSYS */ #endif /* DEBUGSYS */
#endif /* __FSANITIZE_ADDRESS__ */ #endif /* __SANITIZE_ADDRESS__ */

View file

@ -59,7 +59,11 @@ ssize_t appendd(char **b, const void *s, size_t l) {
return -1; return -1;
} }
} }
if (l) {
*(char *)mempcpy(p + z.i, s, l) = 0; *(char *)mempcpy(p + z.i, s, l) = 0;
} else {
p[z.i] = 0;
}
z.i += l; z.i += l;
if (!IsTiny() && W == 8) z.i |= (size_t)APPEND_COOKIE << 48; if (!IsTiny() && W == 8) z.i |= (size_t)APPEND_COOKIE << 48;
*(size_t *)(p + z.n - W) = z.i; *(size_t *)(p + z.n - W) = z.i;

View file

@ -53,7 +53,7 @@ size_t fread(void *buf, size_t stride, size_t count, FILE *f) {
p = buf; p = buf;
n = stride * count; n = stride * count;
m = f->end - f->beg; m = f->end - f->beg;
memcpy(p, f->buf + f->beg, MIN(n, m)); if (MIN(n, m)) memcpy(p, f->buf + f->beg, MIN(n, m));
if (n < m) { if (n < m) {
f->beg += n; f->beg += n;
return count; return count;

View file

@ -35,6 +35,9 @@ uint32_t crc32c(uint32_t init, const void *data, size_t size) {
pe = p + size; pe = p + size;
h = init ^ 0xffffffff; h = init ^ 0xffffffff;
if (X86_HAVE(SSE4_2)) { if (X86_HAVE(SSE4_2)) {
while (p < pe && ((intptr_t)p & 7)) {
h = h >> 8 ^ kCrc32cTab[(h & 0xff) ^ *p++];
}
for (; p + 8 <= pe; p += 8) { for (; p + 8 <= pe; p += 8) {
asm("crc32q\t%1,%0" : "+r"(h) : "rm"(*(const uint64_t *)p)); asm("crc32q\t%1,%0" : "+r"(h) : "rm"(*(const uint64_t *)p));
} }

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
TEST(getenv, test) { TEST(getenv, test) {
@ -26,3 +27,8 @@ TEST(getenv, test) {
unsetenv("X"); unsetenv("X");
EXPECT_EQ(NULL, getenv("X")); EXPECT_EQ(NULL, getenv("X"));
} }
BENCH(getenv, bench) {
char *getenv_(const char *) asm("getenv");
EZBENCH2("getenv(TZ)", donothing, getenv_("TZ"));
}

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/bits/bits.h" #include "libc/bits/bits.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
@ -230,6 +231,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) {
} }
TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) { TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) {
if (IsWindows()) return; // TODO(jart): fixme
int n; int n;
ASSERT_EQ(0, errno); ASSERT_EQ(0, errno);
EXPECT_SYS(0, 3, dup(2)); EXPECT_SYS(0, 3, dup(2));

View file

@ -16,11 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/libfatal.internal.h" #include "libc/log/libfatal.internal.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
@ -280,6 +282,10 @@ TEST(ShowCrashReports, testStackOverrunCrash) {
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
if (strstr(output, "'int' index 10 into 'char [10]' out of bounds")) {
// ubsan nailed it
} else {
// asan nailed it
if (!strstr(output, "☺☻♥♦♣♠•◘○")) { if (!strstr(output, "☺☻♥♦♣♠•◘○")) {
fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
@ -290,6 +296,7 @@ TEST(ShowCrashReports, testStackOverrunCrash) {
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
}
free(output); free(output);
} }
@ -376,7 +383,7 @@ TEST(ShowCrashReports, testDivideByZero) {
} }
ASSERT_NE(-1, wait(&ws)); ASSERT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws)); EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(128 + SIGFPE, WEXITSTATUS(ws)); assert(128 + SIGFPE == WEXITSTATUS(ws) || 77 == WEXITSTATUS(ws));
/* NULL is stopgap until we can copy symbol tablces into binary */ /* NULL is stopgap until we can copy symbol tablces into binary */
#ifdef __FNO_OMIT_FRAME_POINTER__ #ifdef __FNO_OMIT_FRAME_POINTER__
if (!OutputHasSymbol(output, "FpuCrash")) { if (!OutputHasSymbol(output, "FpuCrash")) {
@ -385,6 +392,10 @@ TEST(ShowCrashReports, testDivideByZero) {
__die(); __die();
} }
#endif #endif
if (strstr(output, "divrem overflow")) {
// UBSAN handled it
} else {
// ShowCrashReports() handled it
if (!strstr(output, gc(xasprintf("%d", pid)))) { if (!strstr(output, gc(xasprintf("%d", pid)))) {
fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n", fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
@ -410,10 +421,24 @@ TEST(ShowCrashReports, testDivideByZero) {
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
}
free(output); free(output);
} }
// clang-format off // clang-format off
//
// test/libc/log/backtrace_test.c:59: ubsan error: 'int' index 10 into 'char [10]' out of bounds
// 0x000000000040a352: __die at libc/log/die.c:40
// 0x0000000000489bc8: __ubsan_abort at libc/intrin/ubsan.c:196
// 0x0000000000489e1c: __ubsan_handle_out_of_bounds at libc/intrin/ubsan.c:242
// 0x0000000000423666: BssOverrunCrash at test/libc/log/backtrace_test.c:59
// 0x0000000000423e0a: SetUp at test/libc/log/backtrace_test.c:115
// 0x000000000049350b: testlib_runtestcases at libc/testlib/testrunner.c:98
// 0x000000000048ab50: testlib_runalltests at libc/testlib/runner.c:37
// 0x00000000004028d0: main at libc/testlib/testmain.c:94
// 0x0000000000403977: cosmo at libc/runtime/cosmo.S:69
// 0x00000000004021ae: _start at libc/crt/crt.S:78
//
// asan error: global redzone 1-byte store at 0x00000048cf2a shadow 0x0000800899e5 // asan error: global redzone 1-byte store at 0x00000048cf2a shadow 0x0000800899e5
// x // x
// ........................................OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO // ........................................OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
@ -444,7 +469,9 @@ TEST(ShowCrashReports, testDivideByZero) {
// 0x00000000004026db: main at libc/testlib/testmain.c:155 // 0x00000000004026db: main at libc/testlib/testmain.c:155
// 0x000000000040323f: cosmo at libc/runtime/cosmo.S:64 // 0x000000000040323f: cosmo at libc/runtime/cosmo.S:64
// 0x000000000040219b: _start at libc/crt/crt.S:67 // 0x000000000040219b: _start at libc/crt/crt.S:67
//
// clang-format on // clang-format on
TEST(ShowCrashReports, testBssOverrunCrash) { TEST(ShowCrashReports, testBssOverrunCrash) {
if (!IsAsan()) return; if (!IsAsan()) return;
size_t got; size_t got;
@ -486,7 +513,8 @@ TEST(ShowCrashReports, testBssOverrunCrash) {
__die(); __die();
} }
#endif #endif
if (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone")) { if (!strstr(output, "'int' index 10 into 'char [10]' out of bounds") &&
(!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone"))) {
fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
@ -556,7 +584,7 @@ TEST(ShowCrashReports, testNpeCrash) {
EXPECT_TRUE(WIFEXITED(ws)); EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(77, WEXITSTATUS(ws)); EXPECT_EQ(77, WEXITSTATUS(ws));
/* NULL is stopgap until we can copy symbol tables into binary */ /* NULL is stopgap until we can copy symbol tables into binary */
if (!strstr(output, "null pointer dereference")) { if (!strstr(output, "null pointer")) {
fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
@ -568,11 +596,16 @@ TEST(ShowCrashReports, testNpeCrash) {
__die(); __die();
} }
#endif #endif
if (strstr(output, "null pointer access")) {
// ubsan nailed it
} else {
// asan nailed it
if (!strstr(output, "∅∅∅∅")) { if (!strstr(output, "∅∅∅∅")) {
fprintf(stderr, "ERROR: crash report didn't have shadow diagram\n%s\n", fprintf(stderr, "ERROR: crash report didn't have shadow diagram\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
} }
}
free(output); free(output);
} }
@ -617,7 +650,8 @@ TEST(ShowCrashReports, testDataOverrunCrash) {
__die(); __die();
} }
#endif #endif
if (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone")) { if (!strstr(output, "'int' index 10 into 'char [10]' out of bounds") &&
(!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone"))) {
fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();
@ -663,8 +697,7 @@ TEST(ShowCrashReports, testNpeCrashAfterFinalize) {
EXPECT_TRUE(WIFEXITED(ws)); EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(IsAsan() ? 77 : 128 + SIGSEGV, WEXITSTATUS(ws)); EXPECT_EQ(IsAsan() ? 77 : 128 + SIGSEGV, WEXITSTATUS(ws));
/* NULL is stopgap until we can copy symbol tables into binary */ /* NULL is stopgap until we can copy symbol tables into binary */
if (!strstr(output, IsAsan() ? "null pointer dereference" if (!strstr(output, IsAsan() ? "null pointer" : "Uncaught SIGSEGV (SEGV_")) {
: "Uncaught SIGSEGV (SEGV_MAPERR)")) {
fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n",
gc(IndentLines(output, -1, 0, 4))); gc(IndentLines(output, -1, 0, 4)));
__die(); __die();

View file

@ -2,7 +2,7 @@ int main(int argc, char *argv[]) {
int rc; int rc;
char *s; char *s;
FILE *f; FILE *f;
showcrashreports(); ShowCrashReports();
s = strdup(argv[0]); s = strdup(argv[0]);
s[0] = 'Z'; s[0] = 'Z';
f = fopen("/dev/null", "w"); f = fopen("/dev/null", "w");

View file

@ -1255,7 +1255,7 @@ static void EmitData(struct As *a, const void *p, uint128_t n) {
struct Slice *s; struct Slice *s;
s = &a->sections.p[a->section].binary; s = &a->sections.p[a->section].binary;
s->p = realloc(s->p, s->n + n); s->p = realloc(s->p, s->n + n);
memcpy(s->p + s->n, p, n); if (n) memcpy(s->p + s->n, p, n);
s->n += n; s->n += n;
} }
@ -3910,8 +3910,10 @@ static void Objectify(struct As *a, int path) {
Fail(a, "unsupported relocation type"); Fail(a, "unsupported relocation type");
} }
} }
if (a->sections.p[i].binary.n) {
memcpy(elfwriter_reserve(elf, a->sections.p[i].binary.n), memcpy(elfwriter_reserve(elf, a->sections.p[i].binary.n),
a->sections.p[i].binary.p, a->sections.p[i].binary.n); a->sections.p[i].binary.p, a->sections.p[i].binary.n);
}
elfwriter_commit(elf, a->sections.p[i].binary.n); elfwriter_commit(elf, a->sections.p[i].binary.n);
elfwriter_finishsection(elf); elfwriter_finishsection(elf);
} }

View file

@ -19,7 +19,7 @@
#include "third_party/chibicc/chibicc.h" #include "third_party/chibicc/chibicc.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
Assembler(argc, argv); Assembler(argc, argv);
return 0; return 0;
} }

View file

@ -119,28 +119,28 @@ o/$(MODE)/third_party/infozip/zip.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIP_COM_OBJS) \ $(THIRD_PARTY_ZIP_COM_OBJS) \
$(CRT) \ $(CRT) \
$(APE) $(APE_NO_MODIFY_SELF)
@$(APELINK) @$(APELINK)
o/$(MODE)/third_party/infozip/zipsplit.com.dbg: \ o/$(MODE)/third_party/infozip/zipsplit.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIPSPLIT_OBJS) \ $(THIRD_PARTY_ZIPSPLIT_OBJS) \
$(CRT) \ $(CRT) \
$(APE) $(APE_NO_MODIFY_SELF)
@$(APELINK) @$(APELINK)
o/$(MODE)/third_party/infozip/zipnote.com.dbg: \ o/$(MODE)/third_party/infozip/zipnote.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIPNOTE_OBJS) \ $(THIRD_PARTY_ZIPNOTE_OBJS) \
$(CRT) \ $(CRT) \
$(APE) $(APE_NO_MODIFY_SELF)
@$(APELINK) @$(APELINK)
o/$(MODE)/third_party/infozip/zipcloak.com.dbg: \ o/$(MODE)/third_party/infozip/zipcloak.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIPCLOAK_OBJS) \ $(THIRD_PARTY_ZIPCLOAK_OBJS) \
$(CRT) \ $(CRT) \
$(APE) $(APE_NO_MODIFY_SELF)
@$(APELINK) @$(APELINK)
.PHONY: o/$(MODE)/third_party/infozip .PHONY: o/$(MODE)/third_party/infozip

View file

@ -2195,7 +2195,7 @@ char **argv; /* command line tokens */
char **args = NULL; /* could be wide argv */ char **args = NULL; /* could be wide argv */
if (!IsTiny()) showcrashreports(); if (!IsTiny()) ShowCrashReports();
#ifdef THEOS #ifdef THEOS
/* the argument expansion from the standard library is full of bugs */ /* the argument expansion from the standard library is full of bugs */

View file

@ -872,7 +872,7 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
const char *f = fname ? fname : _("Current time"); const char *f = fname ? fname : _("Current time");
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX; ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
file_timestamp_sprintf (buf, ts); file_timestamp_sprintf (buf, sizeof(buf), ts);
OSS (error, NILF, OSS (error, NILF,
_("%s: Timestamp out of range; substituting %s"), f, buf); _("%s: Timestamp out of range; substituting %s"), f, buf);
} }
@ -933,27 +933,37 @@ file_timestamp_now (int *resolution)
/* Place into the buffer P a printable representation of the file /* Place into the buffer P a printable representation of the file
timestamp TS. */ timestamp TS. */
void void
file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts) file_timestamp_sprintf (char *p, int n, FILE_TIMESTAMP ts)
{ {
/*
* [jart] patch weakness upstream because buffer can probably overflow
* if integer timestamp is irreguular
*/
int m;
time_t t = FILE_TIMESTAMP_S (ts); time_t t = FILE_TIMESTAMP_S (ts);
struct tm *tm = localtime (&t); struct tm *tm = localtime (&t);
if (tm) if (tm)
sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d", snprintf (p, n, "%04d-%02d-%02d %02d:%02d:%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (t < 0) else if (t < 0)
sprintf (p, "%ld", (long) t); snprintf (p, n, "%ld", (long) t);
else else
sprintf (p, "%lu", (unsigned long) t); snprintf (p, n, "%lu", (unsigned long) t);
p += strlen (p); m = strlen (p);
p += m;
n -= m;
if (n <= 0) return;
/* Append nanoseconds as a fraction, but remove trailing zeros. We don't /* Append nanoseconds as a fraction, but remove trailing zeros. We don't
know the actual timestamp resolution, since clock_getres applies only to know the actual timestamp resolution, since clock_getres applies only to
local times, whereas this timestamp might come from a remote filesystem. local times, whereas this timestamp might come from a remote filesystem.
So removing trailing zeros is the best guess that we can do. */ So removing trailing zeros is the best guess that we can do. */
sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts)); snprintf (p, n, ".%09d", FILE_TIMESTAMP_NS (ts));
p += strlen (p) - 1; m = strlen (p) - 1;
p += m;
n += m;
while (*p == '0') while (*p == '0')
p--; p--;
p += *p != '.'; p += *p != '.';
@ -1052,7 +1062,7 @@ print_file (const void *item)
else else
{ {
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
file_timestamp_sprintf (buf, f->last_mtime); file_timestamp_sprintf (buf, sizeof(buf), f->last_mtime);
printf (_("# Last modified %s\n"), buf); printf (_("# Last modified %s\n"), buf);
} }
puts (f->updated puts (f->updated

View file

@ -164,14 +164,14 @@ int stemlen_compare (const void *v1, const void *v2);
add 4 to allow for any 4-digit epoch year (e.g. 1970); add 4 to allow for any 4-digit epoch year (e.g. 1970);
add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN". */ add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN". */
#define FLOOR_LOG2_SECONDS_PER_YEAR 24 #define FLOOR_LOG2_SECONDS_PER_YEAR 24
#define FILE_TIMESTAMP_PRINT_LEN_BOUND \ #define FILE_TIMESTAMP_PRINT_LEN_BOUND /* 62 */ \
(((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \ (((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \
* 302 / 1000) \ * 302 / 1000) \
+ 1 + 1 + 4 + 25) + 1 + 1 + 4 + 25)
FILE_TIMESTAMP file_timestamp_cons (char const *, time_t, long int); FILE_TIMESTAMP file_timestamp_cons (char const *, time_t, long int);
FILE_TIMESTAMP file_timestamp_now (int *); FILE_TIMESTAMP file_timestamp_now (int *);
void file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts); void file_timestamp_sprintf (char *, int, FILE_TIMESTAMP );
/* Return the mtime of file F (a struct file *), caching it. /* Return the mtime of file F (a struct file *), caching it.
The value is NONEXISTENT_MTIME if the file does not exist. */ The value is NONEXISTENT_MTIME if the file does not exist. */

View file

@ -15,6 +15,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
#include "libc/intrin/kprintf.h"
#include "libc/rand/rand.h" #include "libc/rand/rand.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "third_party/mbedtls/common.h" #include "third_party/mbedtls/common.h"
@ -763,6 +764,10 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
const unsigned char *input, const unsigned char *input,
unsigned char *output ) unsigned char *output )
{ {
RSA_VALIDATE_RET( ctx );
RSA_VALIDATE_RET( input );
RSA_VALIDATE_RET( output );
int ret = MBEDTLS_ERR_THIS_CORRUPTION; int ret = MBEDTLS_ERR_THIS_CORRUPTION;
size_t olen; size_t olen;
@ -798,10 +803,6 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
* checked result; should be the same in the end. */ * checked result; should be the same in the end. */
mbedtls_mpi I, C; mbedtls_mpi I, C;
RSA_VALIDATE_RET( ctx );
RSA_VALIDATE_RET( input );
RSA_VALIDATE_RET( output );
if( rsa_check_context( ctx, 1 /* private key checks */, if( rsa_check_context( ctx, 1 /* private key checks */,
f_rng != NULL /* blinding y/n */ ) != 0 ) f_rng != NULL /* blinding y/n */ ) != 0 )
{ {

View file

@ -87,7 +87,7 @@ int mbedtls_test_platform_setup(void) {
char *p; char *p;
int ret = 0; int ret = 0;
static char mybuf[2][BUFSIZ]; static char mybuf[2][BUFSIZ];
showcrashreports(); ShowCrashReports();
setvbuf(stdout, mybuf[0], _IOLBF, BUFSIZ); setvbuf(stdout, mybuf[0], _IOLBF, BUFSIZ);
setvbuf(stderr, mybuf[1], _IOLBF, BUFSIZ); setvbuf(stderr, mybuf[1], _IOLBF, BUFSIZ);
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
@ -794,7 +794,8 @@ static int convert_params(size_t cnt, char **params, int *int_params_store) {
* *
* \return 0 for success else 1 * \return 0 for success else 1
*/ */
static dontinline int test_snprintf(size_t n, const char *ref_buf, int ref_ret) { static dontinline int test_snprintf(size_t n, const char *ref_buf,
int ref_ret) {
int ret; int ret;
char buf[10] = "xxxxxxxxx"; char buf[10] = "xxxxxxxxx";
const char ref[10] = "xxxxxxxxx"; const char ref[10] = "xxxxxxxxx";

View file

@ -2410,9 +2410,11 @@ _PyObject_FastCall_Prepend(PyObject *callable,
/* use borrowed references */ /* use borrowed references */
args2[0] = obj; args2[0] = obj;
if (nargs > 1) {
memcpy(&args2[1], memcpy(&args2[1],
args, args,
(nargs - 1)* sizeof(PyObject *)); (nargs - 1)* sizeof(PyObject *));
}
result = _PyObject_FastCall(callable, args2, nargs); result = _PyObject_FastCall(callable, args2, nargs);
if (args2 != small_stack) { if (args2 != small_stack) {

View file

@ -97,7 +97,7 @@ static inline void *
_PyMem_RawMalloc(void *ctx, size_t size) _PyMem_RawMalloc(void *ctx, size_t size)
{ {
#ifdef __COSMOPOLITAN__ #ifdef __COSMOPOLITAN__
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
return __asan_memalign(16, size); return __asan_memalign(16, size);
#else #else
return dlmalloc(size); return dlmalloc(size);
@ -117,7 +117,7 @@ static inline void *
_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) _PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize)
{ {
#ifdef __COSMOPOLITAN__ #ifdef __COSMOPOLITAN__
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
return __asan_calloc(nelem, elsize); return __asan_calloc(nelem, elsize);
#else #else
return dlcalloc(nelem, elsize); return dlcalloc(nelem, elsize);
@ -141,7 +141,7 @@ _PyMem_RawRealloc(void *ctx, void *ptr, size_t size)
if (size == 0) if (size == 0)
size = 1; size = 1;
#ifdef __COSMOPOLITAN__ #ifdef __COSMOPOLITAN__
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
return __asan_realloc(ptr, size); return __asan_realloc(ptr, size);
#else #else
return dlrealloc(ptr, size); return dlrealloc(ptr, size);
@ -155,7 +155,7 @@ static inline void
_PyMem_RawFree(void *ctx, void *ptr) _PyMem_RawFree(void *ctx, void *ptr)
{ {
#ifdef __COSMOPOLITAN__ #ifdef __COSMOPOLITAN__
#ifdef __FSANITIZE_ADDRESS__ #ifdef __SANITIZE_ADDRESS__
__asan_free(ptr); __asan_free(ptr);
#else #else
dlfree(ptr); dlfree(ptr);
@ -2029,11 +2029,13 @@ int
static void static void
_PyMem_DebugRawFree(void *ctx, void *p) _PyMem_DebugRawFree(void *ctx, void *p)
{ {
debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; debug_alloc_api_t *api;
uint8_t *q = (uint8_t *)p - 2*SST; /* address returned from malloc */ uint8_t *q;
size_t nbytes; size_t nbytes;
if (p == NULL) if (p == NULL)
return; return;
api = (debug_alloc_api_t *)ctx;
q = (uint8_t *)p - 2*SST; /* address returned from malloc */
_PyMem_DebugCheckAddress(api->api_id, p); _PyMem_DebugCheckAddress(api->api_id, p);
nbytes = read_size_t(q); nbytes = read_size_t(q);
nbytes += 4*SST; nbytes += 4*SST;

View file

@ -1501,6 +1501,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
} while (c == ' ' || c == '\t' || c == '\014'); } while (c == ' ' || c == '\t' || c == '\014');
/* Set start of current token */ /* Set start of current token */
if (tok->cur)
tok->start = tok->cur - 1; tok->start = tok->cur - 1;
/* Skip comment */ /* Skip comment */

View file

@ -17,7 +17,7 @@
#include "third_party/python/Include/pystate.h" #include "third_party/python/Include/pystate.h"
/* clang-format off */ /* clang-format off */
#if defined(__FSANITIZE_ADDRESS__) || defined(__FSANITIZE_UNDEFINED__) #if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_UNDEFINED__)
STATIC_YOINK("__die"); /* to guarantee backtraces */ STATIC_YOINK("__die"); /* to guarantee backtraces */
#endif #endif

View file

@ -505,7 +505,7 @@
/* #undef WITH_LIBINTL */ /* #undef WITH_LIBINTL */
/* Define if you want to compile in Python-specific mallocs */ /* Define if you want to compile in Python-specific mallocs */
#ifndef __FSANITIZE_ADDRESS__ #ifndef __SANITIZE_ADDRESS__
#define WITH_PYMALLOC 0 #define WITH_PYMALLOC 0
#endif #endif
@ -580,7 +580,7 @@
/* #define FAST_LOOPS 1 /\* froot loops *\/ */ /* #define FAST_LOOPS 1 /\* froot loops *\/ */
#ifdef __FSANITIZE_UNDEFINED__ #ifdef __SANITIZE_UNDEFINED__
#define HAVE_ALIGNED_REQUIRED 1 #define HAVE_ALIGNED_REQUIRED 1
#endif #endif

View file

@ -297,7 +297,7 @@ int bf_set(bf_t *r, const bf_t *a)
} }
r->sign = a->sign; r->sign = a->sign;
r->expn = a->expn; r->expn = a->expn;
memcpy(r->tab, a->tab, a->len * sizeof(limb_t)); if (a->len) memcpy(r->tab, a->tab, a->len * sizeof(limb_t));
return 0; return 0;
} }

View file

@ -24,6 +24,7 @@
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/calls/weirdtypes.h" #include "libc/calls/weirdtypes.h"
#include "libc/dce.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
@ -328,6 +329,10 @@ int main(int argc, char **argv)
#endif #endif
size_t stack_size = 0; size_t stack_size = 0;
#if IsModeDbg()
ShowCrashReports();
#endif
#ifdef CONFIG_BIGNUM #ifdef CONFIG_BIGNUM
/* load jscalc runtime if invoked as 'qjscalc' */ /* load jscalc runtime if invoked as 'qjscalc' */
{ {

View file

@ -488,6 +488,11 @@ int main(int argc, char **argv)
BOOL bignum_ext = FALSE; BOOL bignum_ext = FALSE;
#endif #endif
namelist_t dynamic_module_list; namelist_t dynamic_module_list;
#if IsModeDbg()
ShowCrashReports();
#endif
if (argc == 2 && !strcmp(argv[1], "-n")) return 0; if (argc == 2 && !strcmp(argv[1], "-n")) return 0;
out_filename = NULL; out_filename = NULL;
output_type = OUTPUT_EXECUTABLE; output_type = OUTPUT_EXECUTABLE;

View file

@ -10926,7 +10926,7 @@ typedef struct CodeContext {
#define M2(op1, op2) ((op1) | ((op2) << 8)) #define M2(op1, op2) ((op1) | ((op2) << 8))
#define M3(op1, op2, op3) ((op1) | ((op2) << 8) | ((op3) << 16)) #define M3(op1, op2, op3) ((op1) | ((op2) << 8) | ((op3) << 16))
#define M4(op1, op2, op3, op4) ((op1) | ((op2) << 8) | ((op3) << 16) | ((op4) << 24)) #define M4(op1, op2, op3, op4) ((op1) | ((op2) << 8) | ((op3) << 16) | ((uint32_t)(op4) << 24))
static BOOL code_match(CodeContext *s, int pos, ...) static BOOL code_match(CodeContext *s, int pos, ...)
{ {

View file

@ -1950,7 +1950,7 @@ int main(int argc, char **argv)
BOOL is_test262_harness = FALSE; BOOL is_test262_harness = FALSE;
BOOL is_module = FALSE; BOOL is_module = FALSE;
showcrashreports(); ShowCrashReports();
#if !defined(_WIN32) #if !defined(_WIN32)
/* Date tests assume California local time */ /* Date tests assume California local time */

View file

@ -174,8 +174,8 @@ o/$(MODE)/%.shell.o: %.c o/$(MODE)/%.o
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $< @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
o/$(MODE)/third_party/sqlite3/shell.shell.o: QUOTA = -M512m -C16 o/$(MODE)/third_party/sqlite3/shell.shell.o: QUOTA = -M512m -C16
o/$(MODE)/third_party/sqlite3/vdbe.o: QUOTA = -M512m o/$(MODE)/third_party/sqlite3/vdbe.o: QUOTA = -M1024m
o/$(MODE)/third_party/sqlite3/vdbe.shell.o: QUOTA = -M512m o/$(MODE)/third_party/sqlite3/vdbe.shell.o: QUOTA = -M1024m
o/$(MODE)/third_party/sqlite3/fts5.o: QUOTA = -M512m -C16 o/$(MODE)/third_party/sqlite3/fts5.o: QUOTA = -M512m -C16
o/$(MODE)/third_party/sqlite3/fts5.shell.o: QUOTA = -M512m -C16 o/$(MODE)/third_party/sqlite3/fts5.shell.o: QUOTA = -M512m -C16

View file

@ -809,7 +809,9 @@ void _tr_stored_block(struct DeflateState *s, charf *buf, uint64_t stored_len,
bi_windup(s); /* align on byte boundary */ bi_windup(s); /* align on byte boundary */
put_short(s, (uint16_t)stored_len); put_short(s, (uint16_t)stored_len);
put_short(s, (uint16_t)~stored_len); put_short(s, (uint16_t)~stored_len);
if (stored_len) {
memcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); memcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
}
s->pending += stored_len; s->pending += stored_len;
#ifdef ZLIB_DEBUG #ifdef ZLIB_DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (uint64_t)~7L; s->compressed_len = (s->compressed_len + 3 + 7) & (uint64_t)~7L;

View file

@ -3105,7 +3105,7 @@ static void OnlyRunOnFirstCpu(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (!NoDebug()) showcrashreports(); if (!NoDebug()) ShowCrashReports();
pty = NewPty(); pty = NewPty();
pty->conf |= kPtyNocanon; pty->conf |= kPtyNocanon;
m = NewMachine(); m = NewMachine();

View file

@ -727,7 +727,7 @@ void GetOpts(int argc, char *argv[]) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int i, rc; int i, rc;
showcrashreports(); ShowCrashReports();
GetOpts(argc, argv); GetOpts(argc, argv);
xsigaction(SIGFPE, OnDivideError, 0, 0, 0); xsigaction(SIGFPE, OnDivideError, 0, 0, 0);
if (optind == argc) { if (optind == argc) {

View file

@ -101,7 +101,7 @@ FLAGS\n\
-C SECS set cpu limit [default 16]\n\ -C SECS set cpu limit [default 16]\n\
-L SECS set lat limit [default 90]\n\ -L SECS set lat limit [default 90]\n\
-M BYTES set mem limit [default 512m]\n\ -M BYTES set mem limit [default 512m]\n\
-F BYTES set fsz limit [default 100m]\n\ -F BYTES set fsz limit [default 256m]\n\
-O BYTES set out limit [default 1m]\n\ -O BYTES set out limit [default 1m]\n\
-s decrement verbosity [default 4]\n\ -s decrement verbosity [default 4]\n\
-v increments verbosity [default 4]\n\ -v increments verbosity [default 4]\n\
@ -725,14 +725,15 @@ int main(int argc, char *argv[]) {
int ws, opt, exitcode; int ws, opt, exitcode;
char *s, *p, *q, **envp; char *s, *p, *q, **envp;
mode = firstnonnull(getenv("MODE"), MODE);
/* /*
* parse prefix arguments * parse prefix arguments
*/ */
mode = MODE;
verbose = 4; verbose = 4;
timeout = 90; /* secs */ timeout = 90; /* secs */
cpuquota = 16; /* secs */ cpuquota = 16; /* secs */
fszquota = 100 * 1000 * 1000; /* bytes */ fszquota = 256 * 1000 * 1000; /* bytes */
memquota = 512 * 1024 * 1024; /* bytes */ memquota = 512 * 1024 * 1024; /* bytes */
if ((s = getenv("V"))) verbose = atoi(s); if ((s = getenv("V"))) verbose = atoi(s);
while ((opt = getopt(argc, argv, "hnvstC:M:F:A:T:V:O:L:")) != -1) { while ((opt = getopt(argc, argv, "hnvstC:M:F:A:T:V:O:L:")) != -1) {
@ -785,6 +786,16 @@ int main(int argc, char *argv[]) {
exit(1); exit(1);
} }
/*
* extend limits for slow UBSAN in particular
*/
if (!strcmp(mode, "dbg") || !strcmp(mode, "ubsan")) {
cpuquota *= 2;
fszquota *= 2;
memquota *= 2;
timeout *= 2;
}
cmd = argv[optind]; cmd = argv[optind];
if (!strchr(cmd, '/')) { if (!strchr(cmd, '/')) {
if (!(cmd = commandv(cmd, ccpath))) exit(127); if (!(cmd = commandv(cmd, ccpath))) exit(127);
@ -957,11 +968,13 @@ int main(int argc, char *argv[]) {
} }
if (wantasan) { if (wantasan) {
AddArg("-fsanitize=address"); AddArg("-fsanitize=address");
AddArg("-D__FSANITIZE_ADDRESS__"); /* compiler adds this by default */
/* AddArg("-D__SANITIZE_ADDRESS__"); */
} }
if (wantubsan) { if (wantubsan) {
AddArg("-fsanitize=undefined"); AddArg("-fsanitize=undefined");
AddArg("-fno-data-sections"); AddArg("-fno-data-sections");
AddArg("-D__SANITIZE_UNDEFINED__");
} }
if (no_sanitize_null) { if (no_sanitize_null) {
AddArg("-fno-sanitize=null"); AddArg("-fno-sanitize=null");

View file

@ -275,7 +275,7 @@ void Disassemble(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports(); ShowCrashReports();
int fd; int fd;
void *map; void *map;
struct stat st; struct stat st;

View file

@ -141,7 +141,9 @@ static void FlushTables(struct ElfWriter *elf) {
symtab = AppendSection(elf, ".symtab", SHT_SYMTAB, 0); symtab = AppendSection(elf, ".symtab", SHT_SYMTAB, 0);
for (i = 0; i < ARRAYLEN(elf->syms); ++i) { for (i = 0; i < ARRAYLEN(elf->syms); ++i) {
size = elf->syms[i]->i * sizeof(Elf64_Sym); size = elf->syms[i]->i * sizeof(Elf64_Sym);
if (size) {
memcpy(elfwriter_reserve(elf, size), elf->syms[i]->p, size); memcpy(elfwriter_reserve(elf, size), elf->syms[i]->p, size);
}
elfwriter_commit(elf, size); elfwriter_commit(elf, size);
} }
FinishSection(elf); FinishSection(elf);

View file

@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
int opt; int opt;
FILE *fin, *fout; FILE *fin, *fout;
showcrashreports(); ShowCrashReports();
while ((opt = getopt(argc, argv, "ho:s:z:")) != -1) { while ((opt = getopt(argc, argv, "ho:s:z:")) != -1) {
switch (opt) { switch (opt) {

View file

@ -87,7 +87,7 @@
* - 1 byte exit status * - 1 byte exit status
*/ */
#define DEATH_CLOCK_SECONDS 16 #define DEATH_CLOCK_SECONDS 32
#define kLogFile "o/runitd.log" #define kLogFile "o/runitd.log"
#define kLogMaxBytes (2 * 1000 * 1000) #define kLogMaxBytes (2 * 1000 * 1000)

View file

@ -302,7 +302,7 @@ static void printelfrelocations(void) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int fd; int fd;
showcrashreports(); ShowCrashReports();
if (argc != 2) { if (argc != 2) {
fprintf(stderr, "usage: %s FILE\n", argv[0]); fprintf(stderr, "usage: %s FILE\n", argv[0]);
return 1; return 1;

View file

@ -150,7 +150,7 @@ static void DoIt(int y, int x) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char *s; char *s;
int y, x; int y, x;
showcrashreports(); ShowCrashReports();
f = stdin; f = stdin;
while ((s = chomp(xgetline(f)))) { while ((s = chomp(xgetline(f)))) {
n = strwidth(s, 0); n = strwidth(s, 0);

View file

@ -488,7 +488,7 @@ int main(int argc, char *argv[]) {
int fd; int fd;
uint8_t *map; uint8_t *map;
struct stat st; struct stat st;
showcrashreports(); ShowCrashReports();
CHECK_EQ(2, argc); CHECK_EQ(2, argc);
CHECK_NE(-1, (fd = open(argv[1], O_RDONLY))); CHECK_NE(-1, (fd = open(argv[1], O_RDONLY)));
CHECK_NE(-1, fstat(fd, &st)); CHECK_NE(-1, fstat(fd, &st));

View file

@ -266,7 +266,7 @@ int main(int argc, char *argv[]) {
int fd; int fd;
uint8_t *map; uint8_t *map;
struct stat st; struct stat st;
showcrashreports(); ShowCrashReports();
CHECK_EQ(2, argc); CHECK_EQ(2, argc);
CHECK_NE(-1, (fd = open(argv[1], O_RDONLY))); CHECK_NE(-1, (fd = open(argv[1], O_RDONLY)));
CHECK_NE(-1, fstat(fd, &st)); CHECK_NE(-1, fstat(fd, &st));

View file

@ -1793,7 +1793,8 @@ Keywords={
"__PG__", "__PG__",
"__MFENTRY__", "__MFENTRY__",
"__MNO_VZEROUPPER__", "__MNO_VZEROUPPER__",
"__FSANITIZE_UNDEFINED__", "__SANITIZE_ADDRESS__",
"__SANITIZE_UNDEFINED__",
"__MNOP_MCOUNT__", "__MNOP_MCOUNT__",
"__MRECORD_MCOUNT__", "__MRECORD_MCOUNT__",
"__x86_64__", "__x86_64__",

View file

@ -45,6 +45,8 @@
"__INTMAX_C" "__INTMAX_C"
"__UINTMAX_C" "__UINTMAX_C"
"__TIMESTAMP__" "__TIMESTAMP__"
"__SANITIZE_ADDRESS__"
"__SANITIZE_UNDEFINED__"
"__FP_FAST_FMA" "__FP_FAST_FMA"
"__FP_FAST_FMAF" "__FP_FAST_FMAF"
"__FP_FAST_FMAL" "__FP_FAST_FMAL"

View file

@ -158,8 +158,6 @@
"__PG__" "__PG__"
"__MFENTRY__" "__MFENTRY__"
"__MNO_VZEROUPPER__" "__MNO_VZEROUPPER__"
"__FSANITIZE_ADDRESS__"
"__FSANITIZE_UNDEFINED__"
"__MNO_RED_ZONE__" "__MNO_RED_ZONE__"
"__MNOP_MCOUNT__" "__MNOP_MCOUNT__"
"__MRECORD_MCOUNT__" "__MRECORD_MCOUNT__"

View file

@ -75,7 +75,7 @@ void lookup(const char *name) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int i; int i;
showcrashreports(); ShowCrashReports();
for (i = 1; i < argc; ++i) lookup(argv[i]); for (i = 1; i < argc; ++i) lookup(argv[i]);
return 0; return 0;
} }

View file

@ -7341,7 +7341,7 @@ void RedBean(int argc, char *argv[]) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (!IsTiny()) { if (!IsTiny()) {
setenv("GDB", "", true); setenv("GDB", "", true);
showcrashreports(); ShowCrashReports();
} }
RedBean(argc, argv); RedBean(argc, argv);
if (IsModeDbg()) { if (IsModeDbg()) {

View file

@ -588,7 +588,7 @@ int main(int argc, char *argv[]) {
size_t size; size_t size;
char *option; char *option;
unsigned yd, xd; unsigned yd, xd;
showcrashreports(); ShowCrashReports();
GetOpts(argc, argv); GetOpts(argc, argv);
// if sizes are given, 2 cases: // if sizes are given, 2 cases:
// - positive values: use that as the target size // - positive values: use that as the target size

View file

@ -306,7 +306,7 @@ void GenerateMatrix(FILE *f) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int i; int i;
FILE *f; FILE *f;
showcrashreports(); ShowCrashReports();
GetOpts(argc, argv); GetOpts(argc, argv);
CHECK_NOTNULL((f = fopen(path_, "w"))); CHECK_NOTNULL((f = fopen(path_, "w")));
if (optind < argc) FATALF("TODO(jart): support input files"); if (optind < argc) FATALF("TODO(jart): support input files");

View file

@ -1397,7 +1397,7 @@ static void Gui(void) {
*/ */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (!NoDebug()) showcrashreports(); if (!NoDebug()) ShowCrashReports();
out = 1; out = 1;
speed = 1; speed = 1;
tyn = right = 80; tyn = right = 80;

View file

@ -634,7 +634,7 @@ int main(int argc, char *argv[]) {
break; break;
} }
} }
showcrashreports(); ShowCrashReports();
for (i = optind; i < argc; ++i) { for (i = optind; i < argc; ++i) {
WithImageFile(argv[i], scaler); WithImageFile(argv[i], scaler);
} }

View file

@ -926,7 +926,7 @@ static void GetOpts(int argc, char *argv[]) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (!NoDebug()) showcrashreports(); if (!NoDebug()) ShowCrashReports();
out = 1; out = 1;
GetOpts(argc, argv); GetOpts(argc, argv);
Open(); Open();

View file

@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
FILE *f; FILE *f;
int i, n, t; int i, n, t;
char *sym, tabs[64]; char *sym, tabs[64];
showcrashreports(); ShowCrashReports();
f = fopen("/tmp/syms.txt", "r"); f = fopen("/tmp/syms.txt", "r");
memset(tabs, '\t', 64); memset(tabs, '\t', 64);
while ((sym = chomp(xgetline(f)))) { while ((sym = chomp(xgetline(f)))) {

View file

@ -38,6 +38,7 @@
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/madv.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/time/time.h"
#include "tool/decode/lib/flagger.h" #include "tool/decode/lib/flagger.h"
#include "tool/decode/lib/idname.h" #include "tool/decode/lib/idname.h"
@ -518,7 +519,6 @@ void PrintModulesMemoryOrder(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
showcrashreports();
if (IsLinux()) { if (IsLinux()) {
return NextBestThing(); return NextBestThing();
} }

View file

@ -1536,7 +1536,7 @@ int main(int argc, char *argv[]) {
sigaddset(&wut, SIGCHLD); sigaddset(&wut, SIGCHLD);
sigaddset(&wut, SIGPIPE); sigaddset(&wut, SIGPIPE);
sigprocmask(SIG_SETMASK, &wut, NULL); sigprocmask(SIG_SETMASK, &wut, NULL);
showcrashreports(); ShowCrashReports();
fullclear_ = true; fullclear_ = true;
GetOpts(argc, argv); GetOpts(argc, argv);
if (!tuned_) PickDefaults(); if (!tuned_) PickDefaults();