Tuesday, February 26, 2008

Debugging C/C++ programs using simple printf

printf is a good tool for debugging c/c++ source code.
The following printf code can be used to print the values of function name file name and line number:

printf("\nFile is = %s , Function is = %s , Line number is = %d\n", __FILE__ , __FUNCTION__ , __LINE__);


There are two C preprocessor macros : __FUNCTION__ and __PRETTY_FUNCTION__ .
The two produce the same output in C, but the latter provides more information when it appears in a C++ module.

Example using the __PRETTY_FUNCTION__:

printf("\nFile is = %s , Function is = %s , Line number is = %d\n", __FILE__ , __PRETTY_FUNCTION__ , __LINE__);


yields either:
(in case of c)
File is foo.c ,Function is foo,Line Number is 230

"or"
(in case of c++)
File is foo.cpp ,Function is int c::foo,Line Number is 230

Sunday, February 24, 2008

Linux/Window boot problem

Some time ago,I was unable to boot my system.
I have two os on my system :windows and linux.
Something get currupted and only grub command line was appearing after rebooting my system.
I remembered that was a very panic for me.I asked to my friends and system admin but not able to find any solution.
At that time I had some other priority works so I formatted my hard disk and reinstall windows.

Currently I faced the same situation in my office working PC.
Now I founded the solution of this problem and able to reboot my windows machine.

To run the window machine ,I read grub.conf over the internt and fire the following command s on grub command line menu

grub> rootnoverify (hd0,0)
grub> chainloader +1
grub>boot

huh.. my windows starts to boot.

Problems Vs Solutions

One day in the morning ,I got a mail from my Manager regarding problems and solutions.I was surprised what happened to my Manager that he is sending such a mail. when I read the mail and realized that its a very good mail for me to learn something.I am sharing this mail with you.I think its also gives you some idea how to give a simple solution of any problem easily.
-----------------
Difference between Focusing on Problems and Focusing on Solutions
Case 1 :
When NASA began the launch of astronauts into space, they found out that the pens wouldn't work at zero gravity (ink won't flow down to the writing surface). To solve this problem, it took them one decade and $12 million.They developed a pen that worked at zero gravity, upside down, underwater, in practically any surface including crystal and in a temperature range from below freezing to over 300 degrees C.

And what did the Russians do...?? They used a pencil.

Case 2:
One of the most memorable case studies on Japanese management was the case of the empty soapbox, which happened in one of Japan 's biggest cosmetics companies. The company received a complaint that a consumer had bought a soapbox that was empty. Immediately the authorities isolated the problem to the assembly! line, which transported all the packaged boxes of soap to the delivery department. For some reason, one soapbox went through the assembly line empty. Management asked its engineers to solve the problem.

Post-haste, the engineers worked hard to devise an X-ray machine with high-resolution monitors manned by two people to watch all the soapboxes that passed through the line to make sure they were not empty. No doubt,they worked hard and they worked fast but they spent a whoopee amount to do so.But when a rank-and-file employee in a small company was posed with the same problem, he did not get into complications of X-rays, etc., but instead came out with another solution. He bought a strong industrial electric fan and pointed it at the assembly line. He switched the fan on,and as each soapbox passed the fan, it simply blew the empty boxes out of the line.

Moral: Always look for simple solutions. Devise the simplest possible solution that solves the problems. Always focus on solutions & not on problems. So the end of the day the thing that really matters is HOW ONE LOOK INTO THE PROBLEM and Resolve early.

--------------

Friday, February 22, 2008

Open-Solaris Kernel Building and Installation

HOW TO Build and Install Open-Solaris Kernel
====================================
First clear some idea about Solaris and Open-Solaris.
Solaris: Solaris is based on Open -Solaris, and the other parts that have not been yet open sourced.
No full Solaris release based on Open -Solaris available yet.
The next Solaris release (currently codenamed “Nevada”) will be the first release based on Open- Solaris.

Prerequisite:
i-386 Solaris Machine,Compiler Toolchain.
Here I will discuss for x86 machine,but its same for the SPARC and AMD64.

Following are the steps to Build and Install Open-Solaris Kernel:
----------------------------------------------------------------------------

STEP 1: Download the Source code from opensolaris.org
if any one already have the following tar file please skip this step

Tools needed to build Open-Solaris are following:
1. Sun Studio 10 or Sun Studio 11 (compiler),named:
sunstudio10-ii-20050912-sol-x86.tar.bz2
2. ON-specific build tools(SUNWonbld),named:
on-closed-bins-DATE.PLATFORM.tar.bz2
example: SUNWonbld-b47.i386.tar.bz2
3. The Closed Binaries?OS/Networking (ON) Components, named:
on-closed-bins-DATE.PLATFORM.tar.bz2
Example: on-closed-bins-b47.i386.tar

