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

@ -20,18 +20,21 @@
#include "libc/calls/getconsolectrlevent.internal.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/ctrlevent.h"
#include "libc/nt/enum/processaccess.h"
#include "libc/nt/enum/th32cs.h"
#include "libc/nt/errors.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/processentry32.h"
#include "libc/sysv/errfuns.h"
textwindows int sys_kill_nt(int pid, int sig) {
bool32 ok;
int64_t handle;
int64_t h;
int event, ntpid;
// is killing everything except init really worth supporting?
@ -68,20 +71,37 @@ textwindows int sys_kill_nt(int pid, int sig) {
}
}
// XXX: Is this a cosmo pid that was returned by fork_nt?
// is this a cosmo pid that was returned by fork?
if (__isfdkind(pid, kFdProcess)) {
// since windows can't execve we need to kill the grandchildren
// TODO(jart): should we just kill the whole tree too? there's
// no obvious way to tell if it's the execve shell
int64_t hSnap, hProc, hChildProc;
struct NtProcessEntry32 pe = {.dwSize = sizeof(struct NtProcessEntry32)};
ntpid = GetProcessId(g_fds.p[pid].handle);
hSnap = CreateToolhelp32Snapshot(kNtTh32csSnapprocess, 0);
if (Process32First(hSnap, &pe)) {
do {
if (pe.th32ParentProcessID == ntpid) {
if ((h = OpenProcess(kNtProcessTerminate, false, pe.th32ProcessID))) {
TerminateProcess(h, 128 + sig);
CloseHandle(h);
}
}
} while (Process32Next(hSnap, &pe));
}
ok = TerminateProcess(g_fds.p[pid].handle, 128 + sig);
if (!ok && GetLastError() == kNtErrorAccessDenied) ok = true;
return 0;
}
// XXX: Is this a raw new technology pid? Because that's messy.
if ((handle = OpenProcess(kNtProcessTerminate, false, pid))) {
ok = TerminateProcess(handle, 128 + sig);
if ((h = OpenProcess(kNtProcessTerminate, false, pid))) {
ok = TerminateProcess(h, 128 + sig);
if (!ok && GetLastError() == kNtErrorAccessDenied) {
ok = true; // cargo culting other codebases here
}
CloseHandle(handle);
CloseHandle(h);
return 0;
} else {
return -1;

View file

@ -57,8 +57,9 @@ static void sigaltstack2linux(struct sigaltstack *linux,
* struct sigaction sa;
* struct sigaltstack ss;
* ss.ss_flags = 0;
* ss.ss_size = SIGSTKSZ;
* ss.ss_sp = malloc(ss.ss_size);
* ss.ss_size = GetStackSize();
* ss.ss_sp = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
* MAP_STACK | MAP_ANONYMOUS, -1, 0);
* sa.sa_flags = SA_ONSTACK;
* sa.sa_handler = OnStackOverflow;
* __cxa_atexit(free, ss[0].ss_sp, 0);
@ -66,6 +67,11 @@ static void sigaltstack2linux(struct sigaltstack *linux,
* sigaltstack(&ss, 0);
* sigaction(SIGSEGV, &sa, 0);
*
* It's strongly recommended that you allocate a stack with the same
* size as GetStackSize() and that it have GetStackSize() alignment.
* Otherwise some of your runtime support code (e.g. ftrace stack use
* logging, kprintf() memory safety) won't be able to work as well.
*
* @param neu if non-null will install new signal alt stack
* @param old if non-null will receive current signal alt stack
* @return 0 on success, or -1 w/ errno

View file

@ -35,6 +35,7 @@ privileged unsigned __wincrash(struct NtExceptionPointers *ep) {
int sig, code;
ucontext_t ctx;
STRACE("__wincrash");
switch (ep->ExceptionRecord->ExceptionCode) {
case kNtSignalBreakpoint:
code = TRAP_BRKPT;