Skip to content

Commit e0df643

Browse files
committed
upd: crash redirect to ptys
1 parent 27b0d12 commit e0df643

3 files changed

Lines changed: 83 additions & 0 deletions

File tree

src/cpu/isr.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,85 @@ static void kernel_exception_screen(registers_t *regs)
158158
halt_forever();
159159
}
160160

161+
static void pty_fault_write(pty_buf_t *pty, const char *msg)
162+
{
163+
if (!pty || !msg)
164+
return;
165+
166+
uint64_t rflags = spinlock_acquire_irqsave(&pty->lock);
167+
if (!pty->master_open) {
168+
spinlock_release_irqrestore(&pty->lock, rflags);
169+
return;
170+
}
171+
172+
for (size_t i = 0; msg[i]; i++) {
173+
if (pty->s2m_count >= PTY_BUF_SIZE)
174+
break;
175+
if (msg[i] == '\n') {
176+
pty->s2m_data[pty->s2m_write] = '\r';
177+
pty->s2m_write = (pty->s2m_write + 1) % PTY_BUF_SIZE;
178+
pty->s2m_count++;
179+
if (pty->s2m_count >= PTY_BUF_SIZE)
180+
break;
181+
}
182+
pty->s2m_data[pty->s2m_write] = (uint8_t)msg[i];
183+
pty->s2m_write = (pty->s2m_write + 1) % PTY_BUF_SIZE;
184+
pty->s2m_count++;
185+
}
186+
187+
spinlock_release_irqrestore(&pty->lock, rflags);
188+
}
189+
190+
static void userspace_exception_report(registers_t *regs)
191+
{
192+
task_t *task = sched_current_task();
193+
if (!task) {
194+
sched_yield();
195+
return;
196+
}
197+
198+
task->userspace_faults++;
199+
task->last_userspace_fault = regs->int_no;
200+
201+
fd_entry_t *err = NULL;
202+
if (task->fd_table && task->fd_table->entries[2].used)
203+
err = &task->fd_table->entries[2];
204+
205+
if (err && err->type == FD_PTY_SLAVE && err->pty) {
206+
uint64_t cr2 = 0;
207+
if (regs->int_no == PAGE_FAULT)
208+
asm volatile("mov %%cr2, %0" : "=r"(cr2));
209+
210+
char msg[768];
211+
if (regs->int_no == PAGE_FAULT) {
212+
snprintf(msg, sizeof(msg),
213+
"\n%s: %s in %s (pid %d)\n"
214+
" fault=0x%016lx rip=0x%016lx rsp=0x%016lx error=0x%016lx\n",
215+
"ZenOS", exception_title(regs->int_no), task->name, task->pid,
216+
cr2, regs->rip, regs->userrsp, regs->err_code);
217+
} else {
218+
snprintf(msg, sizeof(msg),
219+
"\n%s: %s in %s (pid %d)\n"
220+
" rip=0x%016lx rsp=0x%016lx error=0x%016lx\n",
221+
"ZenOS", exception_title(regs->int_no), task->name, task->pid,
222+
regs->rip, regs->userrsp, regs->err_code);
223+
}
224+
log(msg, 3, 0);
225+
pty_fault_write(err->pty, msg);
226+
}
227+
228+
task->exit_code = 128 + (int)regs->int_no;
229+
task->state = TASK_DEAD;
230+
sched_yield();
231+
}
232+
161233
void isr_handler(registers_t* regs)
162234
{
235+
if (regs->int_no < 32 && (regs->cs & 3)) {
236+
userspace_exception_report(regs);
237+
return;
238+
}
239+
163240
if (regs->int_no < 32 && !(regs->cs & 3))
164241
kernel_exception_screen(regs);
165242

src/kernel/sched.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ task_t *task_create_user_from_parent(void (*entry)(void), const char *name, page
440440
task->wait_result_pid = -1;
441441
task->waiting_on_pid = 0;
442442
task->wait_collected = 0;
443+
task->userspace_faults = 0;
444+
task->last_userspace_fault = 0;
443445
if (parent && parent->fd_table)
444446
{
445447
task->fd_table = fd_table_clone(parent->fd_table);
@@ -1190,6 +1192,8 @@ pid_t sched_fork(uint64_t syscall_frame_ptr)
11901192
child->wait_result_pid = -1;
11911193
child->waiting_on_pid = 0;
11921194
child->wait_collected = 0;
1195+
child->userspace_faults = 0;
1196+
child->last_userspace_fault = 0;
11931197
child->pinned_cpu = sched_pick_user_cpu_locked();
11941198
child->running_cpu = -1;
11951199
child->last_cpu = -1;

src/kernel/sched.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ typedef struct task
6565
pid_t wait_result_pid;
6666
uint8_t waiting_on_pid;
6767
uint8_t wait_collected;
68+
uint32_t userspace_faults;
69+
uint64_t last_userspace_fault;
6870

6971
uint64_t futex_wait_addr;
7072
int futex_woken;

0 commit comments

Comments
 (0)