1
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.

liakoyras
  • 783
  • 10
  • 22
Lilee Naik
  • 35
  • 2
  • 4
    Short answer: no. That's exactly how many *[daemons](https://en.wikipedia.org/wiki/Daemon_(computing))* work. – pmg Sep 09 '19 at 09:30
  • 2
    Infinite recursion would eat up the stack, but normally not infinite loops (unless they do something odd like `alloca`) – harold Sep 09 '19 at 09:32
  • 1
    That function needs no stack at all. Even if the prologue/epilogue are not omitted, the stack usage is constant. – Margaret Bloom Sep 09 '19 at 09:32
  • 1
    although as written it will eat up a lot of cpu (probably an entire cpu thread) - it's basically a busy wait. – Sander De Dycker Sep 09 '19 at 09:32
  • Doing a infinite loop without sleep will lead your cpu to be at full capacity all the time and will make your computer slow down. But it will not crash. – Tom's Sep 09 '19 at 09:37
  • An equivalent construct (some people prefer) (with no *[magic number](https://en.wikipedia.org/wiki/Magic_number_%28programming%29)*) is `for (;;) { /* code /* }` – pmg Sep 09 '19 at 09:38
  • An infinite loop (of any type) does not, in itself, cause a system crash, nor does it "eat up the stack segment". The body of the loop (the action the loop performs on each iteration) might do something that results in a system crash. On modern operating systems, that is easier said than done - for example, a program that exhausts available memory will probably be terminated by the operating system, rather than crashing the system. [And, no, I'm not going to describe techniques that are likely to crash the system]. – Peter Sep 09 '19 at 10:13
  • "I am thinking that it will eat up all the stack segment." -- **why** would it? Loops don't keep allocating space on the stack, function calls do. – Marco Bonelli Sep 09 '19 at 10:43
  • @Tom's If you have a multicore CPU., it might not even slow down. – Steve Summit Sep 09 '19 at 15:08
  • @SteveSummit Are you sure ? I remember doing that mistake on a physics dualcore and the cpu haven't really liked it (it was the first time that I was seeing a cpu over 100% ...). – Tom's Sep 09 '19 at 15:16
  • @Tom's Obviously it depends, and I did say "might". But I just typed `while(1);` into a C interpreter I have handy (which since it's 10 or 100 times less efficient than compiled code, is an even more burdensome loop), and indeed `ps` says it's taking 100% of a CPU, but otherwise the machine seems normal. – Steve Summit Sep 09 '19 at 15:23

3 Answers3

7

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).

What if...?

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).

...but...

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)

Don't forget recursion

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).

Dai
  • 110,988
  • 21
  • 188
  • 277
  • I don't think the `if( ptr )` is needed. `free` works fine on `NULL` pointers. – S.S. Anne Sep 09 '19 at 11:37
  • Also note that C doesn't mandate a stack, which is probably why the stack is so hard to modify. – S.S. Anne Sep 09 '19 at 11:38
  • You are making a whole lot of assumptions here. The system might as well be an embedded system and then most of this answer is irrelevant, while the ways to blow the stack are many more than those you describe. System-independent: declaring too large local variables will blow the stack. – Lundin Sep 09 '19 at 12:52
0

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

brfh
  • 290
  • 1
  • 9
0

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.

Steve Summit
  • 29,350
  • 5
  • 43
  • 68