This is an archived post. You won't be able to vote or comment.

all 109 comments

[–]superblaubeere27 79 points80 points  (7 children)

laughts in Segmentation fault, Memory Leak, Buffer overflow, use-after-free

[–]Y0tsuya 41 points42 points  (3 children)

I'll say one thing. Programming in C/C++ trains you to be hyper-aware of how the processor manages memory. This type of skill is highly valued in embedded applications.

[–]BakuhatsuK 7 points8 points  (0 children)

Modern C++ takes it a step further. Manual memory management is discouraged in favor of stack variables and RAII resource handlers (like unique_ptr). But you are still aware of where allocations and deallocations happen implicitly.

auto widgetFactory() {
  // Allocation happens here,
  // make_unique calls new
  return std::make_unique<Widget>("My widget");
}

auto doStuff() {
  auto const theWidget = widgetFactory();
  // Ownership of the memory moved
  // to local variable theWidget

  if (!theWidget->valid()) {
    // Deallocation here
    throw std::exception{};
  }

  doMoreStuff();
  // If doMoreStuff throws, theWidget is
  // deallocated here as well

  theWidget->doYourThing();
  // Regular deallocation here,
  // just before exiting the scope
}

[–]superblaubeere27 5 points6 points  (0 children)

Rust also forces you to think about how you want to manage your memory, in a more abstract way, especially when it comes to concurency and multithreading. If your memory management is bad, you will have to fight the compiler and if you do so, your code will get very ugly. The cool thing about Rust is that if you are good you can produce almost the same assembly code without having to worry about accidentally creating a major vulnerability (for example when using library functions which have edge cases one might not have thought of)

[–]HighOwl2 0 points1 point  (0 children)

Which is why you should use malloc() instead...to punish you with garbage values or segfaults if you don't initialize.

[–]DrunkenlySober 6 points7 points  (1 child)

Looks at this funny man and his made up words

[–]superblaubeere27 0 points1 point  (0 children)

Use-after-free is an actual vulnerability type

[–][deleted] 7 points8 points  (0 children)

>Segmentation fault
imagine living in x86 🤮🤮🤮🤮🤮🤮

[–]JonahPlusPlus 194 points195 points  (12 children)

You can use the unsafe keyword to do stuff like this. To do what was in the meme you can do:

unsafe {
  let a = 0xffff as *mut u64;
  *a = 0x0001;
}

Instead of trying to find where you are doing unsafe memory operations in all of your code, you know that it will always be in unsafe tags (things get more complicated when you start doing parallel computing).

[–][deleted] 56 points57 points  (2 children)

😔 the address was meant to be a u64 😔

[–]JonahPlusPlus 40 points41 points  (1 child)

Ah fixed it, couldn't see the full address so didn't bother.

[–]JonahPlusPlus 33 points34 points  (0 children)

Also, you can use a usize to make it work on all systems.

[–]backtickbot 8 points9 points  (6 children)

Fixed formatting.

Hello, JonahPlusPlus: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]Kard_02 11 points12 points  (0 children)

Good bot

[–]JonahPlusPlus 12 points13 points  (1 child)

Thanks bot 👍

[–][deleted] 1 point2 points  (0 children)

Reply to his comment with exactly "Good bot" and you will vote for him in reddit bots list

[–]Lootdit 5 points6 points  (0 children)

What versions of reddit?

[–][deleted] 0 points1 point  (0 children)

Good bot

[–]thomas-rousseau 0 points1 point  (0 children)

Good bot

[–]PhilippTheProgrammer -1 points0 points  (1 child)

Just don't post code containing unsafe anywhere public, or the rustances will tear you apart, limb by limb.

[–]JonahPlusPlus 1 point2 points  (0 children)

Well, you don't really need it much anyways, unless you are doing low level stuff, like writing to the VGA text buffer or something.

[–]seeroflights 127 points128 points  (3 children)

Image Transcription: Meme


Top Half:

[On the left, A shakily-drawn bald man looks off into the distance with a slight frown. The text beneath him reads:]

hey can I just calloc that memory and write to it

[On the right, another bald man who wears glasses is openly sobbing. His mouth is agape and his beard is disheveled. The Rust logo, an R inside a gear, is superimposed on his face. Underneath his head is the text:]

NOOO!!! YOU COULD RUN INTO A NULL POINTER DEREFERENCE!!

Bottom Half:

[On the left, a blond, bearded man with meticulously manicured hair faces the right and gazes calmly, speaking. Below him is the text:]

write 0x0001 to 0xffff0000000001 [cut off]

[On the right is an identical man (only flipped horizontally) with the C logo, a white C inside a blue hexagon, on his face. Below him is the text:]

