feat: add support for console sessions to crashpad and crash handling in kernel

This commit is contained in:
2026-06-18 12:56:29 +02:00
parent e3c551b9f6
commit ac25a4edd5
5 changed files with 141 additions and 37 deletions
+49 -3
View File
@@ -1388,11 +1388,57 @@ namespace Sched {
return &processTable[slot];
}
int SpawnCrashPad() {
int SpawnCrashPad(int crasherPid) {
// Spawn crashpad as a child of init (slot 0), not the crashing process.
// We can't use the current process context since we're in ExitProcess.
// The crasher is still alive here (we run before its ExitProcess), but
// it is about to die, so we must not parent the crashpad to it.
static constexpr const char* crashpadPath = "0:/apps/crashpad/crashpad.elf";
return Spawn(crashpadPath, nullptr);
// If the crashing process had a redirected console (i.e. it was running
// under terminal.elf in a console session), hand the crashpad a write
// handle to that same out-stream so it can surface a textual crash
// report to the console user when no desktop is running.
Process* crasher = GetProcessByPid(crasherPid);
int crasherSlot = Ipc::SlotForPid(crasherPid);
bool inheritRedir = crasher && crasher->redirected &&
crasher->ioOutHandle >= 0 && crasherSlot >= 0;
Ipc::Object* outObj = nullptr;
Ipc::HandleType outType = Ipc::HandleType::None;
uint32_t outRights = 0;
if (inheritRedir) {
if (!Ipc::SnapshotHandleForSlot(crasherSlot, crasher->ioOutHandle,
outType, outObj, outRights) ||
outType != Ipc::HandleType::Stream || outObj == nullptr) {
inheritRedir = false;
}
}
// Deferred start when inheriting, so we can wire ioOutHandle before _start.
int childPid = Spawn(crashpadPath, nullptr, /*startReady=*/!inheritRedir);
if (childPid < 0 || !inheritRedir) return childPid;
Process* child = GetProcessByPid(childPid);
int childSlot = Ipc::SlotForPid(childPid);
if (child && childSlot >= 0) {
// Installing with RightWrite retains the stream (writerRefs++/refs++),
// so it outlives the crasher's imminent ExitProcess teardown. The
// snapshot above and this install run back-to-back with no blocking
// call between, while the crasher's handle still pins the stream.
int h = Ipc::InstallHandleForSlot(childSlot, outObj, Ipc::HandleType::Stream,
Ipc::RightWrite | Ipc::RightWait | Ipc::RightDup);
if (h >= 0) {
child->ioOutHandle = h;
child->redirected = true;
child->parentPid = crasherPid;
child->termCols = crasher->termCols;
child->termRows = crasher->termRows;
}
}
// Always start it (even if wiring failed -> it just falls back to silent).
StartProcess(childPid);
return childPid;
}
}