Remove debug_fault_handler - it's not used in our code base - it's not tested (it says so) - it duplicates sel4utils_print_fault_message - move useful code to sel4utils_print_fault_message - make sure sel4utils_print_fault_message doesn't use GetMR, as print may cause it to invalidate the IPC buffer contents.
diff --git a/libsel4debug/include/sel4debug/faults.h b/libsel4debug/include/sel4debug/faults.h deleted file mode 100644 index b3128b5..0000000 --- a/libsel4debug/include/sel4debug/faults.h +++ /dev/null
@@ -1,34 +0,0 @@ -/* - * Copyright 2017, Data61 - * Commonwealth Scientific and Industrial Research Organisation (CSIRO) - * ABN 41 687 119 230. - * - * This software may be distributed and modified according to the terms of - * the BSD 2-Clause license. Note that NO WARRANTY is provided. - * See "LICENSE_BSD2.txt" for details. - * - * @TAG(DATA61_BSD) - */ - -#ifndef _LIBSEL4DEBUG_FAULTS_H_ -#define _LIBSEL4DEBUG_FAULTS_H_ - -/* A basic fault handler for debugging purposes. Note that you are expected to - * call this function from the thread that you wish to act as a fault handler - * as it doesn't return on success. Returns non-zero on failure. - * - * faultep - The endpoint to listen on for fault messages. - * senders - A function for translating endpoint badge to thread name. This is - * helpful if you want to handle faults from multiple threads via badged - * endpoints, but are also in a position to provide this handler with more - * information (than just the badge) about which thread faulted. If this - * parameter is NULL it will be ignored. - * - * TODO: This function has not been tested. I wrote it with the aim of - * debugging some CAmkES code, but there is an open bug (VER-348) that prevents - * setting fault handlers currently. - */ -int debug_fault_handler(seL4_CPtr faultep, - const char * (*senders)(seL4_Word badge)); - -#endif
diff --git a/libsel4debug/src/faulthandler.c b/libsel4debug/src/faulthandler.c deleted file mode 100644 index c690fe9..0000000 --- a/libsel4debug/src/faulthandler.c +++ /dev/null
@@ -1,126 +0,0 @@ -/* - * Copyright 2017, Data61 - * Commonwealth Scientific and Industrial Research Organisation (CSIRO) - * ABN 41 687 119 230. - * - * This software may be distributed and modified according to the terms of - * the BSD 2-Clause license. Note that NO WARRANTY is provided. - * See "LICENSE_BSD2.txt" for details. - * - * @TAG(DATA61_BSD) - */ - -#include <assert.h> -#include <sel4/sel4.h> -#include <stddef.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <sel4debug/faults.h> -#include <sel4debug/unknown_syscall.h> -#include <sel4debug/user_exception.h> - -/* Maximum number of message registers used in any fault transmission. */ -#define USED_MRS 13 - -int debug_fault_handler(seL4_CPtr faultep, - const char * (*senders)(seL4_Word badge)) -{ - char *sender_name = NULL; - - /* If we weren't passed a translation function, make sender_name a buffer - * large enough to handle sprintf-ing a pointer into it. - */ - if (senders == NULL) { - sender_name = (char*)malloc(sizeof(uintptr_t) * 2 + strlen("0x") + 1); - if (sender_name == NULL) { - /* Out of memory */ - return -1; - } - } - - while (1) { - seL4_Word sender; - - /* Wait for a fault. */ - seL4_MessageInfo_t info = seL4_Recv(faultep, &sender); - - /* Get the fault type (see section 5.2 of the manual). */ - seL4_Word label = seL4_MessageInfo_get_label(info); - - seL4_Word length = seL4_MessageInfo_get_length(info); - - /* Save the message registers before doing anything else. This is under - * the assumption printf() or senders() may clobber them. - */ - seL4_Word mrs[USED_MRS]; - for (unsigned int i = 0; i < USED_MRS; i++) { - mrs[i] = seL4_GetMR(i); - } - - /* Retrieve the friendly name of the thread if its available. */ - if (senders == NULL) { - sprintf(sender_name, "%p", (void*)sender); - } else { - sender_name = (char*)senders(sender); - } - - switch (label) { - - case seL4_Fault_CapFault: { - /* See section 5.2.1 of the manual. */ - assert(length > 4); - printf("debug: Cap fault in %s phase from %s\n" - " PC = %p\n" - " CPtr = %p\n", - mrs[2] == 1 ? "receive" : "send", sender_name, - (void*)mrs[0], (void*)mrs[1]); - /* TODO: Failure description. */ - break; - } - - case seL4_Fault_UnknownSyscall: { - /* See section 5.2.2 of the manual. */ - printf("debug: Unknown syscall from %s\n", sender_name); - debug_unknown_syscall_message(printf, mrs); - break; - } - - case seL4_Fault_UserException: { - /* See section 5.2.3 of the manual. */ - printf("debug: User exception from %s\n", sender_name); - debug_user_exception_message(printf, mrs); - break; - } - - case seL4_Fault_VMFault: { - /* See section 5.2.4 of the manual. */ - assert(length == 4); - printf("debug: Virtual memory %s fault from %s\n" - " PC = %p\n" - " Fault address = %p\n" - " Fault status register = %p\n", - mrs[2] == 1 ? "instruction" : "data", sender_name, - (void*)mrs[0], (void*)mrs[1], (void*)mrs[3]); - /* TODO: Translate the FSR nicely for the user. */ - break; - } - - default: { - printf("debug: Unexpected fault %p from %s\n", (void*)label, - sender_name); - for (unsigned int i = 0; i < length && i < USED_MRS; i++) { - printf(" mr%u = %p\n", i, (void*)mrs[i]); - } - if (length > USED_MRS) { - printf(" further %zu registers not shown\n", - length - USED_MRS); - } - } - } - } - - assert(!"unreachable"); - return 0; -}
diff --git a/libsel4utils/src/thread.c b/libsel4utils/src/thread.c index 7d42149..e568663 100644 --- a/libsel4utils/src/thread.c +++ b/libsel4utils/src/thread.c
@@ -184,16 +184,18 @@ sel4utils_print_fault_message(seL4_MessageInfo_t tag, const char *thread_name) { seL4_Fault_t fault = seL4_getFault(tag); + switch (seL4_Fault_get_seL4_FaultType(fault)) { case seL4_Fault_VMFault: assert(seL4_MessageInfo_get_length(tag) == seL4_VMFault_Length); - printf("%sPagefault from [%s]: %s %s at PC: %p vaddr: %p%s\n", + printf("%sPagefault from [%s]: %s %s at PC: %p vaddr: %p, FSR %p%s\n", COLOR_ERROR, thread_name, sel4utils_is_read_fault() ? "read" : "write", seL4_Fault_VMFault_get_PrefetchFault(fault) ? "prefetch fault" : "fault", (void*)seL4_Fault_VMFault_get_IP(fault), (void*)seL4_Fault_VMFault_get_Addr(fault), + (void *)seL4_Fault_VMFault_get_FSR(fault), COLOR_NORMAL); break; @@ -214,10 +216,19 @@ printf("%sInvalid instruction from [%s] at PC: %p%s\n", COLOR_ERROR, thread_name, - (void*)seL4_GetMR(seL4_UserException_FaultIP), + (void*)seL4_Fault_UserException_get_FaultIP(fault), COLOR_NORMAL); break; + case seL4_Fault_CapFault: + printf("%sCap fault from [%s] in phase %s\nPC = %p\nCPtr = %p%s\n", + COLOR_ERROR, thread_name, + seL4_Fault_CapFault_get_InRecvPhase(fault) ? "receive" : "send", + (void*) seL4_Fault_CapFault_get_IP(fault), + (void *) seL4_Fault_CapFault_get_Addr(fault), + COLOR_NORMAL); + break; + default: /* What? Why are we here? What just happened? */ printf("Unknown fault from [%s]: %"PRIuPTR" (length = %"PRIuPTR")\n", thread_name, seL4_MessageInfo_get_label(tag), seL4_MessageInfo_get_length(tag));