mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[panic] Allow assert/panic to take optional user cpu_state
In places where the "user" state is available, like interrupt handlers, panic() and kassert() can now take an optional pointer to that user cpu_state structure, and the panic handler will print that out as well.
This commit is contained in:
@@ -9,5 +9,5 @@ void const *symbol_table = nullptr;
|
|||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void _PDCLIB_assert(const char *message, const char *function, const char *file, unsigned line) {
|
void _PDCLIB_assert(const char *message, const char *function, const char *file, unsigned line) {
|
||||||
panic::panic(message, function, file, line);
|
panic::panic(message, nullptr, function, file, line);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ extern void const *symbol_table;
|
|||||||
__attribute__ ((always_inline))
|
__attribute__ ((always_inline))
|
||||||
inline void panic(
|
inline void panic(
|
||||||
const char *message = nullptr,
|
const char *message = nullptr,
|
||||||
|
const cpu_state *user = nullptr,
|
||||||
const char *function = __builtin_FUNCTION(),
|
const char *function = __builtin_FUNCTION(),
|
||||||
const char *file = __builtin_FILE(),
|
const char *file = __builtin_FILE(),
|
||||||
uint64_t line = __builtin_LINE())
|
uint64_t line = __builtin_LINE())
|
||||||
@@ -28,10 +29,13 @@ inline void panic(
|
|||||||
// If we aren't the first CPU to panic, cpu.panic will be null
|
// If we aren't the first CPU to panic, cpu.panic will be null
|
||||||
if (cpu.panic) {
|
if (cpu.panic) {
|
||||||
cpu.panic->symbol_data = symbol_table;
|
cpu.panic->symbol_data = symbol_table;
|
||||||
|
cpu.panic->user_state = user;
|
||||||
|
|
||||||
cpu.panic->message = message;
|
cpu.panic->message = message;
|
||||||
cpu.panic->function = function;
|
cpu.panic->function = function;
|
||||||
cpu.panic->file = file;
|
cpu.panic->file = file;
|
||||||
cpu.panic->line = line;
|
cpu.panic->line = line;
|
||||||
|
|
||||||
cpu.panic->cpus = g_num_cpus;
|
cpu.panic->cpus = g_num_cpus;
|
||||||
|
|
||||||
*apic_icr = send_nmi_command;
|
*apic_icr = send_nmi_command;
|
||||||
@@ -48,12 +52,13 @@ __attribute__ ((always_inline))
|
|||||||
inline void kassert(
|
inline void kassert(
|
||||||
bool check,
|
bool check,
|
||||||
const char *message = nullptr,
|
const char *message = nullptr,
|
||||||
|
const cpu_state *user = nullptr,
|
||||||
const char *function = __builtin_FUNCTION(),
|
const char *function = __builtin_FUNCTION(),
|
||||||
const char *file = __builtin_FILE(),
|
const char *file = __builtin_FILE(),
|
||||||
uint64_t line = __builtin_LINE())
|
uint64_t line = __builtin_LINE())
|
||||||
{
|
{
|
||||||
if (!check)
|
if (!check)
|
||||||
panic::panic(message, function, file, line);
|
panic::panic(message, user, function, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define assert(x) kassert((x))
|
#define assert(x) kassert((x))
|
||||||
|
|||||||
@@ -21,11 +21,14 @@ struct cpu_state
|
|||||||
/// Kernel-wide panic information
|
/// Kernel-wide panic information
|
||||||
struct panic_data
|
struct panic_data
|
||||||
{
|
{
|
||||||
void const * symbol_data;
|
void const *symbol_data;
|
||||||
char const * message;
|
cpu_state const *user_state;
|
||||||
char const * function;
|
|
||||||
char const * file;
|
char const *message;
|
||||||
|
char const *function;
|
||||||
|
char const *file;
|
||||||
uint32_t line;
|
uint32_t line;
|
||||||
|
|
||||||
uint16_t cpus;
|
uint16_t cpus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ isr_handler(cpu_state *regs)
|
|||||||
asm volatile ("mov %%dr5, %%r13" ::: "r13");
|
asm volatile ("mov %%dr5, %%r13" ::: "r13");
|
||||||
asm volatile ("mov %%dr6, %%r14" ::: "r14");
|
asm volatile ("mov %%dr6, %%r14" ::: "r14");
|
||||||
asm volatile ("mov %%dr7, %%r15" ::: "r15");
|
asm volatile ("mov %%dr7, %%r15" ::: "r15");
|
||||||
kassert(false, "Debug exception");
|
kassert(false, "Debug exception", regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isr::isrDoubleFault:
|
case isr::isrDoubleFault:
|
||||||
kassert(false, "Double fault");
|
kassert(false, "Double fault", regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isr::isrGPFault:
|
case isr::isrGPFault:
|
||||||
@@ -113,7 +113,7 @@ isr_handler(cpu_state *regs)
|
|||||||
snprintf(message, sizeof(message), "General Protection Fault, error:%lx%s",
|
snprintf(message, sizeof(message), "General Protection Fault, error:%lx%s",
|
||||||
regs->errorcode, regs->errorcode & 1 ? " external" : "");
|
regs->errorcode, regs->errorcode & 1 ? " external" : "");
|
||||||
}
|
}
|
||||||
kassert(false, message);
|
kassert(false, message, regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isr::isrPageFault: {
|
case isr::isrPageFault: {
|
||||||
@@ -138,7 +138,7 @@ isr_handler(cpu_state *regs)
|
|||||||
(regs->errorcode & 0x04) ? " user" : "",
|
(regs->errorcode & 0x04) ? " user" : "",
|
||||||
(regs->errorcode & 0x08) ? " reserved" : "",
|
(regs->errorcode & 0x08) ? " reserved" : "",
|
||||||
(regs->errorcode & 0x10) ? " ip" : "");
|
(regs->errorcode & 0x10) ? " ip" : "");
|
||||||
kassert(false, message);
|
kassert(false, message, regs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ isr_handler(cpu_state *regs)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(message, sizeof(message), "Unknown interrupt 0x%lx", regs->interrupt);
|
snprintf(message, sizeof(message), "Unknown interrupt 0x%lx", regs->interrupt);
|
||||||
kassert(false, message);
|
kassert(false, message, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the IST for this vector to what it was
|
// Return the IST for this vector to what it was
|
||||||
|
|||||||
@@ -113,6 +113,13 @@ print_cpu_state(serial_port &out, const cpu_state ®s)
|
|||||||
out.write(clear);
|
out.write(clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_user_state(serial_port &out, const cpu_state ®s)
|
||||||
|
{
|
||||||
|
out.write("\n\e[1;35m USER:\e[0 ");
|
||||||
|
print_cpu_state(out, regs);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace panicking
|
} // namespace panicking
|
||||||
|
|
||||||
// For printf.c
|
// For printf.c
|
||||||
|
|||||||
@@ -28,5 +28,6 @@ void print_header(
|
|||||||
void print_cpu(serial_port &out, cpu_data &cpu);
|
void print_cpu(serial_port &out, cpu_data &cpu);
|
||||||
void print_callstack(serial_port &out, symbol_table &syms, frame const *fp);
|
void print_callstack(serial_port &out, symbol_table &syms, frame const *fp);
|
||||||
void print_cpu_state(serial_port &out, const cpu_state ®s);
|
void print_cpu_state(serial_port &out, const cpu_state ®s);
|
||||||
|
void print_user_state(serial_port &out, const cpu_state ®s);
|
||||||
|
|
||||||
} // namespace panicking
|
} // namespace panicking
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ _panic_entry:
|
|||||||
push_all
|
push_all
|
||||||
check_swap_gs
|
check_swap_gs
|
||||||
|
|
||||||
mov r9, rsp
|
mov rdi, rsp
|
||||||
|
|
||||||
mov rax, [rsp + REGS.rip]
|
mov rax, [rsp + REGS.rip]
|
||||||
push rax
|
push rax
|
||||||
|
|||||||
@@ -22,13 +22,7 @@ panicking::symbol_table &syms = __syms_storage.value;
|
|||||||
constexpr int order = __ATOMIC_ACQ_REL;
|
constexpr int order = __ATOMIC_ACQ_REL;
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void panic_handler(
|
void panic_handler(const cpu_state *regs)
|
||||||
const void *symbol_data,
|
|
||||||
const char *message,
|
|
||||||
const char *function,
|
|
||||||
const char *file,
|
|
||||||
uint64_t line,
|
|
||||||
const cpu_state *regs)
|
|
||||||
{
|
{
|
||||||
cpu_data &cpu = current_cpu();
|
cpu_data &cpu = current_cpu();
|
||||||
panic_data *panic = cpu.panic;
|
panic_data *panic = cpu.panic;
|
||||||
@@ -57,6 +51,9 @@ void panic_handler(
|
|||||||
print_callstack(com1, syms, fp);
|
print_callstack(com1, syms, fp);
|
||||||
print_cpu_state(com1, *regs);
|
print_cpu_state(com1, *regs);
|
||||||
|
|
||||||
|
if (panic && panic->user_state)
|
||||||
|
print_user_state(com1, *panic->user_state);
|
||||||
|
|
||||||
__atomic_clear(&asserting_locked, order);
|
__atomic_clear(&asserting_locked, order);
|
||||||
|
|
||||||
// If we're running on the CPU that panicked, tell the
|
// If we're running on the CPU that panicked, tell the
|
||||||
|
|||||||
Reference in New Issue
Block a user