A Developer's Diary

Dec 25, 2008

Building Apache Log4cxx on Windows

Apache Log4CXX is a logging framework for C++ patterned after Apache log4j.
Read below for sequence of steps for building the software with Visual Studio .NET 2003

1. Download APR 1.3.3 and extract it. Rename to apr
2. Download APR Util 1.3.3 and extract it. Rename to apr-util
3. Download Log4CXX 0.10.0 and extract it
4. Enter directory apache-log4cxx-0.10.0
5. Execute configure.bat
6. Execute configure-aprutil.bat
7. Open the log4cxx.dsw file. When asked to convert the solution, click Yes to All
8. Right click on Solution log4cxx and select Build solution


Read more ...

Jul 15, 2008

Code to check if a number can be expressed in the form 2^n

The bit representation of any number of the form 2^n will have only one field set.
If we do an AND operation with the (number-1) the result is 0
i.e (n & n-1) is 0

The number is of form 2^n if (n & n-1) is 0


Read more ...

May 6, 2008

Installing and Configuring Software/Patches on HPUX

The information on individual patches in a patch bundle can be obtained by using

/usr/sbin/swlist -s /temp/depot_name -l product -a readme patch_name


Patch and software can be installed using the following command. This will open up an interactive interface where you have to select and install the software.

/usr/sbin/swinstall -s /directory/depot –x autoreboot=true

Read more ...

Apr 4, 2008

Java - Debugging In Tomcat 5.5

Steps to be followed to enable debugging in Tomcat 5.5 through Eclipse

Configuring Tomcat
1. Go to configure options in Tomcat5.5
2. Select Tab "Java" and in Java Options add the following lines
-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000

Configuring Eclipse
1. Click on Debug
2. Select Remote Java Application
3. In connection properties add host and Port = 8000
4. Add break point

Happy Debugging :)
Read more ...

Apr 3, 2008

Shell Scripting - Parallel Process Execution in Background

Command for checking the background jobs which are in running state

jobs -r | wc -l


Non-interactive ftp transfer to automate uploading of files parallely on different platforms.

#!/bin/bash

LINUX=linux
AIX=aix
SUNOS=sunos

WIN32=win

MACHINES=" \
    $LINUX \
    $AIX \

    $SUNOS \
    $WIN32"

function checkjobs(){
if [ `jobs -r | wc -l` -eq 0 ]; then

echo "All Background Process completed Successfully"
return 0
fi
sleep 10

checkjobs
}

function upload(){

if [ $# -eq 0 ]; then

echo "Missing Argument"
exit 1
fi

# Non-interactive ftp transfer
ftp -i -v -n hostname <<END_FTP

    user root root
    binary
    cd test
    put "file$1.exe"
    bye

END_FTP
echo "Uploaded file$1.exe"
return 0
}

function uploadfile(){
echo "Uploading Files  Started"
for host in $MACHINES

do
echo "Uploading FILES on host $host"
upload $host &
done

}

uploadfile
checkjobs
echo "All Files Uploaded Successfully"





Making things more simpler, we can use the special command wait and rewrite uploadfile so that we need not check for the background processes

function uploadfile(){
echo "Uploading Files  Started"

for host in $MACHINES
do
echo "Uploading FILES on host $host"

upload $host &
done
wait
}

uploadfile
echo "All Files Uploaded Successfully"





Read more ...

Mar 31, 2008

Shell Scripting - Rotating Progress Bar

The echo -e command is used to change the term color


echo -e "\E[40;32m\b\c"
#Changes the term color to green with black background



#!/bin/bash

function success_banner()

{
echo -e "\E[40;32m\b\c"
echo -e "[OK]"
echo -e "\E[40;37m"

}

function progress_banner()
{
echo ""
echo "##############################################################"

echo ""
echo -e "Step: $1 \b\c"
}

function rotate_line(){

INTERVAL=1
timecount="0"
while :
do
timecount=`expr $timecount + 1`

case $timecount in
"1")
echo -e "-\b\c"

sleep $INTERVAL
;;
"2")
echo -e '\\'"\b\c"

