mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Make some minor fixups to bug reporting, etc.
This commit is contained in:
parent
84764ce7b8
commit
3f015b1e51
31 changed files with 244 additions and 134 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue