Reputation: 55
int main(){
while(1)
{
//code
}
return 0;
}
This is an infinite loop, but will this lead to a system crash?
How does it behave?
I am thinking that it will eat up all the stack segment.
Upvotes: 3
Views: 7129
Reputation: 48020
Short answer: no, this will definitely not lead to a system crash.
There are two longer answers:
(1) This program is a straightforward infinite loop. It will cause the processor to work as hard as it can, doing absolutely nothing. So, yes, the processor will work hard -- but it won't break, because it's not doing anything "wrong", and there's nothing to use up or wear out.
Imagine you have a really nice car. A magically nice car. Imagine it can go up to 150 mph, and it gets an infinite number of miles per gallon, so it never runs out of fuel. Now imagine you have an infinitely long, perfectly straight road. You get out on that perfect road with this perfect car, and you floor it, and pretty soon you're going 150 mph, and you can do this as long as you want -- because, what's going to stop you?
Now, in the real world, of course, there's no car that's that perfect: besides fuel, all real cars need periodic lubrication and other maintenance, and they eventually wear out. But I don't think it's wrong to think of a computer as a perfect machine: It is perfectly happy to sit there and work as hard as it can for basically ever.
(Now, that's not quite true. In the real world, computers, like cars, do eventually wear out. And if the computer has been overclocked, or if someone skimped and didn't put a big enough heat sink on the CPU, then running it flat out like this will probably cause it to heat up and shorten its life. But that's not really the kind of "system crash" we're talking about here anyway.)
(2) The other answer is that even if an infinite-loop program like this did do something wrong, like trying to call a recursive function an infinite number of times, or allocate an infinite amount of memory, or open an infinite number of files -- even in those sorts of cases, a single badly-behaving program isn't supposed to crash the whole system. The program may crash, but not the system.
It's one of the primary duties of an operating system to ensure that ordinary application programs can't interfere with each other, or with the operating system itself. If an ordinary application program can crash the whole system, there's a serious bug -- a serious bug in the operating system.
Now, this was not true in the bad old days of cooperative multitasking, and it was not true in the bad old days of Microsoft Windows (where Blue Screens Of Death were commonplace). It's also not true if you're doing embedded programming. But on a modern OS (and this definitely includes the brave new world of smartphones), badly-behaving applications can't crash the system, because system crashes are unacceptable, and also because applications aren't trustworthy, can't be trusted to not misbehave.
Upvotes: 1
Reputation: 155443
this is an infinite loop
It is. I note that a decent modern C compiler will give you a warning about it, btw.
but did this lead to a system crash?
No, it won't.
If it's a userland process, it won't lead to a "system" (kernel) crash because it doesn't corrupt or misuse kernel resoures.
The code you posted, as-is, won't lead to a process crash either, because there's nothing illegal or undefined in the code either (it just won't do anything useful).
Basically, this (if compiled without optimization):
# Instruction
1 main:
2 push rbp ; `int main` function prologue
3 mov rbp, rsp ;
4 .loop:
5 jmp .loop ; Jump to right before this instruction
You can see this for yourself using a compiler output explorer site like godbolt.org: https://godbolt.org/z/BMzh7i - note there are no changes to the stack-pointer (in rsp
- ignore the mov
in the function prologue, that's unrelated to the while
loop)
how does this behaves?
It would be compiled to a trivial unconditional branch in assembly code that jumps infinitely. (It won't cause a system-hang because the OS controls the preemptive multi-tasking interrupt timer handler).
I am thinking - it will eat up all the stack segment.
It won't because the code you posted doesn't increment the stack-pointer (e.g. by allocating anything on the stack inside the loop without decrementing the stack-pointer, or by making a function call inside the loop without popping the called function's frame - this can happen if you use the wrong calling-convention, but that's an advanced topic).
If you have a local variable inside the while loop, that won't actually cause an allocation for-each-iteration because the previous iteration's values aren't accessible anymore - so this...
while( 1 ) {
int foo;
int ok = fscanf( fd, "%d", &foo );
if( !ok ) break;
}
...is equivalent to this:
int foo;
int ok;
while( 1 ) {
ok = fscanf( fd, "%d", &foo );
if( !ok ) break;
}
(This is also why very old programming languages often had you declare all local variables at the start of the function instead of allowing declaration inside the function - they don't anymore because thankfully language designers care more about language-ergonomics now than they used to).
Generally speaking, never call malloc()
without calling free()
(or more generally: never acquire resources without releasing them), so this code will cause your program to run out of memory eventually:
while( 1 ) {
void* ptr = malloc( 1024 )
}
...but this won't:
while( 1 ) {
void* ptr = malloc( 1024 );
if( ptr ) free( ptr );
}
(well, it might run out of memory due to heap fragmentation depending on how good your malloc
implementation is)
C makes it surprisingly hard to directly manipulate the stack (for example, tail-call optimization requires the compiler to handle it as an optimization: you can't force a tail-call return using a C language feature, unfortunately) - so (to my knowledge) there's only two main ways you can blow the stack:
The main way to overflow the stack is by pushing more stack-frames without popping them - this can be done by having an infinitely recursive function call (without the tail-call optimization).
...or by doing something silly and/or stupid, e.g. by using alloca
(like malloc
, but allocates memory on the stack: but doesn't tell you if it failed).
Upvotes: 8
Reputation: 344
That is the asm code of your loop. It just jump to the previous line of code
.L2:
jmp .L2
This pat of your code dont need any memory
Upvotes: 0