Skip to content

Commit 445177c

Browse files
committed
[exceptions] Print all registers state before crash
1 parent c5c843f commit 445177c

File tree

6 files changed

+71
-39
lines changed

6 files changed

+71
-39
lines changed

src/kernel/core.asm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ global kernel_core_entry_asm
1717
mov fs, ax
1818
mov gs, ax
1919

20+
xor ebp, ebp ; origin of stack trace
2021
mov esp, STACKINIT_KERNEL_CORE ; init stack pointer
2122
jmp kernel_core_entry
2223

src/kernel/interrupts/exceptions.asm

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,23 @@ global _interrupt_handler_0x1F_exception
4343
_interrupt_handler_%1_exception:
4444
; As we are HLT at end of exception there
4545
; is no need to save context for now.
46+
pushad ; execution all general purpose registers
47+
4648
xor eax, eax
49+
mov eax, gs ; execution gs
50+
push eax
51+
mov eax, fs ; execution fs
52+
push eax
53+
mov eax, es ; execution es
54+
push eax
4755
mov eax, ds ; execution ds
4856
push eax
49-
xor eax, eax
50-
mov eax, ss ; execution ss (current also)
57+
mov eax, ss ; execution ss
58+
push eax
59+
mov eax, %1 ; exception id
5160
push eax
5261
mov eax, GDT_KERNEL_DS ; kernel ds
5362
mov ds, eax
54-
mov eax, %1
55-
push eax
5663
call interrupt_handler_0x00_0x1F_exception
5764
HLT
5865
%endmacro

src/kernel/interrupts/exceptions.c

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,58 @@ extern void _interrupt_handler_0x1D_exception();
3737
extern void _interrupt_handler_0x1E_exception();
3838
extern void _interrupt_handler_0x1F_exception();
3939

