Tagged: coding

Brief GDB Basics

In this post I would like to go through some of the very basic cases in which gdb can come in handy. I’ve seen people avoid using gdb, saying it is a CLI tool and therefore it would be hard to use. Instead, they opted for this:

std::cout << "qwewtrer" << std::endl;
DEBUG("stupid segfault already?");

That’s just stupid. In fact, printing a back trace in gdb is as easy as writing two letters. I don’t appreciate lengthy debugging sessions that much either, but it’s something you simply cannot avoid in software development. What you can do to speed things up is to know the right tools and to be able to use them efficiently. One of them is GNU debugger.

Example program

All the examples in the text will be referring to the following short piece of code. I have it stored as segfault.c and it’s basically a program that calls a function which results in segmentation fault. The code looks like this:

/* Just a segfault within a function. */

#include <stdio.h>
#include <unistd.h>

void segfault(void)
{
	int *null = NULL;
	*null = 0;
}

int main(void)
{
	printf("PID: %d\n", getpid());
	fflush(stdout);

	segfault();

	return 0;
}

Debugging symbols

One more thing, before we proceed to gdb itself. Well, two actually. In order to get anything more than a bunch of hex addresses you need to compile your binary without stripping symbols and with debug info included. Let me explain.

Symbols (in this case) can be thought of simply variable and function names. You can strip them from your binary either during compilation/linking (by passing -s argument to gcc) or later with strip(1) utility from binutils. People do this, because it can significantly reduce size of the resulting object file. Let’s see how it works exactly. First, compile the code with striping the symbols:

[astro@desktop ~/MyBook/code]$ gcc -s segfault.c

Now let’s fire up gdb:

[astro@desktop ~/MyBook/code]$ gdb ./a.out
GNU gdb (GDB) Fedora (7.3.1-48.fc15)
Reading symbols from /mnt/MyBook/code/a.out...(no debugging symbols found)...done.

Notice the last line of the output. gdb is complaining that it didn’t find any debuging symbols. Now, let’s try to run the program and display stack trace after it crashes:

(gdb) run
Starting program: /mnt/MyBook/code/a.out 
PID: 21568

Program received signal SIGSEGV, Segmentation fault.
0x08048454 in ?? ()
(gdb) bt
#0  0x08048454 in ?? ()
#1  0x0804848d in ?? ()
#2  0x4ee4a3f3 in __libc_start_main (main=0x804845c, argc=1, ubp_av=0xbffff1a4, init=0x80484a0, fini=0x8048510, 
    rtld_fini=0x4ee1dfc0 , stack_end=0xbffff19c) at libc-start.c:226
#3  0x080483b1 in ?? ()

You can imagine, that this won’t help you very much with the debugging. Now let’s see what happens when the code is compiled with symbols, but without the debuginfo.

[astro@desktop ~/MyBook/code]$ gcc segfault.c 
[astro@desktop ~/MyBook/code]$ gdb ./a.out 
GNU gdb (GDB) Fedora (7.3.1-48.fc15)
Reading symbols from /mnt/MyBook/code/a.out...(no debugging symbols found)...done.
(gdb) run
Starting program: /mnt/MyBook/code/a.out 
PID: 21765

Program received signal SIGSEGV, Segmentation fault.
0x08048454 in segfault ()
(gdb) bt
#0  0x08048454 in segfault ()
#1  0x0804848d in main ()

As you can see, gdb still complains about the symbols in the beginning, but the results are much better. The program crashed when it was executing segfault() function, so we can start looking for any problems from there. Now let’s see what we get when debuginfo get’s compiled in.

[astro@desktop ~/MyBook/code]$ gcc -g segfault.c 
[astro@desktop ~/MyBook/code]$ gdb ./a.out 
GNU gdb (GDB) Fedora (7.3.1-48.fc15)
Reading symbols from /mnt/MyBook/code/a.out...done.
(gdb) run
Starting program: /mnt/MyBook/code/a.out 
PID: 21934

Program received signal SIGSEGV, Segmentation fault.
0x08048454 in segfault () at segfault.c:9
9		*null = 0;

That’s more like it! gdb printed the exact line from the code that caused the program to crash! That means, every time you try to use gdb to get some useful directions for debugging, make sure, that you don’t strip symbols and have debuginfo available!

Start, Stop, Interrupt, Continue

These are the basic commands to control your application’s runtime. You can start a program by writing

(gdb) run

When a program is running, you can interrupt it with the usual Ctrl-C, which will send SIGINTR to the debugged process. When the process is interrupted, you can examine it (this is described later in the post) and then either stop it completely or let it continue. To stop the execution, write

(gdb) kill

If you’d like to let your program carry on executing, use

(gdb) continue

I should point out, that in gdb, you can abbreviate most of the commands to as little as a single character. For instance r can be used for run, k for kill, c for continue and so on :).

Stack traces

Stack traces are very powerful when you need to localize the point of failure. Seeing a stack trace will point you directly to the function, that caused you program to crash. If your project is small or you keep your functions short and straight-forward, this could be all you’ll ever need from a debugger. You can display stack trace in case of a segmentation fault or generally anytime when the program is interrupted. The stack trace can be displayed by a backtrace or bt command

(gdb) bt
#0  0x08048454 in segfault () at segfault.c:9
#1  0x0804848d in main () at segfault.c:17

You see, that the program stopped (more precisely was killed by the kernel with a SIGSEGV signal) at line 9 of segfault.c file while it was executing a function segfault(). The segfault function was called directly from the main() function.

Listing source code

When the program is interrupted (and compiled it with debuginfo), you can list the code directly by using the list command. It will show the precise line of code (with some context) where the program was interrupted. This can be more convenient, because you don’t have to go back into your editor and search for the place of the crash by line numbers.

(gdb) list
4 #include 
5
6 void segfault(void)
7 {
8   int *null = NULL;
9 *null = 0;
10 }
11
12 int main(void)
13 {

We know (from the stack trace), that the program has stopped at line 9. This command will show you exactly what is going on around there.

Breakpoints

Up to this point, we only interrupted the program by sending a SIGTERM to it manually. This is not very useful in practice though. In most cases, you will want the program stop at some exact place during the execution, to be able to inspect what is going on, what values do the variables have and possibly to manually step further through the program. To achieve this, you can use breakpoints. By attaching a breakpoint to a line of code, you say that you want the debugger to interrupt every time the program wants to execute the particular line and wait for your instructions.

A breakpoint can be set by a break command (before the program is executed) like this

(gdb) break 8
Breakpoint 2 at 0x4005c0: file segfault.c, line 8.

I’m using line number to specify, where to put the break, but you can use also function name and file name. There are multiple variants of arguments to break command.

You can list the breakpoints you have set up by writing info breakpoints:

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What
1       breakpoint     keep n   0x00000000004005d8 in main at segfault.c:14
2       breakpoint     keep y   0x00000000004005c0 in segfault at segfault.c:8

To disable a break point, use disable <Num> command with the number you find in the info.

Stepping through the code

When gdb stops your application, you can resume the execution manually step-by-step through the instructions. There are several commands to help you with that. You can use the step and next commands to advance to the following line of code. However, these two commands are not entirely the same. Next will ‘jump’ over function calls and run them at once. Step, on the other hand, will allow you to descend into the function and execute it line-by-line as well. When you decide you’ve had enough of stepping, use the continue command to resume the execution uninterrupted to the next break point.

Breakpoint 1, segfault () at segfault.c:8
8		int *null = NULL;
(gdb) step
9		*null = 0;

There are multiple things you can do during the process of stepping through a running program. You can dump values of variables using the print command, even set values to variables (using set command). And this is definitely not all. Gdb is great! It really can save a lot of time and lets you focus on the important parts of software development. Think of it the next time you try to bisect errors in the program by inappropriate debug messages :-).

Sources

Advertisements

Dependency Inversion Principle

DIP or Dependency Inversion Principle is yet another guideline for the software designers that work in object-oriented environment. It’s the D in SOLID and it has one huge advantage over the other principles: in case it doesn’t work for you, you can always get some tortilla chips to help (they work wonderfully with dip ;-)).

This principle was introduced by Robert C. Martin in his article in 1996. He points out that the usual way of dependency design among software project is to make general high-level modules dependent on the low-level utilities and mechanism that do the hard (and in most cases also not very interesting) work. This way of dependency makes the high level modules very hard to reuse without many modifications (and people often thing “why the hell didn’t I wrote it again”). And this is wrong.

The high-level modules are key part of the application. That’s where the heart of the application actually is. The algorithm that knows how to use the lower-level modules to achieve the desired functionality of our application. And we want to reuse that without having to modify every third line, so what do we do?

Mr. Martin proposes the Dependency Inversion Principle, which says

A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.

It’s a little tough one to understand at first, so let me explain. The principle states, that there should be some additional layer between high and low level modules — the layer of abstractions. The author says, that there should be an interface (or abstraction) defined between those two modules on whom should both depend. That way high level modules don’t work directly with the low level classes. Low level classes implement the interfaces. In case you’d like to take some module out and use it elsewhere, you don’t need to touch anything inside that module. You simply take it out and implement the interfaces upon which the module depends. Isn’t that awesome?

The second part (part B.) makes clear that the abstractions (or interfaces) should not be designed according to the low level modules (the details). That’s something that might come naturally to a lazy coder “yeah, I’ll just duplicate the header file, make all methods pure virtual and I’m good to go”, no. The interfaces have to be implemented on the same level of abstraction as the high level module otherwise they’re more than useless.

Example of Dependency Inversion

That would be the principle in theory. Let’s see some examples from user interfaces. We’ll have a Window class with two buttons.

class Button
{
    public:
        void makeVisible();
};

class Window
{
    Button* okButton;
    Button* cancelButton;

    Window()
    {
        okButton = new Button;
        okButton->makeVisible();

        cancelButton = new Button;
        cancelButton->makeVisible();
    }

};

The problem here is, that if the Button implementation changes, we’ll have to go here and change the constructor as well. We don’t want that, because the Window class were a subject of a lot of tests, it passed and any additional messing around in it might introduce errors into the class. Using the abstraction layer the situation would look like this

class IButton
{
    public:
        static virtual IButton* getInstance() = 0; // factory method
        virtual void show() = 0;
};

class Window
{
    IButton* okButton;
    IButton* cancelButton;

    public:
        Window()
        {
            okButton = IButton::getInstance();
            okButton->show();

            cancelButton = IButton::getInstance();
            cancelButton->show();
        }
};

class Button : public IButton
{
    public:
        void show();
};

Now, as you can see, there’s an interface IButton and both Button and Window depend on this interface. And that’s the dream. You can take the window and the interface place into an another application, implement the interface and you’re good to go! Note the factory method I used to be able to get the correct instance of buttons.

Sources

The ‘Oh’ Moment

There’s a little thing in software development I like to call the ‘Oh moment‘. I first noticed it when I was working on my bachelor’s thesis (and I was getting those all the time). Let me explain the situation a bit. You’re working on a project, not particularly easy one and finally after a couple of sleepless nights and rather unspecified amount of coffee, you come up with a solution. It seems just perfect. Clean, elegant, looks cool due to all the fancy inheritance, Mum will be proud.

Then first thing tomorrow morning, you start to eagerly write the code. It’s all good until it comes, ‘Oh, man’. One more thing (there always is) that you didn’t take into account and it just won’t work this way. It might work eventually, after some further modifications, but the result won’t be nearly as elegant nor clean. Not even mentioning the sweet inheritance tree. And there goes your excitement. After experiencing an oh-moment, your goal is no longer to create a good piece of software, but to get it done as fast as you can and then run away from it as far as possible.

The excitement from your ideas, good feeling about your work and satisfaction with the results is, in my opinion a key component in software development. Everybody likes doing a good job. And it’s really bad (for you and the project), if you don’t find the results good enough. But how to enjoy the job from the beginning to end?

You need to eliminate the Oh-moments. The more experience you get, the less Oh-moments you experience. But you cannot take them out of the equation entirely. Sh*t happens, and when it does, you need to be ready to minimize the consequences. However, there are couple of methods, that I personally find very helpful in this matter.

Wait

Never and I mean NEVER implement your design right away. It’s good to do something else for a while (my personal favorite is re-factoring and documenting the existing code) and then get back to it. If you still can’t see anything wrong with it, your chances of encountering an Oh-moment in the future are decreasing.

Show It to Others

A great way of avoiding oh moments is explaining your design to a team-mate or a friend. You will see it from whole another perspective and this will help you discover any unwanted surprises wrapped in the design.

Design in Iterations

Generally the later you get the flaw the bigger issue it is, so if you’ve stumbled upon an Oh-moment after a year of development, well, may the force be strong with you. But If you sit back once in a while and think a little further into the future of your application, you might find the dead end fast enough, before you get surrounded in it by a group of guys with knives and baseball bats craving for your wallet.

Documenting Python Code with Sphinx

One of the essential tasks in software development is documenting your code. With no documentation, hardly anyone will be able to understand your code and therefore contribute to your project. Sometimes you might find even yourself looking at your own code wandering, “What the hell is this supposed to mean?” Well, that’s where documentation comes in!