Open -Solaris Source code(onsrc) :
* The Source. For build-synchronized deliveries, you can download a source tarball named:
on-src-DATE.tar.bz2
example:on-src-b47.tar.bz2

Download the above tar files from opensolaris.org in the /var/tmp area,this is used to avoid using space in the working directories.
Following are two link which directed from opensolaris.org to download the above tar files.
http://dlc.sun.com/osol/on/downloads/
This contains a list of archive date wise and b47,b60 etc
http://dlc.sun.com/osol/on/downloads/current/
This contains the latest (current date)source code for download.

Now install all the above one by one:

Untar and Install Sun Studio Compiler:
# cd /opt
# bzip2 -dc /var/tmp/sunstudio10-ii-20050912-sol-x86.tar.bz2(if you have cop)
# tar xvf /var/tmp/sunstudio10-ii-20050912-sol-x86.tar -C .
You will see two directories to be built in the /opt directory
1. netbeans
2. SUNWspro

Untar and Install SUNWonbld:
# bzip2 -d SUNWonbld-b47.i386.tar.bz2
(You will get SUNWonbld-b47.i386.tar file as the result of above)

# tar xvf SUNWonbld-b47.i386.tar -C .
# su (if you haven’t logged in as root)
Password:
# pkgadd -d onbld SUNWonbld
Note that if you have installed a previous version of the tools, you will need to use pkgrm(1m)
to remove them first.


Untar and Install The Closed Binaries?OS/Networking (ON) Components:
Make a work space for you named as : /export/home/open_solaris
$ mkdir /export/home/open_solaris
$cd /export/home/open_solaris
$ bzip2 -d on-closed-bins-b47.i386.tar.bz2
You will get the file on-closed-bins-b47.i386.tar
$ tar xvf on-closed-bins-b47.i386.tar -C .
This operation will create a directory closed inside /export/home/open_solaris/


Untar Open-Solaris Source code(onsrc):
$cd /export/home/open_solaris
$bzip2 -d on-src-b47.tar.bz2
$tar xvf on-src-b47.tar -C .
The sources will unpack into:
/export/home/open_solaris/usr/src



STEP 2: Setting your environment
------------------------------------------
1. cd /export/home/open_solaris
2. cp usr/src/tools/env/opensolaris.sh .
3. edit opensolaris.sh
4. set GATE to open_solaris
5. set CODEMGR_WS to /export/home/open_solaris
6. set STAFFER to your login
7. set VERSION to whatever you want to call it

Step 3 . Kernel Building
-----------------------------
There are two steps to build Open-Solaris:

1.The nightly script is used to perform the actual build (note that nightly builds everything, not just the kernel):
to build the entire ON tree run nightly:
$cd /export/home/open_solaris
$nightly ./opensolaris.sh &

This will take some time so take rest for some hour with a cup of tea or coffee .

The log file is also available (in a slightly different location) during the build; to monitor the progress of
your build in real time, you can do:

$ tail -f /export/home/open_solaris/log/nightly.log

The location of the log is controlled by the LOGFILE and ATLOG variables; see nightly(1) for more details.
If your build fails, you can correct the problem, then use the '-i' option to nightly to run an incremental build,
bypassing the initial clobber. See the nightly(1) manual and Building OpenSolaris for more information on opensolaris.org
http://www.opensolaris.org/os/community/on/devref_toc/devref_4/


2.OR make the kernel manually by dmake as following:
The first thing we need to do is make sure that all the required environment variables are set to the correct values,by running the bldenv script:
1. bldenv -d ./opensolaris.sh
2. cd /usr/src/uts
3. dmake all

Because we didn't do nightly ./opensolaris & before, /src/tools/proto isn't built.
So just go there and build it.
Building the tools
1. cd /usr/src/tools
2. dmake all
this makes proto dir in tools


Step 3: Booting new kernel
--------------------------------
1. cd usr/src/uts
2. Install -G myos.kernel -k i86pc
Example :
bash-3.00# Install -G myos.kernel -k i86pc
WARNING: kmdb isn't built, and won't be included
Creating tarfile /tmp/Install.root/Install.i86pc.tar

3. su (if not root login)
4. cd /
5. tar xf /tmp/Install.root/Install.i86pc.tar .
6. vi /boot/solaris/filelist.ramdisk
add platform/i86pc/myos.kernel to the end of file

7. vi /boot/grub/menu.lst
add an entry pointing kernel to myos.kernel
platform/i86pc/myos.kernel
Example:
#--------------------------------
title my_open_solaris
kernel /platform/i86pc/myos.kernel
module /platform/i86pc/boot_archive
#-----------------------------------
You can skip this step if you wants to reboot the kernel directly from command line(Please see following 8th step )

