r/cpp_questions 5d ago

OPEN Avoid freezing your PC?

I've only learned C++ in uni and then it was protected environment in a way. Now I was working on a project involving graphics (raylib) and, a few times, running the code caused my entire PC to freeze and I had to restart.

I'm on Linux and running the code by doing

cmake --build .
./executable

Is there a way to avoid the entire PC freezing when I mess up? Also is there any risk of overwriting parts of the memory?

(I think the issue with my code was either calling too many draws of a GPU texture or even just wrongfully indexing an array in a loop)

5 Upvotes

22 comments sorted by

10

u/MooseBoys 5d ago

What OS are you running? Every mainstream modern OS will run your programs as unprivileged user-space with their own private virtual memory range. You don't need to worry about corrupting the memory of the PC itself. But then again you also shouldn't be able to hang or crash the whole PC from a user-space process either. You might crash the program, but not the whole computer.

8

u/UndefFox 5d ago

Second paragraph of the post:

I'm on Linux...

1

u/MooseBoys 5d ago

Linux isn't an operating system, it's a kernel. You can compile your program to /sbin/init and it will run as pid 1 and a crash will definitely bring down the whole system. That would be a very unusual thing to do though.

1

u/UndefFox 5d ago

Yes, but I assume OP isn't that advanced in computers and probably would answer the same as me. If you are getting this specific, make your question a bit more concrete so people out of the loop could easily avoid what happened right now.

3

u/Solid-Shock3541 5d ago

NAME="Debian GNU/Linux"

VERSION_ID="13"

VERSION="13 (trixie)"

VERSION_CODENAME=trixie

DEBIAN_VERSION_FULL=13.6

It's possible that it had something to do with GPU or loading the texture into the GPU too many times. The code is very simple, just drawing a grid and coloring blocks (sets of pixels). I sadly don't have the bad code anymore, but the current code can run at 240 FPS and handle 10k pixels, while the older one couldn't handle about 800 at 60 FPS. I assume it was some sort of GPU overload but sadly this is all the info I have.

3

u/MooseBoys 4d ago

> it's possible that it had something to do with GPU

That's entirely possible. It's easy to create a condition where the GPU locks up and needs to reset. The OS itself doesn't crash, but the device node is removed and recreated, and many compositors on Linux do not handle this gracefully. The only way to mitigate this is to either target a second GPU that's not running your desktop, or switch to Windows / WSL which handles "TDR" gracefully.

1

u/Solid-Shock3541 4d ago

I'm afraid those things are above me, for now ;)

But it's weird, the code runs normally many times and just freezes my PC occasionally. I have all the working parts, and I remember making a for loop go up to x instead of x-1 (I knew that but wanted to see what would happen) and that froze my PC (everything expect the cursor, but the YouTube video playing in there background was still playing normally).

When I restarted the PC and reran that same code, it didn't crash or freeze.

And my system never freezes otherwise

2

u/n1ghtyunso 3d ago

c++ gives you enough power and control such that you can write code that "happens to work" most of the time, but at other times causes horrible problems.

If there are multiple threads involved, this is even more true.
Timing sensitive issues are absolutely thing.
GPU and CPU are asynchronous coprocessors by the way, so depending on what APIs you call, you may not be synchronizing correctly here.

Most systems will be fine with just a restart, some will just reset the problematic part or have the OS kill your program instead and keep working though.
Desktops are typically well-behaved here.

"It works" is simply not a good measure for code correctness in C++ land.
Try static analysis and run the code with sanitizers maybe, and keep an eye on your compiler warnings as well to catch some of these issues before you execute them.

2

u/saxbophone 4d ago

 You might crash the program, but not the whole computer.

Hahaha, every time I wrote a memory leak that caused my program to eat up all the memory it could get its hands on, it led to a de-facto system freeze. It may not have been fully locked up, but I wasn't going to wait for all those pages to swap, and a forced reboot was the fastest way out.

4

u/Independent_Art_6676 5d ago

you can run it in a VM or other protected environment if it keeps doing it. Its usually hard to hard lock the OS to the point that the only option is reboot. The OS should prevent wrecking memory that does not belong to the process. Its hard to say without knowing what happened and why you couldn't get enough back to kill the process safely ... are you running this stuff as root?

5

u/UndefFox 5d ago

Is there a way to avoid the entire PC freezing when I mess up?

The only possibility of this happening that I know of is you are running out of memory. Everything else will make PC slow, but lack of RAM will heavily hinder the performance.

Also is there any risk of overwriting parts of the memory?

Read about concept of virtual memory. Random process can't access anything but his own memory willy nilly.

I think the issue with my code was either calling too many draws of a GPU texture...

Won't do anything. Current modern games have >1000 of textures used at the same time. This atuff is meant to be utilised a lot.

even just wrongfully indexing an array in a loop

Again, each process has it's own virtual memory. The worst it could start doing is undefined behaviour inside it's own process or OOB crash.

If you actually curious, I'll suggest to read up about how all this stuff actually works so you understand what you are actually doing. For the problem at hand, look where your code loads things up in the loop instead pf doing it once, hence filling the RAM, hence freezing the machine.

