implement user mode catchable exceptions, refactor system status codes to use NTLSTATUS_ prefix, update build scripts to use shared literal macros for linker arguments, update named queue lifetime cleanup to include KeNamedQueueUnpublishHandle.
This commit is contained in:
1 parent
1f5477cf66
commit
b7fcfce6f7
140 files changed
+7649
-3943
No files matched your search
@@ -138,14 +138,14 @@ static void printUInt64Width(uint64_t n, size_t width) {
|
||||
// Names nt-lite process-abort exit statuses.
|
||||
static const char* processExitStatusName(uint32_t code) {
|
||||
switch (code) {
|
||||
case STATUS_PROCESS_KILLED: return "killed";
|
||||
case STATUS_PROCESS_PAGE_FAULT: return "page-fault";
|
||||
case STATUS_PROCESS_GENERAL_PROTECTION: return "general-protection";
|
||||
case STATUS_PROCESS_ILLEGAL_OPCODE: return "illegal-opcode";
|
||||
case STATUS_PROCESS_DIVIDE_BY_ZERO: return "divide-by-zero";
|
||||
case STATUS_PROCESS_BREAKPOINT: return "breakpoint";
|
||||
case STATUS_PROCESS_ALIGNMENT_FAULT: return "alignment-fault";
|
||||
case STATUS_PROCESS_UNKNOWN_FAULT: return "unknown-fault";
|
||||
case NTLSTATUS_PROCESS_KILLED: return "killed";
|
||||
case NTLSTATUS_PROCESS_PAGE_FAULT: return "page-fault";
|
||||
case NTLSTATUS_PROCESS_GENERAL_PROTECTION: return "general-protection";
|
||||
case NTLSTATUS_PROCESS_ILLEGAL_OPCODE: return "illegal-opcode";
|
||||
case NTLSTATUS_PROCESS_DIVIDE_BY_ZERO: return "divide-by-zero";
|
||||
case NTLSTATUS_PROCESS_BREAKPOINT: return "breakpoint";
|
||||
case NTLSTATUS_PROCESS_ALIGNMENT_FAULT: return "alignment-fault";
|
||||
case NTLSTATUS_PROCESS_UNKNOWN_FAULT: return "unknown-fault";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -527,7 +527,7 @@ static bool readLine(char* buf, int len) {
|
||||
inputReq.Flags = SYS_INPUT_EVENT_FLAG_NONE;
|
||||
inputReq.TimeoutMilliseconds = SYS_WAIT_TIMEOUT_INFINITE;
|
||||
inputReq.RecordOut = &input;
|
||||
if (SysReadInputEvent(&inputReq) != STATUS_SUCCESS) { SysYield(); continue; }
|
||||
if (SysReadInputEvent(&inputReq) != NTLSTATUS_SUCCESS) { SysYield(); continue; }
|
||||
|
||||
INPUT_KEY key = input.Key;
|
||||
if (key == INPUT_KEY_NONE) { SysYield(); continue; }
|
||||
@@ -653,6 +653,7 @@ static void cmd_stats(void) {
|
||||
SYS_DISK_STATS disk;
|
||||
SYS_PTE_STATS pte;
|
||||
SYS_SURFACE_STATS surface;
|
||||
SYS_EXCEPTION_STATS exceptionStats;
|
||||
uint32_t status;
|
||||
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, &sched, sizeof(sched), NULL);
|
||||
@@ -682,7 +683,14 @@ static void cmd_stats(void) {
|
||||
|
||||
size_t cpuPages = (cpuSize + 4095u) / 4096u;
|
||||
if (cpuPages == 0) cpuPages = 1;
|
||||
status = SysAllocVm(0, cpuPages, SYS_VM_READWRITE, SYS_VM_FLAG_NONE, &cpuBuffer);
|
||||
SYS_ALLOC_VM_REQUEST allocReq;
|
||||
memset(&allocReq, 0, sizeof(allocReq));
|
||||
allocReq.Size = sizeof(allocReq);
|
||||
allocReq.PageCount = cpuPages;
|
||||
allocReq.Protect = SYS_VM_READWRITE;
|
||||
allocReq.Flags = SYS_VM_FLAG_NONE;
|
||||
allocReq.BaseOut = &cpuBuffer;
|
||||
status = SysAllocVm(&allocReq);
|
||||
if (status != 0 || !cpuBuffer) {
|
||||
print("stats: cpu buffer allocation failed: ");
|
||||
printUInt(status);
|
||||
@@ -772,6 +780,15 @@ static void cmd_stats(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_EXCEPTION, &exceptionStats, sizeof(exceptionStats), NULL);
|
||||
if (status != 0) {
|
||||
print("stats: exception query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
print("Scheduler:\n");
|
||||
print(" ticks: "); printUInt64(sched.Ticks); print("\n");
|
||||
print(" context switches: "); printUInt64(sched.ContextSwitches); print("\n");
|
||||
@@ -785,6 +802,15 @@ static void cmd_stats(void) {
|
||||
print(" SMT deferrals: "); printUInt64(sched.SmtSiblingDeferrals); print("\n");
|
||||
print(" SMT primary pokes: "); printUInt64(sched.SmtPrimaryPokes); print("\n");
|
||||
|
||||
print("Exceptions:\n");
|
||||
print(" delivered: "); printUInt64(exceptionStats.Delivered); print("\n");
|
||||
print(" user-raised: "); printUInt64(exceptionStats.UserRaised); print("\n");
|
||||
print(" continued: "); printUInt64(exceptionStats.Continued); print("\n");
|
||||
print(" unhandled: "); printUInt64(exceptionStats.Unhandled); print("\n");
|
||||
print(" invalid continue: "); printUInt64(exceptionStats.InvalidContinue); print("\n");
|
||||
print(" max nesting: "); printUInt(exceptionStats.MaxNestedDispatch); print("\n");
|
||||
print(" last code: "); printUInt(exceptionStats.LastCode); print("\n");
|
||||
|
||||
print("CPUs:\n");
|
||||
const SYS_CPU_STAT* cpuRecords = SYS_CPU_STATS_CONST_RECORDS(cpu);
|
||||
uint32_t n = cpu->RecordCount;
|
||||
@@ -1352,11 +1378,11 @@ static void cmd_kill(const char* args) {
|
||||
uint32_t hProc = 0;
|
||||
uint32_t status = SysOpenProcess(pid, &hProc);
|
||||
if (status == 0) {
|
||||
status = SysKillProcess(hProc, (int32_t)STATUS_PROCESS_KILLED);
|
||||
status = SysKillProcess(hProc, (int32_t)NTLSTATUS_PROCESS_KILLED);
|
||||
SysCloseHandle(hProc);
|
||||
}
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED) {
|
||||
if (status == NTLSTATUS_ACCESS_DENIED) {
|
||||
print("kill: process ");
|
||||
printUInt(pid);
|
||||
print(" is termination-protected.\n");
|
||||
@@ -1466,7 +1492,7 @@ static bool shellConsumeQueuedCtrlC(void) {
|
||||
inputReq.Flags = SYS_INPUT_EVENT_FLAG_NONE;
|
||||
inputReq.TimeoutMilliseconds = 0;
|
||||
inputReq.RecordOut = &input;
|
||||
if (SysPeekInputEvent(&inputReq) != STATUS_SUCCESS) return false;
|
||||
if (SysPeekInputEvent(&inputReq) != NTLSTATUS_SUCCESS) return false;
|
||||
|
||||
if ((input.Modifiers & INPUT_MOD_CTRL) && input.Key == INPUT_KEY_C) {
|
||||
(void)SysReadInputEvent(&inputReq);
|
||||
@@ -1487,7 +1513,7 @@ static bool shellConsumeQueuedCtrlC(void) {
|
||||
// Returns whether one input key is currently held.
|
||||
static bool shellIsKeyDown(INPUT_KEY key) {
|
||||
bool down = false;
|
||||
return SysIsKeyDown(key, &down) == STATUS_SUCCESS && down;
|
||||
return SysIsKeyDown(key, &down) == NTLSTATUS_SUCCESS && down;
|
||||
}
|
||||
|
||||
// Waits for a foreground process while watching Ctrl-C without stealing ordinary stdin.
|
||||
@@ -1511,7 +1537,7 @@ static uint32_t waitForegroundProcess(uint32_t hProc) {
|
||||
for (;;) {
|
||||
index = 0;
|
||||
uint32_t status = SysWaitMany(&waitReq);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
if (status != NTLSTATUS_SUCCESS) {
|
||||
SysCloseHandle(inputQueue);
|
||||
return status;
|
||||
}
|
||||
@@ -1525,7 +1551,7 @@ static uint32_t waitForegroundProcess(uint32_t hProc) {
|
||||
if (((modifiers & INPUT_MOD_CTRL) && shellIsKeyDown(INPUT_KEY_C)) || shellConsumeQueuedCtrlC()) {
|
||||
if (!sentBreak) {
|
||||
print("^C\n");
|
||||
(void)SysKillProcess(hProc, (int32_t)STATUS_PROCESS_KILLED);
|
||||
(void)SysKillProcess(hProc, (int32_t)NTLSTATUS_PROCESS_KILLED);
|
||||
sentBreak = true;
|
||||
}
|
||||
}
|
||||
@@ -1624,7 +1650,7 @@ static int runCommand(const char* cmd) {
|
||||
} else {
|
||||
// Foreground mode: Wait for completion and flush standard keyboard stream.
|
||||
uint32_t waitStatus = waitForegroundProcess(hProc);
|
||||
if (waitStatus != STATUS_SUCCESS) {
|
||||
if (waitStatus != NTLSTATUS_SUCCESS) {
|
||||
print("shell: wait failed: ");
|
||||
printUInt(waitStatus);
|
||||
print("\n");
|
||||
@@ -1644,7 +1670,7 @@ static int runCommand(const char* cmd) {
|
||||
print("\n");
|
||||
SysCloseHandle(hProc);
|
||||
INPUT_KEY drainedKey;
|
||||
while (SysPollKeyboard(&drainedKey) == STATUS_SUCCESS) (void)SysReadKey(&drainedKey);
|
||||
while (SysPollKeyboard(&drainedKey) == NTLSTATUS_SUCCESS) (void)SysReadKey(&drainedKey);
|
||||
}
|
||||
} else {
|
||||
print("shell: launch failed\n");
|
||||
|
||||
Reference in new issue
Block a user