mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +00:00
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:
parent
6e52cba37a
commit
ec2cb88058
68 changed files with 1211 additions and 431 deletions
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue