Friday, November 14, 2014

How to create and use your own custom compare method for STL classes?


As you may have known, the STL libraries provide you with a vast collection of classes and algorithms that you can use in your program.
Some of the most popular data structure classes that you may have known are vector and set.
In this articular article, I will talk about both with examples.

STL::set<YourClass>   variable;

Typically this would be your declaration for a set. Notice a set always have unique elements in it that's why sorting is required to help determine if a new element is already existed in the set. Therefore, the elements are already sorted in some default order. The next question is what if you don't like the default sorting.  Let's say you want to sort by the typeID of the object.
If this is the case, you will have to create  you own compare method:

STL::set<YourClass, CompareMethod> variable;

Let's say your class name is Object and the compare method is call SortByType.

STL::set<Object, SortByType> variable;

You would declare your compare method like this:

struct SortByType
{
bool operator()(const Object & object1, const Object & object2)
{
return (object1->GetInterfaceMetaClass()->GetTypeID() > object2->GetInterfaceMetaClass()->GetTypeID());
}
};


Now you can copy the content from the set with default sorting to the your new set:

SLT::set<Object> originalSet;

STL::set<Object, SortByType> newSet(originalSet.begin(), originalSet.end());


If you want to copy to a vector, then you can insert and then sort your vector.

bool SortByType(const RefARpObject & object1, const RefARpObject & object2)
{
return (object1->GetInterfaceMetaClass()->GetTypeID() > object2->GetInterfaceMetaClass()->GetTypeID());
}

STL::vector<Object> vect;
vect.insert(originalSet.begin(), originalSet.end());

STL::sort(vect.begin(), vect.end(), SortByType);

Notice the declaration for SortByType used in the set template are different than the one used by the
sort algorithm.



Friday, October 24, 2014

Linux commands equivalent to Windows start command

In Windows DOS prompt console, you can use the start program to do a lot of things. Here are just a few examples:
>start .   -- open the current folder. Notice this is very helpful if your path is very long. It saves you a lot of time having to traverse to the folder you want manually.
>start http://yahoo.com   -- open yahoo website
>start c:\temp  --- open the Windows dialog with the c:\temp folder opened.


Now, how do we do this in Linux?

If you are using Gnome desktop manager, then you can run this. How do you know you are using a Gnome desktop manager? You can run >pstree and look for gnome keywords. If you do see one, you are probably using a Gnome desktop manager.

>gnome-open .
>gnome-open http://yahoo.com
>gnome-open c:\temp



A generic way to do this is to run xdg-open, but this script is not always installed.

>xdg-open .
>xdg-open http://yahoo.com
>xdg-open c:\temp


Friday, May 16, 2014

How to debug unknown exception in AIX system using dbx?

dbx is the equivalent of gdb debugger in Linux.
Let's assume you have an issue with an application which terminates with an exception in the AIX system.
You don't know where this exception is thrown in the code and the exception message is not very clear to you. The first thing to you need to know is where this exception gets thrown in the code so you can fix the issue. Here is the trick:

>dbx  myprogram

(dbx) stop in __ThrowV6  //break at any exception, __ThrowV6 is the exception handler. All exceptions will go to this exception handler. If you stop here and view the stack you will know exactly where the exception is being thrown.
(dbx) r -c arguments   //run the program with specific arguments


This trick above is handy if you don't know where to set a break point in the program since the exception can be thrown in many places in the code. Some code does handle the exception, but it would just print out a generic message which is useless. It is a good idea to handle the exception and print out the real message.

#include <exception>
using namespace std;
try
{
....
}
catch(exceptio& e)
{
cout << e.what() << endl; //this will print out the actually error causing the exception.
}

Thursday, May 15, 2014

How to share/access Linux folder from Windows machine?

Samba is a service that would allow you to share your Linux folder so that you can access it on your Windows machines.
Here is a quick tutorial on how to do it.

1) first you need to check if the samba server is running or not
/sbin/service --status-all  | grep smb

If it is not running yet, try to start it

sudo /sbin/service smb start

2) second check if this shared definition exists in your smb.conf file

[homes]
         comment = Home Directories
         browseable = no
         writable = yes
         valid users = %S

In order to access the symlinks in your samba share, you need to add the followings to your global section:

[global]

follow symlinks = yes
wide links = yes
unix extensions = no

If the above does not exist in the smb.conf file, add them to the file

sudo emacs -nw  /etc/samba/smb.conf

Your home directory should be shared by default.

Once you have finished modifying the file, restart the samba service

sudo /sbin/service smb restart

3) If you still cannot access the shared in Windows, check and make sure the user is already in the samba database.
It will prompt for the password, it is good to use the same password you used to log into windows.

sudo smbpasswd -a nquach

Once you have everything setup, you can access your linux share on Windows by using this path.

\\linuxmachine\username or \\LinuxHostName\nquach

Cheers

Monday, May 12, 2014

How to profile your code using valgrind?



There are various ways that you can profile the code. I will talk about Callgrind and Massif. You can get a lot more information from these two profilers, but I will just mention about my purposes for using them.
Use Callgrind to find out which methods get called the most, and use Massif to find out which methods use the most memory.

Callgrind records the call history and the program's calls graph. Here I am using it to find which methods get called the most.

Example:
>valgrind --tool=callgrind  --callgrind-out-file=callgrind_prof.out validaterpd -s -o consichk.txt -r coreapplication_OH452963239_v326.rpd -pAdmin123

Use kcachegrind to view the output from callgrind.

>kcachegrind callgrind_prof.out





Massif is a heap profiler. Here I am using it to find out the peak memory usage of my program.
I can also find out which method uses the most memory as well.
For details on now to interpret the results of your profile, please check this page

http://valgrind.org/docs/manual/ms-manual.html


Occasionally you may running into issues where valgrind fails to run complaining about the
VG_N_SEGMENTS segment being too low.

If you run into this error, you need to change the default value and recompile valgrind.
You can search for the cpp file defining this  VG_N_SEGMENTS value and change it.
For example, I have changed it from 30000 to 90000.



Example:

>valgrind --depth=200 --tool=massif  --massif-out-file=main_mem_prof.out validaterpd -s -o consichk.txt -r coreapplication_OH452963239_v326.rpd -pAdmin123

>ms_print main_mem_prof.out > main_depth200.txt


From the screenshot, you can tell that the peak is at snapshot 4 and the peak memory usage is around 4.2GB.

Friday, May 9, 2014

How to install software on your Linux machine?

This article will talk about how to install any software on your Linux machine, if you have the source code. I will not talk about how to install the software from the rpm binary file.

If you already have the RPM file, you can install the software by running

rpm -ivh  filename.rpm

If you want to deinstall from an application installed from a RPM package, you can run

rpm -e <applicationname/processname>
>rpm -e oracle-xe


Here are some of the advantages of installing software from the source code:

1. You cannot find the rpm binaries for your platform
2. Only the source code is provided by the website.
3. You cannot find the latest rpm binaries for the latest source code.

Most of the open source code project will tar and zip the source code in a file like *.bz2 or *.gz.

Here are the steps you need to do:

1. Download the source code. Let's say it is called valgrind-3.7.0.tar.bz2
2. Extract the file.

>tar xvjh valgrind-3.7.0.tar.bz2
or
>tar xzvh valgrind-3.7.0.tar.gz

Assuming the files get extracted into valgrind37 folder
3. cd to the source folder  valgrind37

>cd /valgrind37

4. Configure the software

>./configure  \-prefix=/valgrind37   //run the configuration script. Notice I use to prefix to specify where
I want to install the software. The directory must be an absolute path. If you don't use the prefig, it will install the software in the default location like /usr/bin/.

