diff options
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 4 | ||||
-rw-r--r-- | sys/include/sys/proc.h | 22 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 39 |
3 files changed, 65 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index c57b5d2..37efad4 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -127,6 +127,7 @@ static void trap_user(struct trapframe *tf) { struct proc *td = this_td(); + uintptr_t fault_addr; sigset_t sigset; sigemptyset(&sigset); @@ -148,6 +149,9 @@ trap_user(struct trapframe *tf) break; } + fault_addr = pf_faultaddr(); + proc_coredump(td, fault_addr); + /* * Send the signal then flush the signal queue right * away as these types of events are critical. diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 7aa04b2..54764d0 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -53,6 +53,26 @@ #define PROC_MAX_FILEDES 256 #define PROC_SIGMAX 64 +/* + * The coredump structure, contains information + * about crashes. + * + * @pid: PID of process that has crashed + * @fault_addr: Address of faulting memory access + * @tf: Copy of the programs trapframe + * @checksum: CRC32 checksum of entire coredump + * + * XXX: DO NOT REORDER (always add to the end before 'checksum') + */ +struct __packed coredump { + pid_t pid; + uintptr_t fault_addr; + struct trapframe tf; + + /* XXX: Add entries above the checksum */ + uint32_t checksum; +}; + struct proc { pid_t pid; struct exec_prog exec; @@ -88,7 +108,9 @@ struct proc { struct proc *this_td(void); struct proc *get_child(struct proc *cur, pid_t pid); + void proc_reap(struct proc *td); +void proc_coredump(struct proc *td, uintptr_t fault_addr); pid_t getpid(void); pid_t getppid(void); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 3cf2af8..16cd4b2 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -29,7 +29,13 @@ #include <sys/types.h> #include <sys/proc.h> +#include <sys/cdefs.h> +#include <sys/vnode.h> #include <sys/syscall.h> +#include <sys/filedesc.h> +#include <sys/fcntl.h> +#include <string.h> +#include <crc32.h> pid_t getpid(void) @@ -61,6 +67,39 @@ getppid(void) return td->parent->pid; } +void +proc_coredump(struct proc *td, uintptr_t fault_addr) +{ + struct coredump core; + struct sio_txn sio; + struct vnode *vp; + char pathname[128]; + int fd; + + snprintf(pathname, sizeof(pathname), "/tmp/core.%d", td->pid); + fd = fd_open(pathname, O_RDWR | O_CREAT); + + /* ... Hopefully not */ + if (__unlikely(fd < 0)) { + return; + } + + core.pid = td->pid; + core.fault_addr = fault_addr; + memcpy(&core.tf, &td->tf, sizeof(td->tf)); + + core.checksum = crc32(&core, sizeof(core) - sizeof(core.checksum)); + vp = fd_get(fd)->vp; + + sio.buf = &core; + sio.len = sizeof(core); + sio.offset = 0; + + /* Write the core file */ + vfs_vop_write(vp, &sio); + fd_close(fd); +} + scret_t sys_getpid(struct syscall_args *scargs) { |