Building a C++ project with CMake

Now that I know enough C++ to be able to build something useful, I started looking at tools that will make it possible to create maintainable projects. I’m exploring CMake because it is probably the most popular build tool for C++ projects. It allows you to create platform independent configuration files that can then be translated to the platform of your choice.

Installation

In Ubuntu, you can install CMake using apt-get:

1
sudo apt-get install cmake

For other systems, you can download the binary from CMake’s downloads page.

Read More

Building and using a library in C++

In a previous article I wrote an article explaining how header files work in C++. Among other things, the article explains how you can split your code in multiple files and link them together to create a single executable. One of the advantages of doing this, is that it allows code to be better organized, by separating different responsibilites in different files.

In this article I want to go one step further and explain how to create a library that can be reused by multiple projects.

Read More

Using lsof to find who is using a file or socket

lsof stands for List Open Files. It can help us find which process is using a file at a given point in time. The reason lsof is so useful in Unix/Linux systems is that sockets and devices are treated the same way as files (Pretty much everything is considered a file in Unix/Linux).

Running lsof without any arguments will list all open files in the system. If you have a lot of processes working with a lot of files, prepare to wait. The output looks somethins like this:

1
2
3
4
5
6
7
$ sudo lsof
COMMAND     PID   TID            USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd       1                  root  cwd       DIR              253,1      4096          2 /
systemd       1                  root  rtd       DIR              253,1      4096          2 /
systemd       1                  root  txt       REG              253,1   1577264    5374284 /lib/systemd/systemd
systemd       1                  root  mem       REG              253,1     18976    5375835 /lib/x86_64-linux-gnu/libuuid.so.1.3.0
...
Read More

Assembly - Variables, instructions and addressing modes

In a previous article I showed how to assemble a program using nasm. In this article I’m going to explore different ways to access data and explore some instructions.

Variables

The simplest way do declare variables is by initializing them in the .data segment of a program. The format to define initialized data is:

1
[variable-name]    define-directive    initial-value   [,initial-value]...

An example use:

1
2
3
4
5
6
7
8
9
10
11
section .data
  exit_code dq 0
  sys_call dq 60

section .text
  global _start

_start:
  mov rax, [sys_call]
  mov rdi, [exit_code]
  syscall
Read More

Vim command line mode

The vim command-line mode is the mode we enter when typing Ex commands (:), search patterns (/, ?) or filter commands (!). This mode works a little like insert mode, in that whatever we type, is going to appear in the command line. It is not as powerful as the normal mode, but there are a few combinations we can use to move more efficiently:

  • Ctrl+left, Ctrl+right - Using the arrow keys we can move left and right one character at a time. If we press Ctrl together with the left or right keys, we will move one word at a time
  • Ctrl+B, Ctrl+E - Move to the beginning and end of the command line, respectively
  • Ctrl+W - Deletes the word before the cursor (Only deletes characters at the left of the cursor)
Read More

The Vim statusline

Vim allows us to customize the statusline shown at the bottom of each window. To toggle the statusline visibility, the laststatus option can be used. It can be set to any of these values:

1
2
3
0: never
1: only if there are at least two windows (default)
2: always

If we want to always show the statusline, we can use this command:

1
set laststatus=2
Read More

Writing a vim plugin - Grepfrut

I use grep.vim to grep in multiple files within vim. It usually works pretty well, but I recently needed a little more freedom in how I specify the files in which I want to search, and found that it can’t do what I want. I looked at the code and found that modifying it to do what I want would be hard with the current design, so I decided to create my own plugin.

The plugin I’m going to create is going to be very simple. It is going to provide simple greping functionality with a similar UI to grep.vim, but will allow more freedom on filtering which files to search.

Read More

Introduction to assembly - Assembling a program

I have been working on learning C++ for some time now. I can write and read most code, but there are still a lot of things I don’t understand. One thing that I have noticed about good C++ developers is that they usually know a lot about compilers and the operating system in which they are working. Following their example, I’m going to try to learn about those subjects too.

I’m writing an article about assembly because I have found in some occasions, C++ code being explained in reference to the generated assembly code. Although I had an assembly class in college, I don’t really rememeber anything, so I will have to start from the bottom.

In this article I’m going to be using the x64 (also known as x86-64) architecture, since it’s the architecture most commonly used by modern home computers and servers (for example Intel Core i7).

Read More

Load bash preferences when SSH to a host

I have a laptop computer where I customize my bash using a .bashrc file. Whenever I SSH to a remote host, I always find myself trying to use aliases or other functionality that I have set on my laptop, but they are not there. Today I found a little trick that I can use to copy my .bashrc configuration to a remote host, so I can feel at home.

What we need to do is copy our .bashrc file to the host we are going to SSH to. Something like this would work:

1
scp ~/.bashrc user@host:/tmp/.my-bashrc
Read More

Lock hierarchies to avoid deadlocks

In a previous post I explained how mutexes work and the problem of race conditions.

In this post I introduce another common problem with mutexes, which is deadlocks. Deadlocks are situations when a program can’t make any progress because it is waiting for a mutex that will never be available. This might sound stupid, but it’s something that actually happens very often.

A naive example could be this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <thread>
#include <mutex>

std::mutex mutexA;
std::mutex mutexB;

void doSomething() {
  std::lock_guard<std::mutex> gA(mutexA);
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::lock_guard<std::mutex> gB(mutexB);
}

void doSomethingElse() {
  std::lock_guard<std::mutex> gB(mutexB);
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::lock_guard<std::mutex> gA(mutexA);
}

int main() {
  std::thread t1(doSomething);
  std::thread t2(doSomethingElse);

  t1.join();
  t2.join();
}
Read More