Free Software

Software Engineering with FOSS and Linux

Migrating from VirtualBox to VMWare in Linux

Ok this is not really a post about free software, in fact it is quite the opposite, but after spending a long time trying to figure a way to convert a VirtualBox image to a VMWare one I figured someone may benefit from it. The reason I had to switch was that I couldn’t get DirectX and 3D Acceleration to work in VirtualBox, but it works fine in VMWare (if you have any suggestions to help me with DirectX and 3D Acceleration in VirtualBox please post here, since VirtualBox seems to be running smoother on my laptop). All the info is scattered around the web, but searching for it is tricky since many links refer to old VirtualBox versions and most of them refer to the opposite operation, i.e. migrating from VMWare to VirtualBox. So here we go:

– Locate your VirtualBox virtual drive, in my case this was /var/local/virtual/windows.vdi. For the rest of the post I assume we are in the virtual drive’s directory (i.e. /var/local/virtual)
– Convert it to raw format. In later versions of VirtualBox (I am using 3.1.2) this is done through the VBoxManage tool:

VBoxManage internalcommands converttoraw windows.dvi windows.raw

– Install qemu
– Convert the raw file to a VMWare compatible image format:

qemu-img convert -f raw -O vmdk windows.raw windows.vmdk

You can now delete the raw file to save some space.

– Launch vmware. I am using VMware Workstation 7.0.1.
– Create a new Virtual Machine. At the wizard, use the following steps (the important options are in blue):

Virtual Machine Configuration: Custom
Virtual Machine Hardware Compatibility: Workstation 6.5 – 7.0
Install operating system from: I will install the operating system later
Guest Operating System: Whatever you’re running (I’m using the vm for Windows XP Professional)
Virtual Machine Name: Whatever you want, or leave the defaults
Processors: Whatever you want, or leave the defaults. I’m using 1
Memory: As much as you like. I’m using 1GB
Network Connection: Use network address translation (NAT)
I/O Adapter Types: SCSI adapter: BusLogic.
Disk: Use an existing virtual disk. Then browse for the .vmdk file

When you start the VM, you will be asked to convert it to new format. Do so, since qemu-img may generate formats compatible with older VMWare versions. Also don’t forget to install VMWare Tools (from the VMWare menu select VM, then Install VMWare Tools…), 3D Acceleration didn’t work until I did.

Advertisements

February 21, 2010 Posted by | linux | , , , | 7 Comments

Dealing with mouse and touchpad freezes in Linux

Sometimes the desktop in several Linux distributions freezes for no apparent reason; active windows can still be used, and the mouse pointer can be moved around, but clicking is impossible. Furthermore, your touchpad can no longer be controlled; the ‘Touchpad’ tab disappears from the System / Preferences / Mouse menu. Even if mouse functionality eventually returns, the touchpad remains uncontrollable. This extremely annoying bug occurs randomly and may last for a couple of seconds, or until you restart your X server.

If you check your system’s log after such an event (/var/log/messages) you will notice a few entries similar to these:

Sep  9 09:38:15 umbra kernel: [ 4939.006198] psmouse.c: DualPoint TouchPad at isa0060/serio1/input0 lost sync at byte 1
Sep  9 09:38:15 umbra kernel: [ 4939.012220] psmouse.c: DualPoint TouchPad at isa0060/serio1/input0 - driver resynched.

Basically this indicates an IRQ conflict between your mouse and your touchpad. This is a Linux kernel bug (I am currently using 2.6.28) and as such it affects most distributions. An easy way to recover both mouse and touchpad functionality without having to restart your X server is restarting the mouse driver. Run the following commands on a terminal window:

sudo rmmod psmouse
sudo modprobe psmouse

If there is no terminal window open, you can use one of the following:

  • In Gnome or KDE, press Alt + F2, type gnome-terminal and press Enter
  • Press Control + Alt + F1, login with your username and password, type the commands, then press Control + Alt + F7 to get back to X

