Make some minor fixups to bug reporting, etc.

This commit is contained in:
Justine Tunney 2022-07-11 05:55:17 -07:00
parent 84764ce7b8
commit 3f015b1e51
31 changed files with 244 additions and 134 deletions

View file

@ -43,8 +43,6 @@
#include "libc/thread/openbsd.internal.h"
#include "libc/thread/xnu.internal.h"
STATIC_YOINK("gettid"); // for kprintf()
#define __NR_thr_new 455
#define __NR_clone_linux 56
#define __NR__lwp_create 309
@ -84,6 +82,7 @@ int WinThreadLaunch(void *arg, // rdi
// we can't log this function because:
// 1. windows owns the backtrace pointer right now
// 2. ftrace unwinds rbp to determine depth
// 3. tid in tls for ftrace isn't set yet
// we can't use address sanitizer because:
// 1. __asan_handle_no_return wipes stack
// 2. windows owns the stack memory right now
@ -293,7 +292,9 @@ __attribute__((__constructor__)) static void OpenbsdGetSafeRsp(void) {
oldrsp = __builtin_frame_address(0);
}
static wontreturn void OpenbsdThreadMain(void *p) {
// we can't use address sanitizer because:
// 1. __asan_handle_no_return wipes stack [todo?]
noasan static wontreturn void OpenbsdThreadMain(void *p) {
struct CloneArgs *wt = p;
*wt->ptid = wt->tid;
*wt->ctid = wt->tid;
@ -643,7 +644,7 @@ int clone(void *func, void *stk, size_t stksz, int flags, void *arg, int *ptid,
*ptid = rc;
}
STRACE("clone(%p, %p, %'zu, %#x, %p, %p, %p, %'zu, %p) → %d% m", func, stk,
STRACE("clone(%t, %p, %'zu, %#x, %p, %p, %p, %'zu, %p) → %d% m", func, stk,
stksz, flags, arg, ptid, tls, tlssz, ctid, rc);
return rc;

View file

@ -24,11 +24,12 @@
extern int __threadcalls_end[];
extern int __threadcalls_start[];
#pragma weak __threadcalls_start
#pragma weak __threadcalls_end
privileged void __enable_threads(void) {
if (__threaded) return;
STRACE("__enable_threads()");
__threaded = gettid();
__morph_begin();
/*
* _NOPL("__threadcalls", func)
@ -54,4 +55,5 @@ privileged void __enable_threads(void) {
_base[*p + 2] = 0xe8;
}
__morph_end();
__threaded = gettid();
}

View file

@ -21,6 +21,8 @@
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/lockcmpxchg.h"
#include "libc/intrin/nopl.h"
#include "libc/intrin/pthread.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/stackframe.h"
#include "libc/nexgen32e/threaded.h"
@ -43,9 +45,22 @@ static struct Ftrace {
int skew;
int stackdigs;
int64_t lastaddr;
volatile bool busy;
pthread_mutex_t lock;
volatile bool noreentry;
} g_ftrace;
static void __ftrace_lock(void) {
if (__threaded) {
pthread_mutex_lock(&g_ftrace.lock);
}
}
static void __ftrace_unlock(void) {
if (__threaded) {
pthread_mutex_unlock(&g_ftrace.lock);
}
}
static privileged inline int GetNestingLevelImpl(struct StackFrame *frame) {
int nesting = -2;
while (frame) {
@ -63,18 +78,6 @@ static privileged inline int GetNestingLevel(struct StackFrame *frame) {
return MIN(MAX_NESTING, nesting);
}
static privileged inline void ReleaseFtraceLock(void) {
g_ftrace.busy = false;
}
static privileged inline bool AcquireFtraceLock(void) {
if (!__threaded) {
return _cmpxchg(&g_ftrace.busy, false, true);
} else {
return _lockcmpxchg(&g_ftrace.busy, false, true);
}
}
/**
* Prints name of function being called.
*
@ -85,20 +88,26 @@ static privileged inline bool AcquireFtraceLock(void) {
privileged void ftracer(void) {
long stackuse;
struct StackFrame *frame;
if (AcquireFtraceLock()) {
__ftrace_lock();
if (_cmpxchg(&g_ftrace.noreentry, false, true)) {
frame = __builtin_frame_address(0);
frame = frame->next;
if (frame->addr != g_ftrace.lastaddr) {
stackuse = (intptr_t)GetStackAddr(0) + GetStackSize() - (intptr_t)frame;
stackuse = GetStackAddr() + GetStackSize() - (intptr_t)frame;
kprintf("%rFUN %6P %'13T %'*ld %*s%t\n", g_ftrace.stackdigs, stackuse,
GetNestingLevel(frame) * 2, "", frame->addr);
g_ftrace.lastaddr = frame->addr;
}
ReleaseFtraceLock();
g_ftrace.noreentry = false;
}
__ftrace_unlock();
}
textstartup int ftrace_install(void) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&g_ftrace.lock, &attr);
if (GetSymbolTable()) {
g_ftrace.lastaddr = -1;
g_ftrace.stackdigs = LengthInt64Thousands(GetStackSize());

View file

@ -16,19 +16,48 @@
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/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
static char *_stkbase;
__attribute__((__constructor__)) static void init(void) {
_stkbase = (char *)kFixedmapStart;
}
/**
* Allocates stack.
*
* The size of your returned stack is always GetStackSize().
*
* The bottom 4096 bytes of your stack can't be used, since it's always
* reserved for a read-only guard page. With ASAN it'll be poisoned too.
*
* The top 16 bytes of a stack can't be used due to openbsd:stackbound
* and those bytes are also poisoned under ASAN build modes.
*
* @return stack bottom address on success, or null w/ errrno
*/
void *_mapstack(void) {
return mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
MAP_STACK | MAP_ANONYMOUS, -1, 0);
char *p;
if ((p = mmap(_stkbase, GetStackSize(), PROT_READ | PROT_WRITE,
MAP_STACK | MAP_ANONYMOUS | MAP_FIXED, -1, 0)) != MAP_FAILED) {
if (IsAsan()) {
__asan_poison(p + GetStackSize() - 16, 16, kAsanStackOverflow);
__asan_poison(p, 4096, kAsanStackOverflow);
}
_stkbase += GetStackSize() * 4;
return p;
} else {
return 0;
}
}
/**

View file

@ -106,25 +106,25 @@ forceinline pureconst bool IsShadowFrame(int x) {
}
forceinline pureconst bool IsKernelFrame(int x) {
intptr_t stack = (intptr_t)GetStaticStackAddr(0);
intptr_t stack = GetStaticStackAddr(0);
return (int)(stack >> 16) <= x &&
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsStaticStackFrame(int x) {
intptr_t stack = (intptr_t)GetStaticStackAddr(0);
intptr_t stack = GetStaticStackAddr(0);
return (int)(stack >> 16) <= x &&
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsStackFrame(int x) {
intptr_t stack = (intptr_t)GetStackAddr(0);
intptr_t stack = GetStackAddr();
return (int)(stack >> 16) <= x &&
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsSigAltStackFrame(int x) {
intptr_t stack = (intptr_t)GetStackAddr(0);
intptr_t stack = GetStackAddr();
return (int)(stack >> 16) <= x &&
x <= (int)((stack + (SIGSTKSZ - FRAMESIZE)) >> 16);
}

View file

@ -223,9 +223,8 @@ textstartup void __printargs(const char *prologue) {
PRINT(" L%d%s%s %u-way %,u byte cache w/%s "
"%,u sets of %,u byte lines shared across %u threads%s",
CPUID4_CACHE_LEVEL,
CPUID4_CACHE_TYPE == 1 ? " data"
: CPUID4_CACHE_TYPE == 2 ? " code"
: "",
CPUID4_CACHE_TYPE == 1 ? " data"
: CPUID4_CACHE_TYPE == 2 ? " code" : "",
CPUID4_IS_FULLY_ASSOCIATIVE ? " fully-associative" : "",
CPUID4_WAYS_OF_ASSOCIATIVITY, CPUID4_CACHE_SIZE_IN_BYTES,
CPUID4_PHYSICAL_LINE_PARTITIONS > 1 ? " physically partitioned" : "",
@ -358,7 +357,7 @@ textstartup void __printargs(const char *prologue) {
PRINT(" ☼ %s = %#s", "GetInterpreterExecutableName",
GetInterpreterExecutableName(u.path, sizeof(u.path)));
PRINT(" ☼ %s = %p", "RSP", __builtin_frame_address(0));
PRINT(" ☼ %s = %p", "GetStackAddr()", GetStackAddr(0));
PRINT(" ☼ %s = %p", "GetStackAddr()", GetStackAddr());
PRINT(" ☼ %s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0));
PRINT(" ☼ %s = %p", "GetStackSize()", GetStackSize());

View file

@ -78,9 +78,8 @@ extern char ape_stack_align[] __attribute__((__weak__));
* and (2) the mmap() address picker will choose aligned addresses when
* the provided size is a two power.
*/
#define GetStackAddr(ADDEND) \
((void *)((((intptr_t)__builtin_frame_address(0) - 1) & -GetStackSize()) + \
(ADDEND)))
#define GetStackAddr() \
(((intptr_t)__builtin_frame_address(0) - 1) & -GetStackSize())
/**
* Returns preferred bottom address of stack.
@ -102,7 +101,7 @@ extern char ape_stack_align[] __attribute__((__weak__));
} else { \
vAddr = 0x100000000 - GetStackSize(); \
} \
(void *)vAddr; \
vAddr; \
})
COSMOPOLITAN_C_END_

View file

@ -52,7 +52,7 @@ static textexit void LogStackUse(void) {
bool quote;
char *p, *q;
size_t n, usage;
usage = GetStackUsage(GetStackAddr(0), GetStackSize());
usage = GetStackUsage((char *)GetStackAddr(), GetStackSize());
fd = open(stacklog, O_APPEND | O_CREAT | O_WRONLY, 0644);
p = FormatUint64(stacklog, usage);
for (i = 0; i < __argc; ++i) {

View file

@ -194,7 +194,7 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
_mmi.p = _mmi.s;
_mmi.n = ARRAYLEN(_mmi.s);
argsize = ROUNDUP(sizeof(struct WinArgs), FRAMESIZE);
stackaddr = (intptr_t)GetStaticStackAddr(0);
stackaddr = GetStaticStackAddr(0);
stacksize = GetStackSize();
allocsize = argsize + stacksize;
allocaddr = stackaddr - argsize;