Make fixes and improvements

- Document more compiler flags
- Expose new __print_maps() api
- Better overflow checking in mmap()
- Improve the shell example somewhat
- Fix minor runtime bugs regarding stacks
- Make kill() on fork()+execve()'d children work
- Support CLONE_CHILD_CLEARTID for proper joining
- Fix recent possible deadlock regression with --ftrace
This commit is contained in:
Justine Tunney 2022-05-19 16:57:49 -07:00
parent 6e52cba37a
commit ec2cb88058
68 changed files with 1211 additions and 431 deletions

View file

@ -17,9 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/lockcmpxchgp.h"
#include "libc/intrin/spinlock.h"
#include "libc/log/libfatal.internal.h"
#include "libc/macros.internal.h"
@ -49,7 +51,7 @@
void ftrace_hook(void);
_Alignas(64) char ftrace_lock;
_Alignas(64) int ftrace_lock;
static struct Ftrace {
int skew;
@ -75,6 +77,32 @@ static privileged int GetNestingLevel(struct StackFrame *frame) {
return MIN(MAX_NESTING, nesting);
}
static privileged inline void ReleaseFtraceLock(void) {
int zero = 0;
__atomic_store(&ftrace_lock, &zero, __ATOMIC_RELAXED);
}
static privileged inline bool AcquireFtraceLock(void) {
int me, owner, tries;
for (tries = 0, me = gettid();;) {
owner = 0;
if (_lockcmpxchgp(&ftrace_lock, &owner, me)) {
return true;
}
if (owner == me) {
// we ignore re-entry into ftrace. while the code and build config
// is written to make re-entry highly unlikely, it's impossible to
// guarantee. there's also the possibility of asynchronous signals
return false;
}
if (++tries & 7) {
__builtin_ia32_pause();
} else {
sched_yield();
}
}
}
/**
* Prints name of function being called.
*
@ -83,21 +111,22 @@ static privileged int GetNestingLevel(struct StackFrame *frame) {
* according to the System Five NexGen32e ABI.
*/
privileged void ftracer(void) {
long stackuse;
uint64_t stamp;
size_t stackuse;
struct StackFrame *frame;
_spinlock_cooperative(&ftrace_lock);
stamp = rdtsc();
frame = __builtin_frame_address(0);
frame = frame->next;
if (frame->addr != g_ftrace.lastaddr) {
stackuse = ROUNDUP((intptr_t)frame, GetStackSize()) - (intptr_t)frame;
kprintf("%rFUN %5P %'13T %'*lu %*s%t\r\n", g_ftrace.stackdigs, stackuse,
GetNestingLevel(frame) * 2, "", frame->addr);
g_ftrace.laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc();
g_ftrace.lastaddr = frame->addr;
if (AcquireFtraceLock()) {
stamp = rdtsc();
frame = __builtin_frame_address(0);
frame = frame->next;
if (frame->addr != g_ftrace.lastaddr) {
stackuse = (intptr_t)GetStackAddr(0) + GetStackSize() - (intptr_t)frame;
kprintf("%rFUN %5P %'13T %'*ld %*s%t\r\n", g_ftrace.stackdigs, stackuse,
GetNestingLevel(frame) * 2, "", frame->addr);
g_ftrace.laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc();
g_ftrace.lastaddr = frame->addr;
}
ReleaseFtraceLock();
}
_spunlock(&ftrace_lock);
}
textstartup int ftrace_install(void) {