5. Build the source code
>make

6. Install the sofware
>make install

7. Clean the temp build files.
>make distclean    //you need to run this every time you run ./configure with different prefix values.

8. Set the environment
Most of the time, you only need to set these two environment variables to run any programs.
>export LD_LIBRARY_PATH=/vagrind37/lib/valgrind/:$LD_LIBRARY_PATH
>export PATH=/valgrind37/bin:$PATH




Thursday, April 24, 2014

Linking error LNK2019: unresolved external symbol


Example of an error:

error LNK2019: unresolved external symbol "__declspec(dllimport) protected: virtual __cdecl SECMDIFrameWnd::~SECMDIFrameWnd(void)" (__imp_??1SECMDIFrameWnd@@MEAA@XZ) referenced in function "public: virtual __cdecl ACMainFrame::~ACMainFrame(void)" (??1ACMainFrame@@UEAA@XZ)

How do you fix this error?

Let's say you have checked the followings already:
1. The library file containing the symbol above is in the path.
2. The library files and your build are in 32-bit or 64-bit. You cannot link a 64-bit build to a 32-bit libraries.
3. Make sure your release/debug build is linking to the release/debug build of the libraries.

Next you need to check if  the symbol showed in the error is in the library file.

To check if  symbol virtual __cdecl SECMDIFrameWnd::~SECMDIFrameWnd(void) is in the library, you can use the dllexportviewer program.
You can load the library file into the dllexportviewer program to see all of its symbols. Then you can locate/search if the symbol existed.

Let's say you cannot find it. You can only see this symbol in the library.

virtual __thiscall SECMDIFrameWnd::~SECMDIFrameWnd(void)

Obviously there is a mismatch. The mismatch here indicates that the calling conventions are different. Now you need to know why your program is looking for the cdecl calling convention instead of __thiscall.

One problem is you could have the calling convention set incorrectly in your project settings.
If that's the case, you can check the project settings and change it to use the _fastcall calling convention to fix the issue.







How to determine if a program is thrashing in Linux?

When a program is thrashing, it runs very slow because there was not enough physical memory on the system. Consequently, a lot of reading and writing to disk are happening to swap data in and out of memory. For example, if program needs to load new data into memory in order to run but there is no memory available, the OS would have to take something in memory and write it to disk to free up the memory needed for the program to run further. This is a swap out. When the program needs to access to the old data on disk, the data will have to be copy back to the memory. This is a swap in.
If there is a lot of swap in and out, it indicates the program is thrashing.

When a program is running very slow, and you want to know if it is because of thrashing.
Let's assuming that it is running slow not because it is calculating something complicated that takes a lot of CPU cycle.
Here are the steps you can check to tell if it is thrashing:

1) The first thing you need to look is to check how much memory is available when the program is running.

>free    // running free will tell you how much memory is available. You won't see the available memory equal to zero because the OS would not allow that to happen since it needs some free memory to operate properly.

~# free -m  //-m display in MB
             total       used       free     shared    buffers     cached
Mem:          5800       5774         25          0          7        609
-/+ buffers/cache:       5157        642
Swap:        10047       5047       4999


If there is not a lot of memory left, it does not always mean the program is thrashing. But it is a good indication that a lot of pages are being swapped in (si) and out (so).

2) To see if there is a lot of swappings happening, run vmstat while the program is running.

# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 2802448  25856 731076    0    0    99    14  365  478  7  3 88  3
 0  0      0 2820556  25868 713388    0    0     0     9  675  906  2  2 96  0
 0  0      0 2820736  25868 713388    0    0     0     0  675  925  3  1 96  0
 2  0      0 2820388  25868 713548    0    0     0     2  671  901  3  1 96  0
 0  0      0 2820668  25868 713320    0    0     0     0  681  920  2  1 96  0

Here you see zero value for si and so, but if these columns have a high value, it indicates the program is thrashing.