Hopefully a future kernel release will fix this problem for good.

September 9, 2009 Posted by | linux | , , , , , , , | 33 Comments

Debugging and profiling your C/C++ programs using Free Software

Every developer in Linux knows (and most likely uses) the GCC, a set of compilers, tools and libraries that form the foundation of pretty much all C and C++ development in the FOSS world. However, fewer people, even among professional software developers, are aware of the superb debugging and profiling options available to them.

Before introducing new tools, I will first talk about a few gcc options. Note that several GCC options change with each release. I am using 4.3.3; if something doesn’t work for you, check the documentation for your version.

Let’s begin with a few compiling options that will help you detect errors at compile time. This means less debugging will be needed in the future, which is always a Good Thing.

-Wall

Enable most warnings. According to GCC’s man page,

“This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.”

Note that as of version 4.3.3, two of the most powerful features enabled by -Wall, warnings about uninitialized variables use and out of bounds array checking will only work if you specify an optimization level (-O1 for uninitialized variables, -O2 for array bounds checking). This is planned to change in future GCC versions.

It is generally suggested that all your programs are compiled with the -Wall option enabled. My suggestion is to also compile your program with -O2 to let GCC test for uninitialized variables and out of bounds array use; turn it off afterwards if you wish to have full access to debuging info.

-Wshadow

Warn about shadow variables. Shadow variables (i.e. variables declared inside an inner block with the same name as a variable already existing in the scope) are valid in C/C++, but they are quite error prone. You should avoid using them; this compiler option will help you track unintended use.

-Werror

Treat warnings as errors. This will make the compiler treat all warnings as errors, interrupting compilation. Specific warnings can be exempted from this flag. A common example is using the -Wno-invalid-offsetof flag to supress warnings about using the offsetof() marco to reference member variables of uninitialized objects.

The following flags are related to debugging and profiling:

-g

Generate debugging info in the operating system’s native format. You can use the GNU debugger (gdb) to debug programs compiled with the -g option. Note that even though you can generate debugging info for programs compiled with an optimization (-On) option, debugging data will be less informative.

You should always use the -g option when developing your programs; you can turn this off in your final product.

-pg

Generate profiling info. When running a program compiled with this option, a file named gmon.out will be generated, containing profile information; you can use the GNU profiler (gprof) to analyse this file. Note that the -pg option must be specified both in compiling and in linking options. Personally I never use -pg; I prefer the profiling tool of valgrind, which I will mention later in the article.

As I mentioned, you can use the GNU debugger (gdb) to debug a program compiled with the -g option. An extended description of gdb is beyond the scope of this post; you can check one of the numerous tutorials available on the Internet. However, a few points of interest:

  • You can debug a running process of an executable. Use ps to find the process id (pid) of an executable, run gdb <executable> to begin gdb, and use the attach <pid> command to attach gdb to the running process.
  • You can debug an executable based on a core dump. Simply run gdb <executable> <core>. Note that nowadays programs will not generate a core when they crash, unless the ulimit -c option has been specified in the shell. This is done for security reasons, as an unintented core file can be used to hack into a program. Do not forget to enable this option when developing.

There are several graphical front-ends to gdb available. I prefer to work from the command line, since most of the time I’m debugging remote programs using a terminal window. However I have found kdbg to be an excellent front-end. Here is a screenshot:kdbg - A graphical front-end to gdb

Other available options include ddd, xxgdb and nemiver. Most C/C++ IDEs, such as Eclipse, Netbeans,  KDevelop and Anjuta also contain integrated front-ends to gdb. However getting familiar with the core gdb functionality outside an IDE is probably a good idea.

Valgrind, which I already mentioned earlier, is an invaluable set of tools to anyone dealing with non-trivial debugging and profiling. The platform currently contains the following tools:

  • A memory error detector
  • Two thread error detectors, including race conditions
  • Three profilers: cache and branch-prediction profiler, call-graph generating cache profiler, and heap profiler