40-
void interrupt_handler_0x00_0x1F_exception(int id, int err_code, int ds, int ss, int ip, int cs, int eflag) {
40+
#define gdt_address_from_segment(s, gdte_size) (((s)%(gdte_size)==0)?get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, (s)/(gdte_size)):-1)
41+
42+
struct exceptionContext {
43+
int id; // exception id
44+
45+
int ss, ds, es, fs, gs;
46+
int edi, esi, ebp, esp, ebx, edx, ecx, eax;
47+
48+
// at end
49+
int err_code; // can be optional for some interrupts.
50+
int ip, cs, eflag;
51+
};
52+
53+
void interrupt_handler_0x00_0x1F_exception(struct exceptionContext context) {
54+
// written for handler with error code otherwise ip, cs and eflag will skew.
55+
const int gdte_size = sizeof(struct GDTEntry);
4156
panic_screen_init();
42-
print_log("Hardware exception %d (0x%x) triggered", id, id);
43-
print_log(" Error Code: %x", err_code);
44-
print_log(" CS : %x (GDT entry)", cs);
45-
print_log(" DS : %x (GDT entry)", ds);
46-
print_log(" SS : %x (GDT entry)", ss);
47-
print_log(" IP : %x", ip);
48-
print_log(" FLAG : %x", eflag);
49-
if(cs%sizeof(struct GDTEntry)==0) {
50-
print_log(" PID : %d", get_idt_reverse_pid_lookup_cs(cs));
51-
unsigned int abs_cs = get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, cs/sizeof(struct GDTEntry));
52-
print_log(" abs IP: %x", abs_cs+ip);
53-
print_log(" abs CS: %x", abs_cs);
54-
} else {
55-
print_log(" PID : invalid");
56-
print_log(" abs IP: invalid");
57-
print_log(" abs CS: invalid");
58-
}
59-
if(ds%sizeof(struct GDTEntry)==0) {
60-
print_log(" abs DS: %x", get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, ds/sizeof(struct GDTEntry)));
61-
} else {
62-
print_log(" abs DS: invalid");
57+
58+
print_log("Hardware exception %d (0x%x) triggered", context.id, context.id);
59+
print_log(" Error Code: %x", context.err_code);
60+
if(context.cs%gdte_size==0) {
61+
print_log(" PID : %d", get_idt_reverse_pid_lookup_cs(context.cs));
6362
}
64-
if(ss%sizeof(struct GDTEntry)==0) {
65-
print_log(" abs SS: %x", get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, ss/sizeof(struct GDTEntry)));
66-
} else {
67-
print_log(" abs SS: invalid");
63+
print_log(" FLAG : %x", context.eflag);
64+
print_log(" IP : %x", context.ip);
65+
print_log(" CS : %x => %x", context.cs, gdt_address_from_segment(context.cs, gdte_size));
66+
print_log(" DS : %x => %x", context.ds, gdt_address_from_segment(context.ds, gdte_size));
67+
print_log(" SS : %x => %x", context.ss, gdt_address_from_segment(context.ss, gdte_size));
68+
print_log(" ES : %x => %x", context.es, gdt_address_from_segment(context.es, gdte_size));
69+
print_log(" FS : %x => %x", context.fs, gdt_address_from_segment(context.fs, gdte_size));
70+
print_log(" GS : %x => %x", context.gs, gdt_address_from_segment(context.gs, gdte_size));
71+
print_log(" EAX: %x EBX: %x ECX: %x EDX: %x", context.eax, context.ebx, context.ecx, context.edx);
72+
print_log(" ESP: %x EBP: %x ESI: %x EDI: %x", context.esp, context.ebp, context.esi, context.edi);
73+
74+
// stack trace
75+
{
76+
const int stack_trace_max_depth = 5;
77+
int last_ebp = context.ebp;
78+
// stack[ebp] => previous_ebp, if previous_ebp == 0 then break;
79+
for(int i=0; i<stack_trace_max_depth; i++) {
80+
// to be implemented
81+
break;
82+
}
83+
6884
}
6985

70-
switch (id) {
86+
87+
switch (context.id) {
7188
case 0x0D:
72-
PANIC(id, "[hw_exception] general_protection_fault");
89+
PANIC(context.id, "[hw_exception] general_protection_fault");
7390
}
74-
PANIC(id, "[hw_exception] triggered: no handler");
91+
PANIC(context.id, "[hw_exception] triggered: no handler");
7592
}
7693

7794
void interrupt_handler_0x0D_general_protection_fault(int id, int ip, int cs) {

src/kernel/interrupts/timer.asm

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,19 @@ global create_infant_process_irq0_stack
118118
; do_not_care: next two cs, ip
119119
; CS and IP doesn't matter, as they are controlled by _int_irq0_end
120120

121-
; do_not_care: next four are eax, ebx, ecx, edx
121+
; user: pushad
122122
mov ecx, eax
123123
sub ecx, 8
124-
mov [eax-12-24], ecx ; pushad esp
125-
; do_not_care: next three are ebp, esi, edi
124+
mov [eax-28], ecx
125+
mov ecx, 0
126+
mov [eax-12], ecx ; user: eax
127+
mov [eax-16], ecx ; user: ecx
128+
mov [eax-20], ecx ; user: edx
129+
mov [eax-24], ecx ; user: ebx
130+
; missing esp, pushed on top.
131+
mov [eax-32], ecx ; user: ebp==0, origin of stack trace.
132+
mov [eax-36], ecx ; user: esi
133+
mov [eax-40], ecx ; user: edi
126134

127135
mov ecx, [ebp+0x08] ; arg0
128136
mov [eax-44], ecx ; user: ds

src/usr/local/src/cat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void process(char filename[]) {
99
return;
1010
}
1111
char buffer[80];
12-
for (size_t i = 0; i < 20; i++) {
12+
while(1) {
1313
if (!fgets(buffer, sizeof(buffer), handler)) {
1414
break;
1515
}

tests/app/cat_test.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ QEMU_SCREENSHOT_NAME="cat_test.ppm"
77
python3 -m tests.qemu.monitor -p ${MONITOR_PORT:?} -sc cat readme.md
88

99
test_create_screen_dump
10-
test_screen_content $LINENO "FuzzyOS"
11-
test_screen_content $LINENO "32-bit x86"
10+
test_screen_content $LINENO "Use make to build binaries and image files"

0 commit comments

Comments
 (0)