diff options
author | dzwdz | 2024-08-03 02:04:58 +0200 |
---|---|---|
committer | dzwdz | 2024-08-03 02:04:58 +0200 |
commit | 27b8676963d5d69353f44fde7faaa9a4dfe1567b (patch) | |
tree | 7c5decd1bc4b4a43a1ee331e671681830eb1d1da /src/libc | |
parent | 974c2581c9524aa7546f5863ecc26065e328cd54 (diff) |
kernel: send user interrupt on page fault
I really should just rename interrupts to something else.
This is inspired by Plan9 and meant to make debugging easier, as the
dying process can take a stacktrace etc.
It kinda sucks that the default handler now depends on fprintf, which is quite
a bit of code, but whatever.
Diffstat (limited to 'src/libc')
-rw-r--r-- | src/libc/intr.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/libc/intr.c b/src/libc/intr.c index 12e6f4c..e751fa1 100644 --- a/src/libc/intr.c +++ b/src/libc/intr.c @@ -1,4 +1,5 @@ #include <camellia/intr.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -9,6 +10,23 @@ void intr_set(void (*fn)(struct intr_data *)) { _intr = fn ? fn : intr_null; } -void intr_default(struct intr_data *) { - exit(-1); +/* does haystack begin with needle? */ +static +bool strprefix(const char *haystack, const char *needle) +{ + for (;; haystack++, needle++) { + if (*needle == '\0') return true; + /* note that *haystack == '\0' implies *needle != *haystack */ + if (*needle != *haystack) return false; + } +} + +__attribute__((visibility("hidden"))) +extern char __executable_start[]; + +void intr_default(struct intr_data *d) { + if (strprefix(d->msg, "sys: ")) { + fprintf(stderr, "%s: %s (base %p)\n", getprogname(), d->msg, __executable_start); + } + exit(1); } |