Skip to content

Commit aca717e

Browse files
committed
Non-thread processes are not killed with parent
When parent process is being killed, it kills other child threads first. Non-thread child processes are not killed but become child of the root process. Also includes: * Process management doc update
1 parent e5c80b5 commit aca717e

File tree

2 files changed

+52
-13
lines changed

2 files changed

+52
-13
lines changed

docs/notes/processman.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ Every process has its own process & thread have individual event queue.
132132

133133
### Process exit
134134

135-
Exiting threads is the simplest. Since they only have a stack, exiting threads means to only
135+
Exiting threads are the simplest, since they only have a stack, exiting threads means to only
136136
deallocate the virtual & physical memory for its stack, and freeing the memory used by process's
137137
events and removing the thread from the scheduler queue. That is steps 1 to 4 don't happen for
138138
threads but 5,6 does happen.
@@ -164,6 +164,17 @@ killed by pushing a `KERNEL_EVENT_PROCCESS_CHILD_KILLED` event.
164164

165165
Through this event the parent can determine if a child process has exited and in what condition.
166166

167+
When a process exits, it must also kill its child threads. Child non-thread processes however are
168+
not killed and become children of the Root process.
169+
170+
### Abort
171+
172+
Abort is called when there is a serious error or corruption in the application program. For example
173+
malloc() calls abort when it detects a double free/allocation. The Abort call should kill all
174+
processes what is using the current memory context, that is threads and the parent process. Child
175+
non-thread processes however are not killed since they have a different memory context. These
176+
processes get owned by the Root process.
177+
167178
------------------------------------------------------------------------------
168179

169180
## Problem with creation of new process from a kernel process

src/kernel/x86/process.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
static UINT processCount;
3434
static KProcessInfo* currentProcess = NULL;
35+
static KProcessInfo* rootProcess = NULL;
3536
static ListNode schedulerQueueHead = { 0 };
3637

3738
static bool s_switchProcess (KProcessInfo* nextProcess, ProcessRegisterState* currentProcessState);
@@ -49,6 +50,7 @@ static void s_showQueueItems (ListNode* forward, bool directionForward);
4950
#else
5051
#define s_showQueueItems(...) (void)0
5152
#endif // DEBUG
53+
static void change_parent_process (KProcessInfo* const p, KProcessInfo* const parent);
5254

5355
__attribute__ ((noreturn)) void jump_to_process (U32 type, x86_CR3 cr3, ProcessRegisterState* regs);
5456

@@ -399,6 +401,13 @@ static bool s_switchProcess (KProcessInfo* nextProcess, ProcessRegisterState* cu
399401

400402
nextProcess->state = PROCESS_STATE_RUNNING;
401403
currentProcess = nextProcess;
404+
405+
// Root process is set at the time of switching and not at creation time to ensure that the
406+
// creation of the root process was successful.
407+
if (currentProcess->parent == NULL) {
408+
rootProcess = currentProcess;
409+
}
410+
402411
jump_to_process (nextProcess->flags, cr3, reg);
403412

404413
UNREACHABLE();
@@ -445,12 +454,23 @@ static bool kprocess_kill_process (KProcessInfo** process, U8 exitCode)
445454
if (!(cpinfo = LIST_ITEM (node, KProcessInfo, childrenListNode))) {
446455
FATAL_BUG();
447456
}
457+
448458
INFO ("Killing child process. PID: %u", cpinfo->processID);
449-
if (!kprocess_kill_process (&cpinfo, KPROCESS_EXIT_CODE_FORCE_KILLED)) {
450-
FATAL_BUG(); // Under normal condition its not possible for such a failure.
459+
460+
// Only thread process are killed. Non-thread processes are made child processes of the
461+
// Root process.
462+
if (BIT_ISUNSET (cpinfo->flags, PROCESS_FLAGS_THREAD)) {
463+
INFO ("Non thread process cannot be killed. Being adopted by root process.");
464+
change_parent_process(cpinfo, rootProcess);
465+
k_assert (cpinfo->parent == rootProcess, "Wrong parent set for process");
466+
} else {
467+
INFO ("Killing child thread process. PID: %u", cpinfo->processID);
468+
if (!kprocess_kill_process (&cpinfo, KPROCESS_EXIT_CODE_FORCE_KILLED)) {
469+
FATAL_BUG(); // Under normal condition its not possible for such a failure.
470+
}
451471
}
452472
}
453-
INFO ("All child processes killed. Now killing parent: %x", l_process->processID);
473+
INFO ("All child processes killed/adopted. Now killing parent: %x", l_process->processID);
454474

455475
// If current process is not the process being killed, then there is no need to change
456476
// Page Directories.
@@ -523,6 +543,20 @@ static bool kprocess_kill_process (KProcessInfo** process, U8 exitCode)
523543
}
524544
#pragma GCC diagnostic pop
525545

546+
static void change_parent_process (KProcessInfo* const p, KProcessInfo* const parent)
547+
{
548+
// Root process cannot be child of another process
549+
k_assert (p != rootProcess, "Child process cannot be child of another process");
550+
551+
// Remove the process from the list of its current parent
552+
list_remove (&p->childrenListNode);
553+
554+
// Processes created by threads are owned by its parent process.
555+
p->parent = BIT_ISSET (parent->flags, PROCESS_FLAGS_THREAD) ? parent->parent : parent;
556+
// Add the process to the list of its new parent.
557+
list_add_before (&p->parent->childrenListHead, &p->childrenListNode);
558+
}
559+
526560
void kprocess_init()
527561
{
528562
list_init (&schedulerQueueHead);
@@ -580,18 +614,12 @@ INT kprocess_create (void* processStartAddress, SIZE binLengthBytes, KProcessFla
580614
// Root processes does not have a parent.
581615
pinfo->parent = NULL;
582616
if (currentProcess == NULL) {
583-
// Must be creation of root process. Must not be a flag
584-
k_assert (BIT_ISUNSET (pinfo->flags, PROCESS_FLAGS_THREAD), "Orphan thread");
617+
// Must be creation of root process. Must not be a thread process.
618+
k_assert (BIT_ISUNSET (pinfo->flags, PROCESS_FLAGS_THREAD), "Threads cannot be Root");
585619
INFO ("Root process creation");
586620
} else {
587-
// Processes created by threads are owned by its parent process.
588-
pinfo->parent = BIT_ISSET (currentProcess->flags, PROCESS_FLAGS_THREAD)
589-
? currentProcess->parent
590-
: currentProcess;
591-
621+
change_parent_process (pinfo, currentProcess);
592622
k_assert (pinfo->parent != NULL, "Non-Root processes & Threads must have a parent");
593-
// Parent is non-root process
594-
list_add_before (&pinfo->parent->childrenListHead, &pinfo->childrenListNode);
595623
}
596624

597625
INFO ("New process: ID = %u, Parent ID: %u", pinfo->processID, PARENT_PROCESS_ID (pinfo));

0 commit comments

Comments
 (0)