sleep $INTERVAL
;;
"3")
echo -e "|\b\c"

sleep $INTERVAL
;;
"4")
echo -e "/\b\c"

sleep $INTERVAL
;;
*)
timecount="0" # Reset the count to 0

esac
done
}

function start_rotation(){
rotate_line &

}

function stop_rotation(){
rotate_line_pid=$!
kill -9 $rotate_line_pid

echo -e "\b\b\b"
}

progress_banner Rotation_Bar_Started
start_rotation
sleep 5
stop_rotation
success_banner Ok




Read more ...

Mar 26, 2008

Finding Linux Version

Linux Release Version can be obtained by executing


cat /etc/redhat-release


For getting linux kernel versions execute

uname -a or uname -r

Read more ...

Mar 2, 2008

Accessing 32 bit DLLs' from 64 bit code

A 64-bit process cannot load a 32-bit module into its process space, and a 32-bit processes cannot load a 64-bit module into its process space. The only way that communication can happen between 32-bit and 64-bit modules is through interprocess communication (IPC).

In other words, 32-bit and 64-bit processes can exchange data using IPC techniques such as out-of-process COM, sockets, Windows messages or memory mapped files.

A 32-bit software product contains the main module which calls into the DLL. As long as both the main module and the DLL are 32-bit processes the product can run on both 32-bit and 64-bit platforms. If both the main module and the DLL are migrated to the 64-bit platform, then they can both run in a native 64-bit process. However if only the main module is migrated to 64-bit, it will not be able to load the 32-bit DLL.
The best way to migrate such a product to a 64-bit platform is to migrate both the main module and the dependency DLL, but if the dependency DLL cannot be migrated then it cannot be loaded into the 64-bit process and the application won't work.

Alignment in Memory: The alignment of data in memory is different for 32-bit and 64-bit processes. This means that your more complicated custom data structures may be serialized by a 32-bit process in a way that is different to that expected by a 64-bit process, and vice versa.

Datatype Size: The differences are mainly in pointers which are 32 bits long in 32-bit platform and 64 bits long in 64-bit platform. The pointer-derived data types such as HANDLE and HWND (Windows) are also different between 32-bit and 64-bit versions.

More on Accessing 32 bit DLLs' from 64 bit code

Read more ...

Knowing Default Parameters in C++ and Java

C++ allows functions to have default parameters. This is useful when a parameter should have a specified value when the caller does not supply any value.

class DefParam{
    public:

        //Declare the default parameter(s) in function decalaration
        void printVal(int x=10);
};

//Don't repeat the default parameter in function definition
void DefParam::printVal(int val){
    printf("Val = %d\n",val);
}

int main(){
    DefParam obj;
    obj.printVal(); //Passes 10 to printVal()

    obj.printVal(25); //Passes 25 to printVal()
    return 0;
}

$ ./a.exe
Val = 10
Val = 25

Note: Java does not provide default parameter values, but you can use overloading to achieve the same effects.
Read more ...

Feb 28, 2008

AIX - Tuning process memory size limits

When a process runs out of memory, the process often ends. On AIX systems, the system error log might indicate that the process ended due to memory allocation failure. Use the following command to display the error log

errpt -a | more


On UNIX systems, each user can either inherit resource limits from the root user or have specific limits defined. The most useful setting to use for the process size limits is unlimited. That way, the system process size limits are defined to allow the maximum process growth.

On AIX systems, the number of data segments that a process is allowed to use also limits the process memory size. The default number of data segments is 1. The size of a data segment is 256 MB. Data segments are shared for both data and stack. The maximum number of data segments a process can use is 8

On AIX, the number of segments that a process can use for data is controlled by the LDR_CNTRL environment variable. It is defined in the parent process of the process that is to be affected. For example, the following example defines one additional data segment:

export LDR_CNTRL=MAXDATA=0x10000000


Read more ...