8. reboot using following commands if you have changed menu.list in the above 7th step
$reboot

if you have not changed menu.list in the above 7th step,fire following command for booting new x86 kernel:
$reboot -- 'myos.kernel/unix'

Note that you will need to use either this reboot syntax (reboot -- 'myos.kernel/unix' ) each time you wish to boot the test kernel, or use similar arguments to the bootloader(7 point) or OBP. Otherwise, the normal kernel installed by BFU or the regular installation will be booted.

First steps towards kernel development:
1. vi/usr/src/uts/common/main.c
2. add printf("Hello Kernel World!\n"); in main()[in the middle of the main() code]
3. recompile, install and reboot.

To build a specific component
------------------------------------
To build a specific component, first use bldenv(1) to set up various environment variables,
then cd to the subtree that you want to build. For example to build the sgs:
$ cd /export/home/open_solaris/
$ bldenv ./opensolaris.sh
[status information from bldenv]
$ cd /export/home/open_solaris/usr/src/cmd/sgs
$ dmake all




In short story we can say that following are the steps to recompile, build and intall new kernel
------------------------------------------------------------------------------------------------

1. Obtain the source code, closed binaries, compilers and build tools from www.opensolaris.org or one of its mirrors.
2. Install the ON build tools and Sun Studio compilers into /opt and add their directories to our PATH.
3. Unpack the source and closed binaries tar balls.
4. Copy and edit the opensolaris.sh script.
5. Build the source code using the nightly script or using dmake in usr/src/uts
6. Install the resulting new kernel using the Install script.
7. Reboot using the new kernel.

For more information please visit the following sites
http://www.opensolaris.org
http://www.opensolaris.org/os/community/on/devref_toc/devref_4/

That all from my side.Thanks for reading this article.
Happy Kernel Building and Have a nice Day.

Wednesday, February 20, 2008

TLS(Thread Local Storage)

Thread-local storage (TLS) as the name indicate is a method to make static or global memory local to a thread.
Separate copies of thread-local data that have been allocated at compile-time, must be associated with individual threads of execution.
This is sometimes needed because all threads in a process share the same address space. In other words,data in a static or global variable is normally always located at the same memory location, when referred to by threads from the same process.
Local Variables are already local to threads, because each thread has its own stack, residing in a different memory location.So TLS is not applicable to local variables.

Take an example how two threads worked and update a common global variable:
If thread A sets the thread local variable to 1, and thread B then sets it to 2, then code running in thread A will continue to see the value 1 for the variable while code running in thread B sees the value 2. In Posix threads this type of variable can be created via pthread_key_create() and accessed via pthread_getspecific() and pthread_setspecific().

These functions work well , but making a function call for each access is awkward and inconvenient. It would be more useful if you could just declare a regular global variable and mark it as thread local. That is the idea of Thread Local Storage (TLS).On a system which supports TLS, any global (or static) variable may be annotated with __thread. The variable is then thread local.

To create and use TLS requires following supports:
1. The compiler.
2. Program linker(Static linker)
3. dynamic linker(Run Time Linker) and some kernel support is also needed(thread library).

The design of TLS on ELF systems fully supports shared libraries, including having multiple shared libraries, and the executable itself, use the same name to refer to a single TLS variable. TLS variables can be initialized. Programs can take the address of a TLS variable, and pass the pointers between threads, so the address of a TLS variable is a dynamic value and must be globally unique.


Following are some Compilers list that are able to create TLS:
Sun Studio C/C++, IBM XL C/C++, GNU C & Intel C/C++
all the aboove compilers uses __thread keyword to create thread local storgae.
Variables are declared thread-local using the __thread keyword, as in the following examples:
__thread int i;
__thread static int j;
__thread char *ptr;




Thread-Local Storage Access Models
---------------------------------------------
Each TLS reference follows one of the following access models.
Defining different storage models for TLS variables.

* Local Executable(Staic TLS): Permits access to TLS variables defined in the executable itself.
This model can only reference TLS variables which are part of the TLS block of the dynamic
executable. The link-editor calculates the thread pointer-relative offsets statically, without the
need for dynamic relocations, or the extra reference to the GOT. This model can not be used to
reference variables outside of the dynamic executable.

* Initial Executable: Permits access to a variable which is known to be part of the TLS image of the executable.
This is true for all TLS variables defined in the executable itself, and for all TLS variables in shared libraries explicitly linked with the executable. This is not true for accesses from a shared library, nor for accesses to TLS variables defined in shared libraries opened by dlopen.

* General(Global) Dynamic: Fully general access to TLS variables from an executable or a shared object.

* Local Dynamic: Permits access to a variable which is bound locally within the executable or shared object from which it is referenced. This is true for all static TLS variables, for example. It is also true for protected symbols.