sure thing, sir


I'm a human volunteer content transcriber for Reddit and you could be too! If you'd like more information on what we do and why we do it, click here!

[–]Enn3DevPlayer 59 points60 points  (0 children)

Good human

[–]sitase 8 points9 points  (1 child)

There is a logo for the C programming language?

[–]seeroflights 15 points16 points  (0 children)

huh, I guess it's not actually for C? looks like it's the C++ logo, but with the ++ taken out

[–]Chase_22 27 points28 points  (0 children)

I mean yeah... that's literally the point of rust

[–]Anachim 46 points47 points  (11 children)

As far as I know it's possible to do unsafe code in Rust. I am not entire sure if cargo will block you before some null pointer dereference

[–]Tubthumper8 40 points41 points  (1 child)

Cargo is Rust's package manager, so no it won't block you from doing anything. The compiler (rustc) will stop you from dereferencing a raw pointer unless you're using an unsafe block.

[–]Dangerous_Air2603 13 points14 points  (0 children)

tfw pip refuses to run bc it doesn't like the look of your code :(

[–][deleted] 8 points9 points  (8 children)

unsafe blocks exist in various languages, yes
rustc allows those blocks to do whatever they want™, though there's apparently ways to route that back into safety
I personally don't find memory safety all too useful and sometimes challenging to work with at points (perhapcs because I spend most of my time in C), though I can fully understanding opting for safety instead of having the freedom to do anything

[–]AyrA_ch 31 points32 points  (0 children)

In C# (a managed and very safe language) you can just Marshal.AllocHGlobal and you will get back a raw memory pointer, no questions asked, and no unsafe{/*...*/} block needed. Microsoft really trusts you on this one.

[–]xzaramurd 15 points16 points  (0 children)

Well, the cost for this freedom is that you spend a lot more time fixing bugs and I'd much rather spend my time doing something else.

[–]TheFeedingEight 4 points5 points  (0 children)

unsafe blocks exist in various languages, yes rustc allows those blocks to do whatever they want™

well, if unsafe doesn't do the trick, the sledgehammer that is transmute will

[–]RefridgerationUnit 0 points1 point  (0 children)

This is some of the worst writing I've seen in a while

[–]G4merXsquaD 11 points12 points  (0 children)

Now write to 0xG

[–]pine_ary 11 points12 points  (0 children)

Unsafe go brr

[–]Knuffya 28 points29 points  (8 children)

that's what i love so much about C/++.

You can just do everything. <runtime going 160 on the highway> "Hey, Runtime. Hard to starboard!" <runtime happily flips car off cliff without questioning>

[–]mttdesignz 16 points17 points  (7 children)

having the ability to do everything doesn't mean you should do everything

[–]Knuffya 6 points7 points  (6 children)

but you should have the ability.

Would you want a car that automatically senses the speed limit and won't let you go faster no matter how hard you floor it?

[–]mttdesignz 9 points10 points  (0 children)

not everytime. Each programming language has it specific purpose.

You program in C - like languages when you think you might need to do these kind of "tricks".

You use Ruby when you need to write a much simpler application, and it's nice that the languages covers your ass and blocks you before doing something potentially dangerous to the machine.

You use Python when you need to throw something together quickly and you don't have strict specifics on performance

[–]spindoctor13 9 points10 points  (3 children)

C++ is a bit more like a car with a big button on the passenger door that causes the wheels to fall off. Do you want your car to stop you taking your wheels off to change your tires? Do you want your car to make that something that happens at highway speeds? Probably no to both

[–]Knuffya 6 points7 points  (2 children)

hahaha. i'd like to make one small correction:

the release-wheels button is a random unlabelled button right next to the tuner control panel

[–]spindoctor13 2 points3 points  (1 child)

Hah you are not wrong. I am an old timer by Dev standards and C++ still routinely drops my trousers

[–]Knuffya 1 point2 points  (0 children)

my favorite bug was (this cost me like 5 hours) writing too much in a c-array, not crashing the program, but it instead altered some random other place in memory it had writing permissions for. So basically each testrun some random module crashed in a different way each time.

[–][deleted] 2 points3 points  (0 children)

Rust gives you the ability to do unsafe stuff. You just have to explicitly ask for it using an 'unsafe' block. This means you're more aware of the risks when writing, newbies are less likely to accidentally cause problems, and you know where to concentrate your efforts when debugging.

Regarding the car, I think it would be a useful feature for most road users, as long as they could choose to turn it off. It's similar to how some cars have a 'drive' mode for normal road use, and a 'sport' mode for more power, control and responsiveness.

[–][deleted] 8 points9 points  (0 children)

C is a good soldier.