Feb 23, 2008

Print Hello, World without using semicolon

Not used practically, but asked very frequently by the interviewers.

#include <stdio.h>

int main(){
if(printf("Hello, World\n")){}
while(!printf("Hello, World\n")){}
switch(printf("Hello, World\n")){}
return 0;
}

Read more ...

Feb 18, 2008

Symmetric Cipher

Symmetric Ciphers
Functions Provided: Encryption and Decryption.

They are known as Symmetric because both the sender and the receiver share the same key to encrypt and then decrypt the data. The main function is to provide Confidentiality.
e.g. Say Alice needs to send Bob a confidential document. She would encrypt the document using a symmetric cipher and a key and send it to Bob. Anybody looking at the message enroute to Bob will only see sequence of bytes. Bob on receiving the message will use the same key and the decrypt function of the symmetric cipher used by Alice to produce the original message. Few Symmetric Ciphers are: rotate cipher, Caeser cipher etc.









Disadvantages:
1. The key has to transferred to Bob through a separate communication channel which has to be secure. Then the question arises, if we have a secure communication channel, then why not send the document through that secure channel.
2. If Alice needs to send the document to 100 people, then she would have to use 100 different keys and encrypt the message 100 times and share them across.


Read more ...

Direct Initialisation and Copy Initialisation

How many ways are there to initialize a variable?

1. MyType type;

Here the variable type is initialised using the default ctor MyType::MyType();

2. MyType type();

This looks like a variable declaration, but it's a function declaration for a function type that takes no parameters and returns a MyType.

3. MyType type(u);

This is direct initialization. The variable type is initialized using MyType::MyType(u);

4. MyType type = u;

This is copy initialization and the variable type is always initialized using MyType's copy ctor. Even though there is an '=' sign, this is a copy initialization and not an assignment.

The form MyType type(u) should be preferred. It always works where 'MyType type = u' works and has other advantages e.g (It can take multiple parameters)

Code

/* Example1.cpp */
#include <iostream>
#include <string>
#include <iomanip.h>
class MyType{
private:
int age;
std::string name;
public:
MyType():age(10),name("pankaj"){
std::cout << "\nCalling Constructor 1\n";
}
MyType(int age, std::string str):age(age), name(str){
std::cout << "\nCalling Constructor 2\n";
}
MyType(MyType &t):age(t.age), name(t.name){
std::cout << "\nCalling Constructor 3\n";
}
void show(){
std::cout << "\nName is = "<<name;
std::cout << "\nAge is = "<<age;
std::cout << endl;
}
};

int main(){
MyType type;
type.show();
MyType t(type);
t.show();
MyType b(50, "Anky");
MyType a = b;
a.show();
}


Output:
$ ./a.exe

Calling Constructor 1

Name is = pankaj
Age is = 10

Calling Constructor 3

Name is = pankaj
Age is = 10

Calling Constructor 2

Calling Constructor 3

Name is = Anky
Age is = 50

Here, MyType a = b; also calls the Constructor 3

Code

/* Example2.cpp */
#include <iostream>
#include <string>
#include <iomanip.h>
class MyType{
private:
int age;
std::string name;
public:
MyType():age(10),name("pankaj"){
std::cout << "\nCalling Constructor 1\n";
}
MyType(int age, std::string str):age(age), name(str){
std::cout << "\nCalling Constructor 2\n";
}
//MyType(MyType &t):age(t.age), name(t.name){
std::cout << "\nCalling Constructor 3\n";
}
void show(){
std::cout << "\nName is = "<<name;
std::cout << "\nAge is = "<<age;
std::cout << endl;
}
};
int main(){
MyType type;
type.show();
//MyType t(type);
//t.show();
MyType b(50, "Anky");
MyType a = b;
a.show();
}


Output:
$ ./a.exe

Calling Constructor 1

Name is = pankaj
Age is = 10

Calling Constructor 2

Name is = Anky
Age is = 50

