Don’t create reference from pointer (part 1/2)

When programming in C++ (or any other language) you can sometime hit very weird behavior. Like your “if” statements are ignored. You usually find this the hard way. Like when your program crashes. You check the debugger and you see, that it crashes on null pointer inside “if”. Yes the “if” that checks for null pointers. Strange.
Well in this post I will try to explain what is happening to your program.

In C++ we have something called a reference. Reference is basically an alias to some value/object. This alias has several key points defined in standard. Like a reference has to be bound to a valid object in declaration.

This binding in declaration has the effect that reference can not be null. You will basically always create a valid reference because it is an alias to something. This has some consequences in compilation and especially in resulting assembly.

In compilation compiler can detect when you are doing something wrong and warn you. In resulting assembly the optimizer can omit some checks because it knows, that the object is valid.

A little example

This post is going to explain you why checks are ignored, when using references. First, however lets see a little sample code without references. You will see that the binary doesn’t contain the “if” we put there.

Check this simple code:

int doSomething();

int main( int argc, char** argv )
{
    int i = 5;

    if( i == 5 )
    {
        doSomething();
    }

    return 0;
}

This is the assembly result when no optimization is applied.

main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movl    %edi, -20(%rbp)
        movq    %rsi, -32(%rbp)
        movl    $5, -4(%rbp)
        cmpl    $5, -4(%rbp)
        jne     .L2
        call    _Z11doSomethingv
.L2:
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

This is with -O3 passed to GCC compiler

main:
.LFB0:
        .cfi_startproc
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        call    _Z11doSomethingv
        xorl    %eax, %eax
        addq    $8, %rsp
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc

As you can see the compiled just completely ignored the “if” in the optimized build. Why? Because it knows, that the “if” will always evaluate to true.

This simple code and compiled assembly showed that compiler do some analysis based on what it knows. The same will apply to references. More on that in the second part of this article.

Building RPM – BuildRoot ignored

BuildRoot: %{_tmppath}/%{name}-%{version}-build

Will not be taken into account, because it is overwriten by .rpmrc or rpmbuild cmd line –buildroot
This behavior was introduced in rpm version 4.6.0 ( which was released 6th of January 2009 ). The BuildRoot should not be used any more, because to cite rpm mailing list:

Buildroot from spec is ignored on purpose in rpm 4.6.0. That specs should
(have to) define their own buildroot is simply bad design and a leftover
from ancient times.

The new default build root directory is simple:

$HOME/rpmbuild/BUILDROOT/%{name}-%{version}/

So this explains a lot. If you are like me and read all kind of rpm tutorials on the internet. Then wonder why the hell it does not work as expected.
It is pity that this little detail is not mentioned in some tutorials, created even after 2009.

SfDD (Segmentation fault Driven Development)

You know it, you just did not realize it till now.

Crash, some call it crush, boom, explode … . It happened before, it is happening right now and it will happen in future. Lets face the truth. Programmers are people and people make mistakes. It is not constrained to C devs or C++ devs, Python devs, javascript devs or even Rust devs do make mistakes. When you program in some language the product of this mistakes are core dumps

Most of us make multi-threaded or asynchronous(event base) programs, the result of this is that the code is complex. The program flow is not linear, not just a bunch of ifs but rather modules that are somehow interconnected. It is very complex and with complexity bugs are very easily introduced.

We programmers get issues with our code all the time, most of the time it is something simple/stupid, but there are times when someone hit an issue that crashes our program. Not just crash, but we simply have no clue what is happening there(the result of the complexity). Some of us take such things as a challenge and that is where the SfDD starts.

Sure a wise programmer makes tests that can help, or try to reproduce the crash with minimal steps/config/environment required. However in the end we are just searching for answer for the question – is it still crashing?

Sometime we spend with SfDD a few days. The fix is usually simple but it includes a deep understanding of the code/app. The SfDD is actually very good in this regard, because it always teach a lesson or two to the programmer.

The best thing about SfDD is when it ends. Lets imagine a very real example. You have a crash in the system, you don’t know what is causing it. You start to debug, unit test your code, producing core dumps like crazy. You just had to clear /var/core for the second time because you ran out of disk space and now finally you found it. You make a commit of only a few lines changed, maybe some few if-s added or some legacy code removed that was there only because the other modules were not working as expected, but they fixed that already. Now you just pushed it and it all ends. The issue is solved and the feeling you get is just super. This is the best part of SfDD. The feeling of good work, accomplishment, good game, work nicely done. You feel the power of your new knowledge, the new stuff about C standard you just learned 2 days ago is really useful. The crazy stuff about pointers and references in C++ is still crazy but at least you know it. The compiler optimizations is looking less like a black magic. Also you know a part of the app you code and you start being the target for asking for help from others. For the rest of the day you take the least IQ demanding issue you can find and solve it like nothing.

This is SfDD, one of the best software development method ever invented.

Starting docker for the first time