Following examples shows how to make executable and shared object using these models
1. Local Exec model

Example:
--------

//executable itself
__thread int i;

int
foo()
{
return(i);
}

int
main()
{
foo();
}

2.Initial Exec model

Example:can be in executable or in shared object
-------
extern __thread int i;

int
foo()
{
retun i;
}


3.General (Global)Dynamic

Example:
--------

__thread int i;

int
foo()
{
return(i);
}

4.Local Dynamic

Example:
--------

static __thread int i,j;

int
foo()
{
return (i + j);
}

-----------


For more information Please read:
http://docs.sun.com/app/docs/doc/817-1984/chapter8-1?a=view

Open-Solaris Vs Linux

Open- Solaris Vs Linux PART Ist
=========================

Configuring the dynamic linker search path
--------------------------------------------
File Name for editing paths:

Linux : /etc/ld.so.conf
Solaris: /var/ld/ld.config

If you have used Linux you might be used to add paths where librarys reside to /etc/ld.so.conf and run ldconfig afterwards.
Under Solaris there's a similar way to configure paths for the dynamic linker. Please note that it's only slightly better than setting LD_LIBRARY_PATH -- you can break things if you don't know exactly what you're doing.

Configuration files for the dynamic linker reside under /var/ld/ in solaris. Unlike under Linux you're not meant to edit those with your favourite editor(vi ,emacs etc). Simply running crle without arguments will give you something like this:

# crle

Default configuration file (/var/ld/ld.config) not found
Default Library Path (ELF): /lib:/usr/lib (system default)
Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default)

Now you can add a new path -- for example /usr/local/lib -- with crle -l 'path'. This might look like this:

# crle -l /lib:/usr/lib:/usr/local/lib
# crle

Configuration file [version 4]: /var/ld/ld.config
Default Library Path (ELF): /lib:/usr/lib:/usr/local/lib
Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default)

Command line:
crle -c /var/ld/ld.config -l /lib:/usr/lib:/usr/local/lib

Please note that you have to specify all directories, not just the one you'd like to add.otherwise system will not run since most system libraries (ie libc.so.1,libm.so.1 etc )resides /lib ,/usr/lib


OS x86 Solaris
===========
link-editor(Static Linker) : /usr/lib/
runtime linker/loader : /usr/lib/ld.so.1
configure : crle
config file: /var/ld/ld.config
cache file : /var/ld/ld.config

OS x86 Linux
===========
link-editor (Static Linker) : /usr/bin/ld
runtime linker/loader : /lib/ld-2.3.2.so (/lib/ld-linux.so.2)
configure : ldconfig
config file: /etc/ld.so.conf
cache file : /etc/ld.so.cache

----------------------------------Finish (Configuring ...)--------------------

Application Building on Linux and Solaris
============================
Using Make Files:

Both the Solaris OS and Linux provide the make utility, which can be used to build applications from its
source files. The make utility works recursively on a makefile that describes the relationship between
the target file and its dependencies.
On Linux, GNU make searches for the makefile in the following order:
1. ./GNUmakefile
2. ./makefile
3. ./Makefile
In addition, GNU make implicitly can extract a file from RCS/SCCS directories if necessary.

The Solaris make utility searches for the makefile in the following order:
1. Non-POSIX Mode
• ./makefile
• If ./SCCS/s.makefile is present, it tries to retrieve the most recent version of the makefile.
• ./Makefile
• If ./SCCS/s.Makefile is present, it tries to retrieve the most recent version of the makefile.
2. POSIX Mode
• ./makefile, ./Makefile
• s.makefile, SCCS/s.makefile
• s.Makefile, SCCS/s.Makefile
Both the versions of make have compatible command-line options.

Thursday, February 7, 2008

Building Executables on Solaris using Make


Here you can see how we can build any executable using make utility.Most people are trying to build any executable using following command:
cc -o test test.c
or
gcc -o test test.c
The above command can be simply replace using make command just fire follwing:
make test

Now see following examples :how to do the same
#cat test.c
int
main()
{
printf("inside main\n");
}


1.Using Sun's make using the defaults:

# make test
cc -o test test.c

2. Using GNU's version of make, gmake, using the defaults:

# gmake test
cc test.c -o test


Notice that in above two cases even though the arguments to cc are reversed, the end result is the same.

(Interested readers can referred to the respective manual pages for more details about make, gmake, and Makefiles.)

3. Sets the CC variable before calling make:

# CC=gcc make test
gcc -o test test.c

Notice that this time, gcc is used to compile test.c rather than cc (we can use a similar invocation with gmake if that is the build tool we want to use).

The above 3 points are also applicable to linux also.
Those who are working on Linux,can try the above make ,gmake commands.