Here MyType a = b; works even when Constructor 3 is commented out because a default copy constructor is created for you when you don't specify one yourself. In such case, the default copy constructor will simply do a
bitwise copy for primitives (including pointers) and for objects types call their copy constructor. If in the later case, a copy constructor is not explicitly defined then, in turn, a default copy constructor will be implicitly created.

Read more ...

Feb 17, 2008

80-20 Rule

According to 80-20 Rule: Look for that 20% of the code where your program spends 80% of it's time

e.g. The HTTP specification is a 100 page document that describes all possible HTTP requests that a web server must handle.Most of the HTTP requests that traverse through the web are very simple. They contain only a small subset of the possible HTTP headers that a request can possibly contain.

Since Microsoft and Netscape have a dominating share of the browser market, all you need to do is peek at the request headers sent by these two browsers. This is yet another manifestation of the 80-20 rule—20% of your possible inputs will occur 80% of the time. An efficient use of programmer resources is to tune those 20% of the request types that appear 80% of the time.
The HTTP Accept header is part of an HTTP request. It specifies what document formats are acceptable to the browser. The HTTP specification allows for the Accept header to have any combination of upper and lowercase. When you read a string token and want to determine if it is the Accept header, it is not enough to perform

memcmp("Accept:", header, 7)

We need to perform a case-sensitive string compare. We implemented a home-grown version for a casesensitive string-compare:

int memCaseCmp(char*,char*, int) {...}

To be HTTP compliant, the correct action should be

Code
if ( 0 == memCaseCmp("accept:", header, 7) )
{
// This is the Accept header
}

However, memCaseCmp() is not cheap. It needs to uppercase both strings and then call memcmp(). This is where our domain expertise must come into play. Like we said, Microsoft and Netscape have a commanding share of the browser market. The Accept header they send happens to be "Accept:". This is only one of the many upper- and lowercase combination that HTTP allows, but it is the one we are going to receive 95% of the time, so it is the one we care about. The following test tries to take advantage of that:

Code
if ( (0 == memcmp("Accept:", header,7)) || // An intelligent // gamble... (0 == memCaseCmp("accept:", header, 7))) { // This is the Accept header }

In 95% of the inputs, the memcmp() test is going to succeed, and we will never call the more expensive memCaseCmp().

Read more ...

Feb 16, 2008

Synthesised Default Constructor

If we do not explicitly define constructors, then the compiler will generate the default constructor for us. The compiler-created default constructor is known as Synthesised Default Constructor.

It initializes each member using the same rules as are applied for variable initializations. Because the synthesised constructor does not automatically initialise the members of build-in type, we have to define the default Constructor explicitely. Bugs due to uninitialised variables can be hard to find.

Unitialised variables cause Run-Time problems as no compiler can detect all uses of uninitialised variables.

Read more ...

Feb 4, 2008

Finding dependent libraries on Aix

Finding dependent libraries on AIX.

Method 1.
This is a small dlopen test program "dltest.cpp"

//File: dltest.cpp

#include <stdio.h>
#include <dlfcn.h>

int main()
{
    char str[20] = {0};
    printf("\nEnter path to the Library to be loaded = ");
    scanf("%s", str);

    void *libhandle = dlopen(str, RTLD_LAZY);
    if(NULL == libhandle)
    {
        printf("\nUnable to load library. Error: %s\n", dlerror());
    }
    else
    {
        printf("\nSuccessfully loaded library %s\n", str);
    }

    return 0;
}

Compile the above program using:
xlC_r -brtl -o out dltest.cpp

Executing the file ./out will give the dlerror() output and the missing dependent libraries.

Method 2.
A dirty way to search.

ldd filename


It will not list the libraries which are present. It simply displays "Cannot Find" all libraries which are dependent and not found.
More conveniently

truss ldd somefilename.so >> output.txt 2>&1

Check the output.txt and search for libs which are not there.
Read more ...

Jan 30, 2008

Overview of 32-bit and 64-bit objects

It is important to generally understand how 32-bit and 64-bit objects are related in a computing environment, since there can be several dependencies between them that can affect everything from what hardware you purchase to how you deploy your applications.

32-bit and 64-bit hardware
32-bit computer hardware uses 32 bits to represent memory addresses and to process instructions and data. 64-bit hardware uses 64 bits to do the same thing. In general, 32-bit operating systems run on 32-bit hardware and 64-bit operating systems run on 64-bit hardware, although it is possible to run 32-bit operating systems on some 64-bit hardware.


32-bit and 64-bit operating systems
Operating systems consist of a kernel that interfaces directly with the hardware and operating system libraries. Operating systems come with either a 32-bit or 64-bit kernel, or, in some cases, both. In general, 32-bit operating system kernels can exploit four gigabytes of real memory (the physical RAM shared by the operating system and the running applications), whereas 64-bit operating system kernels can exploit more than this. Of course, some 32-bit operating system kernels can exploit more than four gigabytes of memory, but don't do this as well as 64-bit kernels. 64-bit kernels may be required on some operating systems to run 64-bit applications, which cannot be run if a 32-bit kernel is in use. This is the case with all UNIX operating systems, with the exception of AIX. On AIX, a particular exception, you can run 32-bit and 64-bit applications with either a 32-bit or 64-bit kernel; however, to prevent scalability problems it is better to use the 64-bit kernel even when running 32-bit applications.
Operating system libraries are important, because they are required to build and run applications. To build 32-bit applications, you have to link to 32-bit system libraries. To build 64-bit applications you have to link to 64-bit system libraries. Having the 64-bit system libraries available in a particular operating system doesn't necessarily mean that the system is actually capable of running 64-bit applications. This is often true of the 32-bit Windows operating system, which allows you to cross-compile and link 64-bit applications without being able to run them. This is also true of the UNIX platforms, because there are cases where you can install 64-bit-capable versions of operating systems on 32-bit hardware and cases where 32-bit kernels are incapable of running 64-bit applications. Essentially you can consider a 32-bit operating system to be one that only has the capacity to run 32-bit applications, whereas 64-bit operating systems can also run 64-bit applications, although this capability requires the use of 64-bit hardware and might additionally require the use of a 64-bit operating system kernel.

32-bit and 64-bit applications
32-bit applications are compiled such that memory addresses are 32-bit (four bytes) in size. These applications can directly exploit up to four gigabytes of virtual memory - the memory potentially available for use on a computer. This virtual memory constraint is present regardless of the amount of real memory (RAM) available on the system to be shared between the operating system and other applications. 64-bit applications on the other hand are compiled such that memory addresses are 64-bits (eight bytes) in size and can use more than four gigabytes of virtual memory without restriction. Operating systems typically also impose additional virtual memory restrictions on applications, and the theoretical maximum virtual memory per application may be as little as 1-2 gigabytes, even though it may have 32-bit addressing capability.
When you compile an application on a 32-bit or 64-bit platform, by default it is generally compiled to run on that particular platform. You can create 64-bit applications on 32-bit operating systems and 32-bit applications on 64-bit operating systems with some compilers by using special compiler-specific compile options and by appropriately linking to 32-bit or 64-bit libraries where appropriate.

32-bit applications can generally be run on both 32-bit and 64-bit operating systems, although many operating systems cannot run 64-bit applications if they employ a 32-bit kernel.

Read more ...

Jan 25, 2008

How to see the return value of the last executed command

We obtain the status of the last executed command by executing the following commands

Windows

echo %ERRORLEVEL%

Linux

echo $?

/** retvaluetest.c **/
int main(){
int retval = 10;
printf("\n Return Value is = %d", retval);
return retval;
}

Windows
D:\CPROBL~1>retvaluetest.exe

Return Value = 10
D:\CPROBL~1>retvaluetest.exe

Return Value = 10

Unix
[root@root]# gcc retvaluetest.c
[root@root]# ./a.out

Return Value = 10
[root@root]# echo $?
10
Read more ...