I wanted to try an OpenSUSE Leap installation, just needed the shell not some GUI. My first choice in this kind of situation is to install a distro in VM. I was hearing a lot about docker and I said to myself, why not try a docker instead of VM.

First thing that came to my mind was – wait, can docker even run another linux distro? You know, docker images share kernel and I want to run another distro thus another kernel, this is job for virtualization.

I quickly discovered that you can run another linux distro in docker. Why? Well that’s easy. Every linux distro share the same kernel under the hood. Kernels ABI is usually pretty compatible across different versions.

I guess that all apps are just fine as long as they or better say their libs use syscalls that are available in the host kernel.

Now that we all know that docker can run linux distro let’s actually do that.

I’m running OpenSUSE Tumbleweed. It is a rolling-release distro so the steps may change a bit in future, but I think they will apply for at least some years to come.

Install docker:

sudo zypper install docker docker-compose

Add yourself to docker group so you can use it without sudo

sudo usermod -a -G docker your_name

Docker uses a dockerd daemon in the system, it should be running to use docker. Start it with systemctl

sudo systemctl start docker

To have docker auto start on boot enable it

sudo systemctl enable docker

You can check the whole config using

sudo systemctl status docker

● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2019-01-20 17:45:22 CET; 3h 41min ago
Docs: http://docs.docker.com
Main PID: 1343 (dockerd)
Tasks: 35
Memory: 401.7M
CGroup: /system.slice/docker.service
├─1343 /usr/bin/dockerd --add-runtime oci=/usr/sbin/docker-runc
└─1389 docker-containerd --config /var/run/docker/containerd/containerd.toml --log-level info

Search for the image you want

docker search opensuse

Download the image you want

docker pull opensuse/leap

This will download the latest version of that image, you can specify TAG, but let’s write about that in future post.

Check your installed images

docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
opensuse/leap latest bb77bd72ae3d 3 days ago 102MB

You can see the TAG here.

And now – run it

docker run -i -t opensuse/leap /bin/bash

You can check the params help later with
docker help run

Now you are in your new leap. You can look around, do stuff … . I was really curious about the ps aux command, you can try it too. It shows the compactness of containers.

Exit the image using CTRL+D or just type exit. You can now check the help for run or just check another command that list docker containers.

docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                         PORTS               NAMES
3d3fd74d0748 opensuse/leap "/bin/bash" 2 hours ago Exited (0) About an hour ago kind_khorana

To attach to the container you have to first start it

docker start 3d3fd74d0748

Then attach to it

docker attach 3d3fd74d0748

After you are done with your container you can just delete it

docker rm 3d3fd74d0748

This will delete the container only, not the image. You can check both with commands before. You can run another container of the image anytime you want.

And that is it. So far docker seems very nice.
In another post I will try to run web server in my container so don’t forget to check it how it will turn out.

Starting

I started thinking about getting a blog. After some time I finally decided to actually start one. The blogging content will be about (surprise surprise) programming, tech, linux and open source. From time to time I will probably post some random thought about some social issue or environment.

I have given a lot of thought how to start and what platform to choose. In the end I ended with WordPress and installed it manually on my server that I have for some time now. I already had a personal domain, so this blog is a nice use case for it.

The platform

Obviously I could create easily my blog on some free hosting platform but that was not what I choose.

Requirements

I had some requirements in the beginning, so the decision was a bit easier for me. Here are some

  • Free platform
  • I had to own my data
  • Ads – there should be possibility to add ads for in future
  • Previous experience
  • Good tutorials and documentation

The previous experience point did limit the platforms to 4: WordPress, Joomla, Blogger and Drupal. Blogger being a google product and seeing that google can just shut down what is used by millions then I decided that it is a not a good idea. I did not even study about ads and owning my data. Drupal seemed to have less tutorials and documentation. It looks that Drupal is ideal for very big sites, the ads are OK. I chose not to use it because I looked complicated. The story about Joomla is the same as Drupal’s. So I ended up with WordPress.

Installing

It took me under 1 hour to install and configure wordpress on my server. I’m already hosting a nodejs app on my server and using Nginx , so I had a bit experience with that. I’m using MariaDB instead of MySQL but it seems OK. I was missing php, so I grabbed it from the repo and it all works fine now. I did spend some time picking a theme, but who did not? There will be post in future with steps and troubles that I had during install.

Now what?

As I wrote before this will be a tech blog so expect tutorials and other tech stuff in programming.

The schedule

I said to myself: Let’s try to do at least one post per week for 1 year to see if I can handle it or not.

Expectations

The obvious one is to improve english. Other expectation is to learn new stuff as I will write about something. This is kind of important for me because I was a person that did a lot of research and nowadays it just does not feel like I’m doing it anymore. Another one is: get a bit organized. Create and publish at least one post per week is huge challenge, if you don’t know how to manage your time.

I hope that you will enjoy my blog and find every (or at least most) post useful and/or interesting.