• Please review our updated Terms and Rules here

How to kill a child process ?

wiwa64

Experienced Member
Joined
Aug 28, 2008
Messages
100
Location
Germany
It may not be so widely known, but even as (MS-)DOS is intended to be a single-user single-program operating system, one program (process) can spawn another process in several ways. A very handy one is the C-function "system(<program name>)" which simply runs a child process, while the parent process is waiting. As soon as the child completes, the child is removed from memory and control returns to the parent.

So far, everything works fine. Now parents tend to be curious wanting to know what their children do. To achieve this, the parent process hooks into the timer interrupt, installing an interrupt routine which regularly interrupts the child, temporarily returning control back to the parent, performing some work and then switching back to the child. This continues until the child completes its task and permanently returns control back to the parent process. Even this works fine, so far.

Unfortunately there are "nasti" children, child processes that fail to complete, locking-up the whole system by not (permanently) returning control back to their parent process. In such a situation the parent process has to terminate (that sound less cruel than "kill") the child process from within the interrupt routine, as this is the only way for the parent process to do anything, while the child ist still running.

But how can this be done? The apparently obvious way, making a "termiate process" call (of course with the process-ID switched to the child) doen't work satisfacturely. Even though it does terminate the child, it leaves the parent in an unstable condition unsuitable for further operation.

Any ideas what i might be missing?
 
My only experience with this type of thing has been in assembly, managing my own system calls. I haven't the faintest idea of what C is doing.

It's probably best that the parent process owns and controls all resources, even those of the child. That way, the parent can simply deallocate the memory allocated to the child and unhook any interrupts that were hooked by the child. All time-slicing interrupts, of course, should proceed first through the parent (and return through it) so that child program hangs can be detected.

In other words, build your own multi-tasking executive on top of DOS instead of expecting DOS to supply the functionality.
 
hanging

hanging

Can you give some more details about why the child tasks hang ? There's no real reliable way supported by DOS to kill child processes.
How are you launching your child processes ? Strictly from C, or are you using DOS's EXEC mechaism ?
DOS doesn't really do a good job of managing memory so it's up to your parent and child process to ensure they don't get in each other's way.

DOS doesn't support a lot of things, there's no pre-emptive multitasking, and DOS interrupt handlers are typically aren't reentrant, so if you're currently in the midst of handling your child-checking timer tick and another timer tick comes through, bad things happen unless you've masked the tick with STI during your watchdog & released it with CLI.

That said, what's your target processor that you're writing for ? Depending on what you're writing for there might be possibilties.

Or, instead of hanging of the timer tick, you might want to put this watchdog functionality into a TSR or something, but I don't really know enough about what you're running to be able to say if this would work or not.

What you really want is a NMI to interrupt your process, unfortunately, on the PC, only parity errors and 8087's throw NMI's.

Are you stuck with DOS, or can you try another OS ?

patscc
 
... How are you launching your child processes ? Strictly from C, or are you using DOS's EXEC mechaism ? ...
Well, i launch it "strictly" from C, which in turn uses DOS's EXEC mechaism

... DOS doesn't really do a good job of managing memory so it's up to your parent and child process to ensure they don't get in each other's way.

DOS doesn't support a lot of things, there's no pre-emptive multitasking, and DOS interrupt handlers are typically aren't reentrant, so if you're currently in the midst of handling your child-checking timer tick and another timer tick comes through, bad things happen unless you've masked the tick with STI during your watchdog & released it with CLI. ...
That's not the problem. Under normal conditions, the two processes co-exist peacefully and everything works fine. The challenge is to properly bring the system back into a safe state if something (external to the mashine) went wrong.

... That said, what's your target processor that you're writing for ? Depending on what you're writing for there might be possibilties. ...
I don't see how the target processor could have much influence on the problem.

... Or, instead of hanging of the timer tick, you might want to put this watchdog functionality into a TSR or something, but I don't really know enough about what you're running to be able to say if this would work or not. ...
The problem is not to detect the execptional situation, the problem is to bring the system back into a safe state after having detected it. All a watchdog would do, is reboot the mashine. Well, that's easy and i don't need a watchdog for this. Unfortunately this procedure is time-consuming and the state of the parent process is lost.
 
After having thought more intensively about the problem, i came to the conclusion, that there is probably no general solution.

Considering that the child process can be any DOS program, which in turn can modify its operating environment in almost any way, it is up to that program to clean-up upon termination and no one else could do this job.

No other program nor DOS itself "knows" what the child has done, so simply terminating it, will always risk to leave the system in an undefined state.

Nevertheless should anyone have a clever idea about it, feel free to communicate it.
 
processor

processor

wiwa64 said...I don't see how the target processor could have much influence on the problem[/b]
Because from the 286 onwards, additional logic & instructions are present which make pre-emptive multitasking a lot easier, so it's a lot easier to yank control from a hung program, which is a prelude to killing your 'misbehaving' child process.
wiwa64 also said...he challenge is to properly bring the system back into a safe state if something (external to the mashine) went wrong.
See, this is where DOS's lack of reentrancy comes into play. PC's usually deal with external, unexpected events by the maskable interrupt mechanism. So, if you' re in your timer handler, and you've got the interrupts masked, the system won't respond to the interrupt, or, alternately, the system does respond to the external condition while you're in your timer handler and you didn't mask interrupts, and along comes another timer tick, you've just reentered your handler causing all kinds of unpredictable issues.
wiwa64 posted later...which in turn can modify its operating environment in almost any way,
And it might even re-hook your new timer handler.
You might want to see if you can dig up a copy of DR-DOS. I seem to remember it offered task-switching support, but you'd best verify that, or maybe someone is reading this that actually has DR-DOS and knows more about it.
patscc
 
Why not use one of the multi-tasking message-passing executives written for DOS? It seems to me that you're trying to invent a solution for something that's been solved for at least 20 years.
 
tasks

tasks

Chuck(G) said...multi-tasking message-passing executives written for DOS
Like which ones ?
Anyway, it sounds like he's trying to do this on a 8088, and since there aren't any processor-supported privilege levels, there's nothing to prevent his child process from trashing the main process. DOS will gleefully let you write anywhere in memory you feel the need to.
patscc
 
Like which ones ?
Anyway, it sounds like he's trying to do this on a 8088, and since there aren't any processor-supported privilege levels, there's nothing to prevent his child process from trashing the main process. DOS will gleefully let you write anywhere in memory you feel the need to.

Yes, but there are/were packages that handle resource allocation, multitasking, etc. even on an 8088. Protection is of course, non-existent, but that's only a small aspect.

MS-DOS was never intended as a multi-tasking OS and many of its facilities (e.g. memory management) are unsuited to dynamic process execution and resource allocation.

You can get anything from text-mode Windows lookalikes (e.g. MEWEL) to plane-jane multitaskers (e.g. MT, TAME and a raft of others).

Back in the 90's, I was impressed enough with MEWEL to purchase a souce-code license for it from the author.
 
Thank you for your proposals to solve the problem.

I must admit however, that i did not consider them as fully satisfactory. Implementing a full-blown multi-tasking package, to solve a problem that makes up less then 1% of the actual task, appears to me like overkill.

Nevertheless i believe to have found a solution that might not be perfect but pragmatic. If you are curious about the details, feel free to explore my latest project RMENU, presented in the thread: "Remote control of DOS-Box"
 
Back
Top