Good idea is to include documentation right into the source files. First of all, it helps coders read the source, because if they don’t get something, the documentation is right there! It’s much easier to maintain correct documentation. If you change something, you also change it 10 lines above in the documentation string. There are lots of utilities for analyzing source files and generating documentation from them. JavaDoc for Java, doxygen for C++ and Sphinx for Python.

I assume you know the awesome-looking Python docs, right? Well, that documentation is generated by Sphinx! In this post I’ll try to explain how to get sphinx and most importantly how to get that sweet-looking documentation out of it :-).

Installation

Sphinx is distributed as a python module, so you can use easy_install to get it. Install sphinx and all the dependencies by writing:

$ sudo easy_install sphinx

Easy install is a part of setuptools. So if this doesn’t run anything you probably need to install them. Look for package python-setuptools in your distribution’s repositary.

Setting up the doc folder

Documentation is usualy placed in a separate folder in your project directory. It’s really up to you, but I recomend using doc/ folder. Then you need to setup basic files for sphinx in that particular folder (sphinx calls it a source directory). This can be done by sphinx-quickstart command that will guide you through the whole setup process. The important thing here is to answer yes to the question of enabling autodoc extension. This extension then collect the documentation from your code.

$ mkdir doc
$ cd doc/
$ sphinx-quickstart

Writing documentation

The above mentioned sequence of commands should create a basic directory structure of your sphinx documentation. Somewhere in that structure (it depends on how did you answer to the questions of sphinx-quickstart) will be an index file of the whole docs. By default it will be called index.rst. Content of this file is in reStructured text. It’s a syntax for formating plain text documents. It’s not very hard to learn. Using either rst quick reference, sphinx guide or my personal favorite way — ripping off python docs.

On every html page generated by sphinx is a link to the source rst file it were generated from. And so it is in the python docs. The link is at the bottom of the menu right above the search box. You see, the documentation of python is not only quite large, but also really well formed. So by looking at that you’ll be soon able to write some pretty good docs yourself.

Sphinx documentation example

If you decide to crate a new page, you can simply add a file to the doc/ directory and sphinx will find it and include it into the documentation.

Documentation from docs string isn’t included automatically like in doxygen. You need to specify where to include what. In-depth explanation on how to do that is here.

Conclusion

Well, this was my very brief experience with sphinx. It’s a great tool for creating documentation for your python projects. Hopefully, I’ll get back to it at some point in the future and expand this article.

Sources

My notes on vim

One of the things that have been on my todo list forever — learn vim! And what better time is there for such a thing than a holiday :-)!

What is vim? Only the most awesome text editor in the world! It can run in terminal, so you can use it wherever you want, Gnome, KDE, anything. It has so many capabilities and great features, that will make your life easier. The only downside is that it requires some getting used to … yeah, right :-).

If you’re starting with vim as well, one of the first areas to explore is configuration. Vim loads settings from .vimrc file that is stored in your home directory. There is a fair amount of things that can be configured. And with right configuration vim is godlike text editor!

Here is mine .vimrc file:

" astro .vimrc
set nocompatible
set showmode
set showcmd
set title
set number
set mouse=a
set backspace=2
set showmatch
set autoindent

syntax on

Make vim work with system clipboard

Very important thing (at least for me) is to be able easily copy and paste text outside the editor. In the console environment, the classic CTRL+[CVX] shortcuts doesn’t work very well. Even if they did, the work would be confusing, because vim has its own commands for copy and paste. Those unfortunately don’t work with the “outside world” — the X11. But it’s possible to make them work, so let’s have a look :-).

In order to make it work in terminal, vim has to be compiled with X11 clipboard support. This is indicated by +xterm_clipboard string in vim’s version. To check if the clipboard support is present in your version, try this command:

$ vim --version | grep "\+xterm_clipboard"

On ubuntu and debian-like distros vim comes compiled with this feature, but on RHEL/Fedora/SUSE without. If you are running Redhat/Fedora/CentOS, you can install the vim-X11 package (if you have gvim then this is already installed). This provides the vimx command, which is a console version of Vim with X11-clipboard support. Good idea is making an alias vim to vimx by adding this line to your .bashrc:

if [ -e /usr/bin/vimx ];
then
  alias vim='/usr/bin/vimx';
fi

All you need to do after that is add this line to your .vimrc:

set clipboard=unnamedplus

And you’re good :-). Now you can easily copy and paste from clipboard using standard commands (y, d and p).

Detailed description of what’s going on is here.

Unhighlight text after search

How to remove the highlight of last searched phrase? Try this:

:noh

Sources

To be continued …