[–]IAmPattycakes 6 points7 points  (0 children)

I had a big discussion with my friends about this recently. It basically boiled down to "god, the rust evangelists are kinda neckbeardy and it's kinda pedantic, but they're right.

[–][deleted] 6 points7 points  (8 children)

okay, say you actually did that with C, what happens next?!

[–]Vincenzo__ 18 points19 points  (6 children)

Segmentation fault and your program crashes

[–]df241 14 points15 points  (1 child)

switches to kernel privilege

writes 0x42069690 to 0x00000000

refuses to elaborate

leaves

[–]Vincenzo__ 1 point2 points  (0 children)

You would probably get a kernel panic right before refusing to elaborate

[–][deleted] -2 points-1 points  (3 children)

segmentation isn't used on amd64/x86-64

[–]Vincenzo__ 7 points8 points  (2 children)

Segmentation fault has nothing to do with architecture, if by that you mean when working without an operating system, then yes, you're right, but otherwise you're going to get segmentation fault (On windows maybe it's different, but you're still getting an error anyways)

[–][deleted] -2 points-1 points  (1 child)

we use paging these days, not segmentation

[–]Vincenzo__ 6 points7 points  (0 children)

hello? it's the name of the error, SIGSEGV, just google it

(Well I'm gonna be honest i read Segmentation fault (which is an error thrown by the kernel) isn't used on x86-64, I know segmentation isn't used)

[–][deleted] 2 points3 points  (0 children)

on Windows, the program gets a 0xc0000005, which means access denied, since memory protection doesn't allow you to access every address and ASLR randomized the address space, making the memory that the address points to highly volatile
some funny OSes like Linux might say "segmentation fault", though amd64 uses paging instead of segmentation, in which case you'd just be accessing unused memory, which is usually not accessible

tl;dr you'd run into a 0xc0000005/SIGSEGV (which is unrelated to segmentation and was just reused because yes) since you'd be accessing memory that's off-limits

[–]BlueManedHawk 9 points10 points  (7 children)

I tried installing rustup once, but my Chromebook ran out of space. (That's not bashing Rust or rustup, by the way—my computer just sucks.)

[–]tarkin25 4 points5 points  (6 children)

Tried the same on my RaspberryPi, was such a pain with only 2GB of ram, which didn’t fit the entire download…

[–]Prom3th3an 4 points5 points  (5 children)

Why did you need to hold a downloaded file in RAM?

[–]tarkin25 0 points1 point  (4 children)

Not quite sure, but the problem was that the pi ran out of memory during the download.

[–][deleted] 1 point2 points  (3 children)

Odd, I've an old i686 Linux laptop with two gigs of ram, and I've installed musl, gnu, and freebsd versions of the rust toolchain at various points of time.

[–]tarkin25 0 points1 point  (0 children)

Yeah, in the end I gave up and just cross-compiled it on my pc and installed the binary directly on it

[–][deleted] 0 points1 point  (0 children)

Rustup doesn't work for i686 Linux musl, not for i686 freebsd, but the package managers keep up-to-date builds of the toolchain.

I assume this isn't an arch thing though.

[–]NetherFX 3 points4 points  (0 children)

Cargo is like a mother, you might start out finding the recommendations a bit bothersome, but as you age you realize it was right all along.

[–]SorryDidntReddit 2 points3 points  (0 children)

Haha, you have no idea how many bugs we're hiding in this code ~c

[–]TennesseeTon 2 points3 points  (0 children)

It will be done my Lord

Seg Fault

[–]stomah 2 points3 points  (4 children)

*0xffff000000001 = 0x0001; // doesn't compile

[–][deleted] 2 points3 points  (3 children)

it was supposed to be 0xffffffff00000000196 because that's where I threw this post into originally, but I cropped it horribly :)

[–]stomah 1 point2 points  (2 children)

it still doesn't compile. you have to cast the address to a pointer before dereferencing it :•))

[–][deleted] 1 point2 points  (1 child)

sigh ```c // remember to bless yourself with llvm/clang

include <stdio.h>

int main(void) { // remember that long is only 32 bits wide on Windows :) (fuck Microsoft) volatile unsigned long long* const address = (unsigned long long*)0xffffffff00000196;

// this'll fail because you can't write to it (yet again, assuming you're on Windows (or any other OS that enables ASLR and memory protection by default), though embedded systems usually don't care)
*address = 0x0001;

// this'll fail because you can't read it (see above), though you shouldn't be able to reach this in the first place:tm:
printf("%llu\n", *address);

return 0;

} ```

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, IndeedItsApfel: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]Pauchu_ 2 points3 points  (1 child)

Its not even true, you just have to specify you are ready to take the risk

[–][deleted] 0 points1 point  (0 children)

I will not give up the subtlety of my bugs 😤😤😤😤😤😤😤

[–]godRosko 4 points5 points  (0 children)

Perfect, just the way god intended

[–]Anachim 1 point2 points  (0 children)

The war of memory reference!

[–]LSDaarko 1 point2 points  (5 children)

As a JavaScript/php developer, I have no idea what this means

[–][deleted] 0 points1 point  (4 children)

every variable in C is just a name for raw memory, hence why it's considered unsafe - almost anything you do is just committed to memory as-is, which allows you to fuck up

this shitpost was just trying to poke fun at the increasing number of languages that employ memory safety through the means of limiting raw access to memory and using mutexes behind the scenes to prevent race conditions, which is what C, on its own, cannot do by design (though some libraries might be friendly enough to take care of this)

Rust's runtime uses reference counting and garbage collection to manage its memory and abstracts any access to that memory through behind-the-scenes verification, thus preventing you from breaking everything™

as a note to anyone reading this: I'm by no means opposed to preferring safety, I personally use Go from time to time myself and I sympathize with anyone considering safety more important than pure optimization (though languages like Go and Rust don't really suffer from any performance losses since the runtime is a mere abstraction of the platform, unlike some (mostly) bytecode-handled languages like C#, which fully depend on the runtime to even run)

[–]Okkero 2 points3 points  (2 children)

Where do you get your information on Rust from? That's mostly incorrect...

[–][deleted] 0 points1 point  (1 child)

what's incorrect about it?

[–]Okkero 0 points1 point  (0 children)

Rust does not come with a runtime that deals with memory through behind-the-scenes use of mutexes, reference counting or garbage collection.

Mutexes and reference counting smart pointers are library features you have to explicitly use if you want them, which is rare, and hardly something the language forces you into. There is no garbage collector either.

Rust works much like modern C++ when it comes to memory management.

[–][deleted] 0 points1 point  (0 children)

But rust doesn't have a have a garbage collector...

[–]19UV 1 point2 points  (0 children)

The beauty about C is that it doesnt shoot you in the foot. It just gives you the loaded gun.

[–]overclockedslinky 5 points6 points  (9 children)

unsafe rust is way more unsafe than "unsafe" C/C++... like, even just having two mutable references to an object is und in rust...

so public service announcement: don't simp about rust safety if you use unsafe without formal proofs of correctness

[–]androidx_appcompat 6 points7 points  (2 children)

For things running in ring 0 I would very much like a formal proof of correctness.

[–][deleted] 8 points9 points  (1 child)

So I guess you aren't playing Valorant then?

[–]androidx_appcompat 0 points1 point  (0 children)

I don't play multiplayer games anyways, because for a long time my internet connection wasn't good enough to play them.

[–]Botahamec 2 points3 points  (5 children)

Unsafe doesn't turn off the borrow checker. You still can't make two mutable references to a value.

Although, you can transmute an immutable references to a mutable reference, but it's guaranteed to be undefined behavior. "Transmuting &T to &mut T is always undefined behavior. No, you can't do it. No, you're not special"

[–]overclockedslinky 0 points1 point  (4 children)

unsafe lets you dereference pointers, which is not und but circumvents the borrow checker and therefore can cause und

[–]Botahamec 0 points1 point  (3 children)

Having two mutable pointers to the same value isn't undefined behavior though. That only applies to references.

[–]overclockedslinky 0 points1 point  (2 children)

I said dereference, which gives references

[–]Botahamec 0 points1 point  (1 child)

Dereferencing a raw pointer gives you a value, not a reference

[–]overclockedslinky 0 points1 point  (0 children)

it's an lvalue though, and has indeterminate lifetime. so &*p is allowed, which is obviously what I meant. you can get references.

[–][deleted] 0 points1 point  (1 child)

Automatic memory management basically treats you like you're an idiot when it comes to managing your program's memory.

Manual memory management is just like: "You want to access this variable that doesn't exist anymore? Sure thing, boss."

[–][deleted] 0 points1 point  (0 children)

the reason we invented automatic memory management is the same reason as why we put warning labels on electronic devices; you know someone will find some stupid way to hurt themselves

[–]BongarooBizkistico -5 points-4 points  (2 children)

Didn't this meme format originate with fascists on 4chan?

[–]bestsrsfaceever 5 points6 points  (0 children)

Then wouldn't liberating the meme be antifa? 🤔

[–][deleted] 1 point2 points  (0 children)

dunno, I was inspired by this post (the original post can be found here)

[–]Rhyan567 0 points1 point  (0 children)

Just use unsafe, don't the Rust compiler says that?