ещё настойчиво рекомендую в `HandleTrap()` сделать примерно вот так:
Код:
PROCEDURE GetSigILLVal (pc: ADDRESS): INTEGER;
VAR err, val: INTEGER;
BEGIN
err := 202; val := 0;
IF platform.p.IsReadable(pc, pc + 4) THEN
S.GET(pc, val);
IF val MOD 100H = 8DH THEN (* lea reg,reg *)
IF val DIV 100H MOD 100H = 0F0H THEN
err := val DIV 10000H MOD 100H (* trap *)
ELSIF val DIV 1000H MOD 10H = 0EH THEN
err := 128 + val DIV 100H MOD 10H (* run time error *)
END
END
END;
RETURN err
END GetSigILLVal;
(* check if we are inside a Kernel/HostKernel, or OS libraries *)
PROCEDURE CheckPC (pc: ADDRESS): INTEGER;
VAR
res: INTEGER;
mod: Kernel.Module;
BEGIN
mod := Kernel.modList;
WHILE (mod # NIL) & ((pc < mod.code) OR (pc >= mod.code + mod.csize)) DO
mod := mod.next
END;
IF mod # NIL THEN
IF (mod.name = "Kernel") OR (mod.name = "HostKernel") THEN res := pcInKernel
ELSE res := pcInModule
END
ELSE pc := pcInOSLibs
END;
RETURN res
END CheckPC;
PROCEDURE [cdecl] HandleTrap (sig: INTEGER; siginfo: Libc.Ptrsiginfo_t; context: Libc.Ptrucontext_t);
VAR
inSignalStack: BOOLEAN;
oldpc, oldfp: ADDRESS;
pcpos: INTEGER;
BEGIN
pcpos := CheckPC(context.uc_mcontext.gregs[14]); (* pc *)
IF sig = Libc.SIGINT THEN
(* ignore Ctrl+C if we are in some unsafe to break code *)
IF pcpos # pcInModule THEN
RETURN
END;
ELSE
(* if we trapped inside a kernel, panic and exit, this should not happen!
if we will not panic, recursive traps may occur.
FIXME! *)
IF pcpos = pcInKernel THEN
(* FIXME: this is dangerous; i should find another way to allow asserts/halts in kernel! *)
CASE sig OF
| Libc.SIGILL: (* this is either HALT or runtime error *)
pcpos := GetSigILLVal(context.uc_mcontext.gregs[14]);
IF pcpos >= 128 THEN (* runtime error *)
log.String("FATAL: runtime error"):Int(pcpos - 128):
String(" in Kernel, PC="):Adr(oldpc):String(". Aborting immediately."):Ln;
Libc.exit(2)
END
| Libc.SIGSEGV:
log.String("FATAL: segmentation fault in Kernel, PC="):Adr(oldpc):String(". Aborting immediately."):Ln;
Libc.exit(2)
ELSE END CASE
END
END;
sp := context.uc_mcontext.gregs[7]; (* stack pointer *)
fp := context.uc_mcontext.gregs[6]; (* frame pointer *)
…и так далее…
ну, вы поняли идею. делать ^C в ядре нельзя, потому что мы можем быть посреди процесса сборки мусора, и в итоге память окажется порубаной в лапшу. виндоядро имеет такую охрану, а позикс-ядра нет, и в итоге в позиксах ^C — русская рулетка.
в общем, сделайте что-то по мотивам этого кода у себя.