@@ -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+
161233void 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
0 commit comments