Extended documentation on the various tools is provided on http://valgrind.org. Here I will display examples of my favotire tools: the memory error detector, and the call-graph generating cache profiler.

Consider the following trivial and utterly useless program:

#include <string.h>
#include <stdio.h>

void myfunc( const char *arg )
{
    char *p, *ptr;
    ptr = strdup( arg );
    /* process ptr here, but forget to free memory */
}

int main( int argc, char *argv[] )
{
    myfunc( "hello world" );
    return 0;
}
Checking this program with valgrind will reveal the memory leak:
xenofon@umbra:~/tmp$ valgrind --track-origins=yes --leak-check=full ./a.out |tee valgrind.out
[...]
==21882== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==21882==    at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==21882==    by 0x40BB34F: strdup (in /lib/tls/i686/cmov/libc-2.9.so)
==21882==    by 0x80483D4: myfunc (in /home/xenofon/tmp/a.out)
==21882==    by 0x80483F6: main (in /home/xenofon/tmp/a.out)
[...]

In non-trivial examples this alone can be a big saver. But the memory check of valgrind is MUCH more than this. Consider the following example:

#include <iostream>
#include <string>
using namespace std;

class Person {
private:
    string name;
    int age, sex;
public:
    enum { MALE, FEMALE };
    Person( string name, int age, int sex )
    {
        this->name = name;
        this->age = age;
        //this->sex = sex; /* we forgot this! */
    }
    void Print( )
    {
        cout << "Name: " << name << endl;
        cout << "Age : " << age << endl;
        cout << "Sex : " << ( sex == MALE ? "Male" : "Female" ) << endl;
    }
};

int main( int argc, char *argv[] )
{
    Person p( "alphamale", 32, Person::MALE );
    p.Print();
    return 0;
}

Valgrind will catch the error:

[...]
Name: alphamale
Age : 32
==22871== Conditional jump or move depends on uninitialised value(s)
==22871==    at 0x8048BCC: Person::Print() (in /home/xenofon/tmp/a.out)
==22871==    by 0x8048A5B: main (in /home/xenofon/tmp/a.out)
==22871==  Uninitialised value was created by a stack allocation
==22871==    at 0x80489D0: main (in /home/xenofon/tmp/a.out)
Sex : Female
[...]

Even though this example is also trivial, using uninitialized variables is an extremely common mistake. The -Wuninitialized compiler option of gcc (which is automatically included if you specify the -Wall flag) will help in some cases, but not all. It will not detect the above case, and it certainly cannot detect any case that can only occur at run-time. Valgrind checks all the allocated memory at bit level, and issues a warning when you attempt to use uninitialized areas.

Valgrind can also be used for profiling. I commonly use the call-graph cache profiler to generate profile data which can be analyzed by specialized tools. First, ask valgrind to use the appropriate tool:

xenofon@umbra:~/program/arctic/server$ valgrind --tool=callgrind ./server 2702

Once the program terminates, a file named callgrind.out.<pid> is generated. This file contains the profiling info of your program. If your program forks, a seperate callgrind.out file is generated for every child, distinguished by the pid extension. You can then use the amazing kcachegrind tool to inspect the info:

kcachegrind

Kcachegrind lets you inspect CPU time spent in each function and all its subroutines, navigate through the call graph, check a list of callers and callees, and is generally an invaluable tool to detect bottlenecks in the performance of your program. Furthermore, it is extremely user-friendly. Give it a try, you will love it.

Obviously there are several more tools to help you debug and profile your C/C++ programs. Furthermore, debugging and profiling, just like all programming, is more about the process than the tools. However, once you learn to make them part of your programming activities, you will happily find out that there are several superb free software tools to support your endeavours.

May 18, 2009 Posted by | Programming | , , , , , , , , | 12 Comments