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

Aggregate initialization in C++

I previously wrote an article about variable initialization in C++, but sadly, initialization of variables in C++ is a complicated subject with a lot of options.

Aggregate classes

Before talking about aggregate initialization, we need to know what an aggregate is. Aggregate classes have these properties:

  • All its data members are public
  • Doesn’t define any constructors
  • Doesn’t have virtual functions
  • Doesn’t inherit from any class
  • Doesn’t have any in-class initializers

An example could be:

1
2
3
4
5
class Person {
 public:
  std::string name;
  int age;
};
Read More

AVL Trees

I wrote an article about Binary Search Trees a few weeks ago. AVL trees are a specialization of Binary Search Trees.

AVL trees (named after their inventors, Adelson-Velskii and Landis) were the first kind of self-balancing tree to be invented, so their implementation is somewhat simple compared to newer self-balancing trees.

This type of tree allows you to perform insertions, deletions and searches in O(log n). This tree keeps track of the heights of all the nodes. Every time one node is inserted or deleted, the balancing factor (difference between the heights of left and right subtree) of its ancestors is checked. If the balancing factor is greater than 1 or lower than -1, then the tree is rebalanced.

Read More

Spell and Grammar checking on vim

I recently moved my blog to Jekyll, which means I now write my posts in my favorite editor. One problem I encountered is that vim doesn’t check my spelling by default, which means I probably had a lot of mistakes in the last posts I wrote.

Because I prefer people thinking I know how to write, I decided to look for a tool that would help me with this.

Installation

The first thing I had to do was install Java Runtime:

1
sudo apt install default-jre
Read More

Binary Search Trees

A Binary Search Tree (BST) is a binary tree where the nodes are ordered following these characteristics:

  • The left subtree of a node contains only nodes with values lower than the node’s value
  • The right subtree of a node contains only nodes with values greater than the node’s value
  • The left and right subtree each must also be a Binary Search Tree
  • There must be no duplicate values
  • A unique path exists from the root to every other node

The possible operations on a Binary Search Tree are: Search, Insert and Delete. An update is just a delete followed by an insert.

Binary Search Trees are pretty easy to implement and let you insert, delete and search in O(n) in the worse case scenario. There are self-balancing Binary Search Trees, that are harder to implement but offer O(log n) performance. I’m not going to cover self-balancing trees in this post.

Read More

Advanced top for system diagnosis

In a previous post I went over the basics of top. In this post I’m going over some more advanced features that can be used to diagnose problems.

Top will by default refresh every 3 seconds. If this is too often for you, you can specify how many seconds to wait between each refresh:

1
top -d 10

d stands for delay.

Another useful option is to hide idle tasks:

1
top -i

The letter i can also by used to toggle idle tasks while top is running.

If you are interested in processes belonging to a specific user:

1
top -u adrian
Read More

Introduction to top for system diagnosis

top is a program available in most Unix systems. It allows us to see the processes or threads running on a computer and help understand what they are doing at a high level (How much CPU or memory they are using, etc).

The top command with no modifiers will show something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
top - 11:44:51 up 13:24,  1 user,  load average: 0.58, 0.56, 0.63
Tasks: 247 total,   1 running, 246 sleeping,   0 stopped,   0 zombie
%Cpu(s):  9.3 us,  2.5 sy,  0.0 ni, 88.1 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem : 20296196 total, 15693616 free,  2027196 used,  2575384 buff/cache
KiB Swap: 20713468 total, 20713468 free,        0 used. 17373856 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 6541 adriana+  20   0 1711996 371500 179160 S  14.6  1.8   2:48.36 chromium-browse
 6086 adriana+  20   0 3204864 397544 143956 S  11.3  2.0   5:20.30 chromium-browse
 6560 adriana+  20   0 1299604 152364  77924 S   7.0  0.8   0:36.41 chromium-browse
 6521 adriana+  20   0 1338048 192696  94196 S   6.6  0.9   0:58.36 chromium-browse
 2860 adriana+  20   0 2000924 238864  68368 S   3.0  1.2   4:54.79 gnome-shell
 1440 root      20   0  233260  83616  25896 S   1.0  0.4   0:14.25 splunkd
 1914 root      20   0  500940  34424  20004 S   1.0  0.2   0:25.60 docker-containe
12367 adriana+  20   0   35600   3464   2896 R   0.7  0.0   0:00.05 top
    8 root      20   0       0      0      0 S   0.3  0.0   0:03.92 rcu_sched
  345 root       0 -20       0      0      0 S   0.3  0.0   0:01.65 kworker/u9:3
 1387 root      20   0  299452  64072  39456 S   0.3  0.3   2:24.16 Xorg
 1833 root      20   0  756772  68200  39192 S   0.3  0.3   0:11.96 dockerd
Read More