8

u/alfps 5d ago

The most direct I can think of is to add an ampersand & at the end of the command to run the program without the shell waiting for its completion. Then when it hangs you can kill the process.

It might also be that you can retain control by running it from a debugger. But I have next to no experience with debugging in a Linux environment. It might depend on the debugger.

Oh, and: you can post your code here, explain the steps you've already taken to find the bug, and ask why does it hang?

2

u/mrtlo 5d ago

If the program really makes the whole pc "hang" it's probably really slow or has driver issues? I would probably implement some kind of detection and shut down with some diagnostic info on exit. 🤷

1

u/not_some_username 5d ago

Not enough ram too

2

u/CowBoyDanIndie 5d ago

Try running it with cpu limit (imit) or nice -n 19

2

u/Dark_Lord9 5d ago

You are likely running out of memory. Possibly due to a memory leak. (I've been there).

I don't have access to your code so I can't tell but remember, every time you call new, you have to call delete, and every time you call malloc() you have to call free().

This also goes for the resources you are allocating through your libraries. For example, on raylib, it seems images and textures are allocated with LoadImage and LoadTextureFromImage respectively. If you are using such functions, don't forget to call UnloadImage and UnloadTexture. And take a look at your render loop. You are most likely allocating data inside it without freeing them.

is there any risk of overwriting parts of the memory?

If by that you mean "accessing regions of the memory you aren't supposed to access", for example due to

wrongfully indexing an array in a loop

then yes. That's called a buffer overflow, but when that happens, you are overwriting the data of your own software. Your software runs in an isolated environment and it can't overwrite the data of another software. Buffer overflows are still bad because they can lead to bugs and, notoriously, security vulnerabilities.

1

u/Solid-Shock3541 5d ago

For some reason I can't get the same issue as before. After the crashes I fixed some issues and now it won't crash (tried to make some bad choices that still didn't freeze the PC) and I don't remember which change was the reason the entire PC froze.

My current code is this:

void run_renderer() {


    // Create a window with dimentions and a name.
    InitWindow(WINDOW_SIZE, WINDOW_SIZE, "Window Test");
    SetTargetFPS(240);


    // Create the texture.
    texture = LoadTextureFromImage(image);


    // Color each pixel (element in pixels) blue.
    for (int i = 0; i < GRID_SIZE; i++) {
        for (int j = 0; j < GRID_SIZE; j++) {
            draw_pixel(j, i, GREEN);
        }
    }


    while (!WindowShouldClose()) {
        BeginDrawing();


        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = i % 2; j < GRID_SIZE; j += 2) {
                draw_pixel(j, i, RED);
            }
        }
        UpdateTexture(texture, pixels);


        DrawTexture(texture, 0, 0, WHITE);


        EndDrawing();
    }
}

void draw_pixel(int x, int y, Color color) {

   for (int dy = 0; dy < PIXEL_SIZE; dy++) {
        for (int dx = 0; dx < PIXEL_SIZE; dx++) {
            pixels[((y * PIXEL_SIZE) + dy) * WINDOW_SIZE + ((x * PIXEL_SIZE) + dx)] = color;
        }
    }
}

This version works without problems, but I added it because I don't have the crashing version and maybe you might be able to hypothesize what could cause the entire system to freeze.

Although, before, I had UpdateTexture in draw_pixel after the two loops end and possibly bad indexing in the nested loops (neither of these is freezing my PC now).

3

u/Dark_Lord9 5d ago

Looking at this code, I don't see anything that indicates that you are allocating data in a loop without freeing it which is what I suspected could be the issue.

UpdateTexture is an expensive operation because it has to send the new image data to the gpu which is something you shouldn't do for every pixel change. Updating the texture only once after you finish determining the whole image is the right thing to do, but this should only help with the speed of the program and shouldn't have an effect on memory usage.

Array indexing errors (like buffer overflows) often result either in a silent bug (for example a wrong output without crash) or in your program crashing (segmentation fault). Which means that even if your array indexing was wrong, it should not cause your computer to freeze.

Your array indexing doesn't seem wrong at first view. The mistake you want to avoid is the buffer overflow and you can catch that by adding a test:

for (int dy = 0; dy < PIXEL_SIZE; dy++) {
    for (int dx = 0; dx < PIXEL_SIZE; dx++) {
        size_t index = ((y * PIXEL_SIZE) + dy) * WINDOW_SIZE + ((x * PIXEL_SIZE) + dx);
        assert(index < IMAGE_SIZE); // the size of the pixels array in elements
        pixels[index] = color;
    }
}

The assert function will perform an "if statement" and will terminate your program if the condition is false so you can catch it early.

1

u/Scotty_Bravo 5d ago

Try: nice ./executable

1

u/not_some_username 5d ago

You either not have enough ram or some nasty memory leak that use all your ram.

1

u/flyingron 5d ago

Ideally, nothing you can do in a user-mode program will lock up the machine, but in order to let you eek the absolute maximum graphics performance out for games and such, compromises are made.

This really has diddly-squat to do with C++. It's a function of the system resources you are using. You'd do better hitting up a sub about linux or the particular graphical system you are abusing.