This post details my adventures with the Linux virtual memory subsystem, and my discovery of a creative way to taunt the OOM (out of memory) killer by accumulating memory in the kernel, rather than in userspace.
Keep reading and you’ll learn:
Internal details of the Linux kernel’s demand paging implementation
How to exploit virtual memory to implement highly efficient sparse data structures
What page tables are and how to calculate the memory overhead incurred by them
A cute way to get killed by the OOM killer while appearing to consume very little memory (great for parties)
Note: Victor Michel wrote a great follow up to this post here.
This was a pretty interesting buggy scenario I found while reading the clang-tidy checks. If you’re writing a function that takes a forwarding reference (what looks like an rvalue reference, but whose type is a template argument), you need to be careful to not call std::move on it. You need to make sure to call std::forward instead. Otherwise, you might accidentally trigger a move on an object passed by a caller! This would be confusing, since their object would be moved from, and they never explicitly called std::move on it.
I got bit by unique_ptr when implementing a linked list today. You need to be careful to manually release() the unique_ptr before resetting or you might accidentally free the entire list. This comes up when doing insertions and stuff like that.
I was reading about GCC and noticed this very suspicious warning line about an accidental compatibility break: https://gcc.gnu.org/gcc-8/changes.html
I thought it would be interesting to reproduce this. I reproduced this specific scenario they outline and compiled two translations units, one with GCC 8.1, one with an earlier version (GCC 7) and observed the segfault that happens when two incompatible calling conventions interact with each other.
Don’t assume it’s safe to use pre-built dependencies when compiling C++ programs. You might want to build from source, especially if you can’t determine how a pre-built object was compiled, or if you want to use a different C++ standard than was used to compile it.
Ubuntu has public build logs which can help you determine if you can use a pre-built object, or if you should compile from source.
pkg-config is useful for generating the flags needed to compile a complex third-party dependency. CMake’s PkgConfig module can make it easy to integrate a dep into your build system.
Use CMake IMPORTED targets (e.g. BZip2::Bzip2) versus legacy variables (e.g. BZIP2_INCLUDE_DIRS and BZIP2_LIBRARIES).