Reputation: 971
int w(int x, int y){
if(x != y) {
w(x, y);
}else return x+y;
}
Call it this way:
w(0, 5);
For distinct values (like above), it generates an infinite recursion. The problem is, once the program started this way, the specific process turns into a D mode (waiting for an internal I/O, therefore untouchable).
while(1){
if(0 != 5){
//foo
}else{
//bar
}
}
Generates R state mode - perfectly capable of getting SIGKILL.
Although normal loops beat recursions performance-wise; the system should still be capable of killing the process.
Why is this happening? And how to prevent it remotely?
The code will be compiled an executed by a program that returns its output to the webclient via sockets. So there is no control over what the user attempts to compile.
Edit:
Ubiquitous process of compiling and running the code:
$ g++ main.cpp -o m
$ ./m
Edit2:
$ g++ --version
g++ (GCC) 4.9.2 20150204 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ df --print-type
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/sda2 ext4 957174124 168965980 739563400 19% /
dev devtmpfs 4087124 0 4087124 0% /dev
run tmpfs 4089872 528 4089344 1% /run
tmpfs tmpfs 4089872 76 4089796 1% /dev/shm
tmpfs tmpfs 4089872 0 4089872 0% /sys/fs/cgroup
tmpfs tmpfs 4089872 1052 4088820 1% /tmp
tmpfs tmpfs 817976 12 817964 1% /run/user/1000
The tests were done on Arch Linux x64 (with latest gcc).
Edit3:
The same problem occurs even after reinstalling the OS. The image has been used on another pc as well, where this problem does not occur.
Upvotes: 9
Views: 254
Reputation: 14360
I will start with a cite from this answer(zerodeux): Linux Process States.
... The D state (TASK_UNINTERRUPTIBLE) is a special sleep mode which is only triggered in a kernel space code path, when that code path can't be interrupted (because it would be to complex to program), most of the time in the hope that it would block very shortly. I believe that most "D states" are actually invisible, they are very short lived and can't be observed by sampling tools such as 'top'.
So, it's possible the kernel set the D state for a process that it's calling some function (at the exact moment the function it's being called and nothing else) becouse that involve memory work, call stack modifications, and other complex things.
Your code left almost no time between w(x, y)
calls so it's possible that is causing you to see the continuous D state.
I could not reproduce your code's behaviour, but I have an experiment in mind, set a time sleep (about a second is enough) before call w(x, y)
, and see what happends.
On the other hand, I think the program is actualy being executed, in fact in your code you're passing x
and y
as values so, in every call copies will be made and that will comsume memory(the call stack also consumes memory). You can then (another experiment) check for the memory consumption, if the program is not being executed, the memory consumtpion stay the same in time.
Upvotes: 1
Reputation: 21528
I'm not sure to have undertood:
Launch your command in this way:
./m & echo $! > mpid
So to kill process:
kill $(cat mpid)
Upvotes: 1