summaryrefslogtreecommitdiff
path: root/src/libc/intr.c
diff options
context:
space:
mode:
authordzwdz2024-08-03 02:04:58 +0200
committerdzwdz2024-08-03 02:04:58 +0200
commit27b8676963d5d69353f44fde7faaa9a4dfe1567b (patch)
tree7c5decd1bc4b4a43a1ee331e671681830eb1d1da /src/libc/intr.c
parent974c2581c9524aa7546f5863ecc26065e328cd54 (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/intr.c')
-rw-r--r--src/libc/intr.c22
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);
}