Tuesday, 14 February 2012

How to write Make files for real time applications? What is Static Library and Dynamic(Shared) library?

Writing make files needs some understanding and practice. Once you understand how to write Makefiles, then it will be simple.

What is Makefile:
     When there are many source files and some source files has dependency on other files. Compilation of these source code files can be difficult. In order to build these files auto magically, makefiles came in to existence.

Makefiles are special format files that together with the make utility will help  to auto magically build and manage projects.

Build Process

  1. Compiler takes the source files and outputs object files

  2. Linker takes the object files and creates an executable 

How to use "make" utility?
run
 > make -f  myMakefile
 or
> make        < In turn it will run the Makefile present in the directory >


clean:
> make clean

How to write small makefile?


mainFile.c

#include<stdio.h>
#include "def.h"
int main()
{
   int result;
   result= function1(3) + FUNC_VALUE;

   printf(" The Result of the program is :%d\n", result);
   return 0;
}

def.h

#define FUNC_VALUE 8

int function1(int a);

fun.c

int function1(int a)
{
   /* Return Value of a */
   return (a);
}


How to compile files with out Makefile?

gcc mainFile.c fun.c -o test

How to compile files with Makefile ?

Makefile    (With Out Dependencies)

all:
        gcc mainFile.c fun.c -o test.exe
clean:
        rm -f *.o
        rm -f *.exe

This makefile generates only test.exe, there won't be mainFile.o, fun.o  files. This is compilation and as well as link these objects(.o objects) to generate .exe file.

all:
        gcc -c mainFile.c fun.c
clean:
        rm -f *.o
        rm -f *.exe

This makefile generates only .o files, there won't be .exe file. This is just compilation and generates .o files. 

On this first example we see that our target is called all. This is the default target for makefiles. The make utility will execute this target if no other one is specified.
We also see that there are no dependencies for target
all, so make safely executes the system commands specified.
Finally, make compiles the program according to the command line we gave it.

Makefile    (With  Dependencies)

all : test

test : mainFile.o fun.o
        gcc mainFile.o fun.o -o test.exe
#mainFile.o : (with out file name also work)

mainFile.o : mainFile.c 
        gcc -c mainFile.c

fun.o : fun.c
        gcc -c fun.c

clean:
        rm -f *.o
        rm -f *.exe

Explanation:
First Makefile will see "all". all is having dependency as test 
step1: all is having dependency as test 
step2: Go to test. "test" is having dependencies as mainFile.o fun.o 
step3: Go to first dependency mainFile.o. 
step4: Then we define a rule "mainFile.o : mainFile.c" that applies to mainFile ending in the .o    suffix.  The rule says that the .o file depends upon the .c version of the mainFile.c file. The rule then says that to generate the .o file, make needs to compile the .c file using the compiler(gcc). 
step5: Go to second dependency fun.o.The rule says generate the fun.o file using compiler. 
step6: Once it found the dependecies, then it will execute the command present in the "all".
 gcc mainFile.o fun.o -o test.exe.

 In other words,  the target all has only dependencies, but no system commands. In order for make to execute correctly, it has to meet all the dependencies of the called target (in this case all).
Each of the dependencies are searched through all the targets available and executed if found.



Makefile With Macros -> Procedure 1:

# step1: define the Compiler as gcc. $(CC) is the variable. $ represents variable.

CC = gcc

# step2: define compiler flags "CFLAGS"  if you mention -g option it is for GDB, -wall to display all
# warnings

CFLAGS = -g -Wall

# Whenever you give Make, it will come to all, then checks the label test
# step3:

all : test

# test is having dependencies as mainFile.o and fun.o
# step4:
# returns from step5 and step4

test : mainFile.o fun.o
        $(CC) $(CFLAGS) mainFile.o fun.o -o test.exe

#step5:
# mainFile.o will have dependency on "mainFile.c"

mainFile.o : mainFile.c
        $(CC) -c mainFile.c

#step6:
# fun.o will have dependency on "fun.c"

fun.o : fun.c
        $(CC) -c fun.c

clean:
        rm -f *.o
        rm -f *.exe


Makefile With Macros -> Procedure 2:


#  define the Compiler as gcc. $(CC) is the variable. $ represents variable.
CC = gcc

#  define compiler flags "CFLAGS"  if you -g option it is for GDB, -wall to display all
# warnings

CFLAGS = -g -Wall

#step3:
# Return to step2

OBJS =  $(PWD)/mainFile.o \
          $(PWD)/fun.o


#step1:

all : test

#step2:

test : $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) -o test.exe

#step4:
#Return to step3
# It will compile all the files and generate .o's.
# or  $(PWD)/*.o : *.c

$(PWD)/%.o : %.c
        $(CC) $(CFLAGS) -c $< -o $@


clean:
        rm -f *.o
        rm -f *.exe

How to Generate Static Library and Dynamic Library(Shared Libaries) Using Makefile:

First of all i would like give some introduction about static library and dynamic library.

What is Static Library?

Static libraries are simply a collection of ordinary object files; conventionally, static libraries end with the ``.a'' suffix. This collection is created using the ar (archiver) program.  

In static linking, the size of the executable becomes greater than in dynamic linking, as the library code is stored within the executable rather than in separate files

Static libraries permit users to link to programs without having to recompile its code, saving recompilation time. Note that recompilation time is less important given today's faster compilers, so this reason is not as strong as it once was. Static libraries are often useful for developers if they wish to permit programmers to link to their library, but don't want to give the library source code.

To create a static library, or to add additional object files to an existing static library, use a command like this:

                   ar rcs library.a File1.o File2.o
or 
                   ar -qcs library.a File1.o File2.o 



Makefile to Generate Static Library.

Let's take small example, suppose there are two files and generate the static library and link it to main file.

file1.c

int fun1(int a, int b)
{
  int c;

  /* add the Two Variables */
  c= a+b;
  return(c);
}

file2.c

int fun2(int a, int b)
{
  int c;

  /* add the Two Variables */
  c= a+b;
  return(c);
}
 Above there are two files, here you can find the Makefile to generate the library using file1.o and file2.o

Makefile to generate MyLibrary.a using file1.o and file2.o

CC = gcc

CFLAGS = -g -Wall

# .a extension for static library
# .so extension for dynamic library
# step 1:
# it goes to step2:

all: libMylibrary.a


#step 3:
# Return to step 2
# Declare this OBJS before it is used, Here OBJS is a variable.

OBJS = $(PWD)/file1.o \
       $(PWD)/file2.o

#step 2:

libMylibrary.a : $(OBJS)
        ar -qcs libMylibrary.a $(OBJS)


# step 4:
# Return to step 3

$(PWD)/%.o : %.c
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        rm -f *.o
        rm -f *.a


How to Link this library to the Main function file to get .exe

mainFile.c

#include<stdio.h>
#include<stdlib.h>

extern int fun1(int a, int b);
extern int fun2(int a, int b);

int main()
{

  printf("The value of Function1: %d", fun1(4,5));
  printf("The value of Function2: %d", fun2(6,7));

  return 0;
}

Makefile links library and generate the test.exe

CC = gcc

CFLAGS = -g -Wall

# .a extension for static library
# .so extension for dynamic library
# step 1:
# it goes to step2:

all: test


#step 3:
# Return to step 2

OBJS = $(PWD)/mainFile.o \

#step 2:

test : $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) $(LIBDIR) $(LIBLOG) -o test.exe


#step 4:
# Return to Step 3

$(PWD)/mainFile.o : mainFile.c
        $(CC) $(CFLAGS) -c mainFile.c

# Step 5:
# For static library, always include LIB DIR
# This is Mandatory
LIBDIR =  -L./
LIBLOG = -lMylibrary

clean:
        rm -f *.o
        rm -f *.a

 Important Point:
When ever you are linking static library to mainFile,  it is mandatory to mention the LIBDIR( where the library is present) using -L option. This $(LIBDIR) should be included when generating .exe file. 

Note: How to run your own makefile, suppose i have makefile as Makefile_org, then run using the below command.
make -f Makefile_org
clean :
 make -f Makefile_org clean

Real Time Example.
Suppose there are three modules BMODULE, CMODULE , DMODULE. BMODULE  is having dependency upon other two modules i.e. CMODULE , DMODULE
Hence, first compile CMODULE  and DMODULE and link their objects to BMODULE to generate the .exe.
Here  DMODULE generates the static library and CMODULE generates the object files(o's)

Step1:  Create Directories of BModule, DModule, CModule

-bash-3.2#  mkdir mreddya
-bash-3.2#  mkdir MAKEFILE_EXERCISE  

create directories under /root/mreddya/MAKEFILE_EXERCISE/as shown below.
-bash-3.2#  mkdir BMODULE
-bash-3.2#  mkdir CMODULE 
-bash-3.2#  mkdir DMODULE
 
Step2:  Create sub-directories of BModule, DModule, CModule
create sub directories under each module as shown below.
-bash-3.2# cd DMODULE/
-bash-3.2#  mkdir src
-bash-3.2#  mkdir inc
-bash-3.2#  mkdir obj 

-bash-3.2# cd CMODULE/
-bash-3.2#  mkdir src
-bash-3.2#  mkdir inc
-bash-3.2#  mkdir obj 

-bash-3.2# cd BMODULE/
-bash-3.2#  mkdir src
-bash-3.2#  mkdir inc
-bash-3.2#  mkdir obj 

Step 3:  Generate Library for DModule for the below files

-bash-3.2# cd DMODULE/
-bash-3.2# cd
Create four files under source directory, dModulefile1.c  dModulefile2.c  dModulefile3.c, Makefile
-bash-3.2# cd DMODULE/
-bash-3.2# cd inc
Create three files under inc,dModulefile1.h  dModulefile2.h  dModulefile3.h


dModulefile1.c

#include "dModulefile1.h"

int DModuleFunction1(int a)
{
   printf("I am in DModuleFunction1 and its Value:%d", a);
   a = a + FUNC_VALUE4;
   return(a);
}

dModulefile2.c

#include "dModulefile2.h"

int DModuleFunction2(int b)
{
   printf("I am in DModuleFunction2 and its Value:%d", b);
   b = b + FUNC_VALUE5;
   return(b);
}

dModulefile3.c

#include "dModulefile3.h"

int DModuleFunction3(int c)
{
   printf("I am in DModuleFunction3 and its Value:%d", c);
   c = c + FUNC_VALUE6;
   return(c);
}

dModulefile1.h
#include<stdio.h>
#define FUNC_VALUE4 14

dModulefile2.h
#include<stdio.h>
#define FUNC_VALUE5 11

dModulefile3.h
#include<stdio.h>
#define FUNC_VALUE6 13

Step 4:  Makefile for DMODULE (Makefile place in src directory)

# define the Compiler as gcc
CC = gcc

# define compiler flags "CFLAGS"  if you -g option it is for GDB, -wall to display all
# warnings

CFLAGS= -g -Wall

# TO include Directories, To include any directories give -I/Path Directory
# e.g: INCLUDEDIR = -I/VOBS/CMODULE/INC/, to include one more directory
# then Syntax will be INCLUDEDIR += -I/VOBS/CMODULE/INC/
#                     INCLUDEDIR  = -I/VOBS/BMODULE/INC/

INCLUDEDIR = -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc

# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj

# copy all .o( Objects) in to object directory
# All Objects are stored in OBJ-DIR
#
OBJS = $(OBJ-DIR)/dModulefile1.o \
        $(OBJ-DIR)/dModulefile2.o \
        $(OBJ-DIR)/dModulefile3.o \


# First whenever we give Make, it comes here, and Check OBJS
# Then It will check what and all .o are required from 
# OBJS directory
# then it will go Command to generate the .o's.

all:    libDmodule.a

# Generate the Library

libDmodule.a: $(OBJS)
        ar -qcs libDmodule.a $(OBJS)

#To Generate %.o means same directory.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files # to .o files using command.)
# To get the Target the below command should be executed, 
# otherwise Linker error will be there.

$(OBJ-DIR)/%.o : %.c
        $(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@


clean:
        rm -f $(OBJ-DIR)/*.o
        rm -f *.a

Step 5:  Run the Makefile and check the results

-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
-bash-3.2# make
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile1.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile1.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile2.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile2.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile3.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile3.o
ar -qcs libDmodule.a /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile1.o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile2.o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile3.o

-bash-3.2# ls
dModulefile1.c  dModulefile2.c  dModulefile3.c  libDmodule.a  Makefile

-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj
-bash-3.2# ls
dModulefile1.o  dModulefile2.o  dModulefile3.o
Step 6:  Generate objects for CMODULE

-bash-3.2# cd CMODULE/
-bash-3.2# cd
Create four files under source directory, cModulefile1.c  cModulefile2.c  cModulefile3.c, Makefile
-bash-3.2# cd CMODULE/
-bash-3.2# cd inc
Create three files under inc,cModulefile1.h  cModulefile2.h  cModulefile3.h

cModulefile1.c

#include "cModulefile1.h"

int CModuleFunction1(int a)
{
   printf("I am in CModuleFunction1 and its Value:%d", a);
   a = a + FUNC_VALUE1;
   return(a);
}
cModulefile2.c

#include "cModulefile2.h"

int CModuleFunction2(int b)
{
   printf("I am in CModuleFunction2 and its Value:%d", b);
   b = b + FUNC_VALUE2;
   return(b);
}

dModulefile3.c

#include "cModulefile3.h"

int CModuleFunction3(int c)
{
   printf("I am in CModuleFunction3 and its Value:%d", c);
   c = c + FUNC_VALUE3;
   return(c);
}

cModulefile1.h
#include<stdio.h>
#define FUNC_VALUE1 10

cModulefile2.h
#include<stdio.h>
#define FUNC_VALUE2 11

cModulefile2.h
#include<stdio.h>
#define FUNC_VALUE3 11


Step 7:  Makefile for CMODULE (Makefile place in src directory)

# define the Compiler as gcc
CC = gcc

# define compiler flags "CFLAGS"  if you -g option it is for GDB, -wall to display all
# warnings

CFLAGS= -g -Wall

# TO include Directories, To include any directories give -I/Path Directory
# e.g: INCLUDEDIR = -I/VOBS/CMODULE/INC/, to include one more directory
# then Syntax will be INCLUDEDIR += -I/VOBS/CMODULE/INC/
#                     INCLUDEDIR  = -I/VOBS/BMODULE/INC/

INCLUDEDIR = -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc

# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj

# copy all .o( Objects) in to object directory
# All Objects are stored in OBJ-DIR
#
OBJS = $(OBJ-DIR)/cModulefile1.o \
        $(OBJ-DIR)/cModulefile2.o \
        $(OBJ-DIR)/cModulefile3.o \


# First whenever we give Make, it comes here, and Check OBJS
# Then It will check what and all .o are required from 
# OBJS directory
# then it will go Command to generate the .o's.

all: $(OBJS)

#To Generate %.o means same directory.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files to .o files using command.)
#    command.
#To Generate %.o means same directory.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files to .o files using command.)
#    command.
# To get the Target the below command should be executed, otherwise
# Linker error will be there.

$(OBJ-DIR)/%.o : %.c
        $(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@


clean:
        rm -f $(OBJ-DIR)/*.o


Step 8:  Run the Makefile and check the results

-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/CMODULE/src

-bash-3.2# make clean
rm -f /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/*.o

-bash-3.2# make
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc -c cModulefile1.c -o /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/cModulefile1.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc -c cModulefile2.c -o /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/cModulefile2.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc -c cModulefile3.c -o /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/cModulefile3.o
-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj

-bash-3.2# ls
cModulefile1.o  cModulefile2.o  cModulefile3.o

Step 9: Get .exe by Linking the CMODULE and DMODULE to BMODULE 

-bash-3.2# cd BMODULE/
-bash-3.2# cd
Create two files under source directory, bModulefile.c,  Makefile
-bash-3.2# cd BMODULE/
-bash-3.2# cd inc
Create one file under inc,bModulefile.h

bModulefile.c

#include<stdio.h>

#include "bModulefile.h"

/* extern the Functions */
extern int CModuleFunction1(int );
extern int CModuleFunction2(int );
extern int CModuleFunction3(int );
extern int DModuleFunction1(int );
extern int DModuleFunction2(int );
extern int DModuleFunction3(int );


void getFunValue(void)
{
  int result = 0;

  result = CModuleFunction1(3)* FUNC_VALUE8;
  printf("The Result value with CModuleFunction1:%d\n", result);
  result = CModuleFunction2(4)* FUNC_VALUE8;
  printf("The Result value with CModuleFunction2:%d\n", result);
  result = CModuleFunction3(5)* FUNC_VALUE8;
  printf("The Result value with CModuleFunction3:%d\n", result);
  result = DModuleFunction1(3)* FUNC_VALUE8;
  printf("The Result value with DModuleFunction1:%d\n", result);
  result = DModuleFunction2(4)* FUNC_VALUE8;
  printf("The Result value with DModuleFunction2:%d\n", result);
  result = DModuleFunction3(5)* FUNC_VALUE8;
  printf("The Result value with DModuleFunction3:%d\n", result);
}
int main()
{
   /* call the getFunValue Function */
   getFunValue();
   return 0;
}

bModulefile.h


#define FUNC_VALUE8 1

Step 10:  Makefile for BMODULE (Makefile place in src directory)
This Makefile links both CMODULE and DMODULE and generates the test.exe


Some points to be Noted here:
Before compiling BMODULE, first it is mandate to compile CMODULE and DMODULE.
Once CMODULE and DMODULE compiled and run the Makefile of BMODULE.

Step 11:  Makefile compiles first CMODULE and DMODULE then BMODULE
Run this Makefile using make all command


# This is the Main Make file which incorporates all the files and
# generates the .exe file.

# define the Compiler Macro as gcc
CC = gcc

# define any Flags whether to compile as 64 bit(-m64) or with -g option
# to debug in gdb and also to show file name with warnings.
CFLAGS = -g -Wall

# Include the Directories which you want to link here.
# Include the .h directories.
# Whenever multiple directories are included then use +=  with -I option
INCL_DIR += -I/root/mreddya/MAKEFILE_EXERCISE/BMODULE/inc

# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/BMODULE/obj

EXE-DIR = /root/mreddya/MAKEFILE_EXERCISE/BMODULE/src

COBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj

DLIB_DIR = /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src


OBJS = $(OBJ-DIR)/bModulefile.o

COBJS = $(COBJ-DIR)/cModulefile1.o \
        $(COBJ-DIR)/cModulefile2.o \
       $(COBJ-DIR)/cModulefile3.o \


EXTERNALLIBS = -L$(DLIB_DIR)
LIBLOG       = -lDmodule



CMODULE_COMPILE:
        cd /root/mreddya/MAKEFILE_EXERCISE/CMODULE/src && make
DMODULE_COMPILE:
        cd /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src && make
BMODULE_COMPILE:
        $(CC) $(CFLAGS) $(INCL_DIR) -c *.c -o $(OBJS)

all:
        make all_modules

all_modules:
        make CMODULE_COMPILE
        make DMODULE_COMPILE
        make BMODULE_COMPILE
        $(CC) -o test.exe $(OBJS) $(EXTERNALLIBS) $(LIBLOG) $(COBJS)


clean:
        rm -f $(OBJ-DIR)/*.o
        rm -f $(EXE-DIR)/*.exe
        rm -f $(COBJ-DIR)/*.o
        rm -f $(DOBJ-DIR)/*.o

There are several ways to write make files, this is one way.
write small script and compile the Makefiles like show below.

build.sh script

cd /root/mreddya/MAKEFILE_EXERCISE/CMODULE/src
make
cd /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
make

cd /root/mreddya/MAKEFILE_EXERCISE/BMODULE/src
make

What is Dynamic Library or Shared Library (.so)?

Dynamic library is also called as Shared Library. 
Shared Library is a binary file(.so file) contains object (.o) files. All object files form as shared library  and this library can be loaded or unloaded dynamically.

By using shared library concept, one can make the code is position-independent, meaning that the code may be loaded anywhere in memory. Applications linked to shared objects at run time.
 
How to generate a shared library:

Step 1: Create object code, it means generate object files (.o files) 

 gcc -fPIC -c <filename.c>

The -fPIC option tells gcc to create position independent code which is necessary for shared libraries.
  e.g: gcc -fPIC -c myfilename.c

Step 2: Create shared library 

 gcc -g -Wall -shared -o  <library Name>  <objectfile1.o,  objectfile2.o>

 It will create the library with .so extension.
e.g: gcc -g -Wall -shared -o  libMyfuncs.so file1.o  file2.o


How to use the shared library to your application

Step 1:
Set the environment for Library using 
 export LD_LIBRARY_PATH=.

The above indicates the path directory where the library is present. ./ or  .  indicates the present directory

Step 3:
Compile your Main file and generate the object code.
e.g: gcc -c mainFile

And then Link the shared library  to the main file as mentioned below.


 e.g: gcc  -L./ -lMyfuncs mainFile.o -o test.exe

 Notes:
suppose if  "-L/opt/exp", means library is present in this directory and link the library using -llibName. The name of the library is Myfuncs.so.
The libraries will NOT be included in the executable but will be dynamically linked during run time execution.
That's reason size of .exe is small when we compare with static library.

How to check the list of shared libraries using by the application.

Use simple command.
ldd <.exe>

 -bash-3.2# ldd test.exe
        libMyFun.so => ./libMyFun.so (0x00002ab25d70f000)
        libc.so.6 => /lib64/libc.so.6 (0x0000003ef7c00000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003ef6c00000)



Simple Makefile to generate shared library

file1.c

int func1(int a, int b)
{
    int c;
    /* Add */
    c= a+b;
    return(c);
}

file2.c

 int func1(int a, int b)
{
    int c;
    /* Add */
    c= a+b;
    return(c);
}

Makefile to generate shared library as lib

CC = gcc

CFLAGS = -g -Wall

OBJS = $(PWD)/file1.o \
        $(PWD)/file2.o

all: libMyFun.so

libMyFun.so : $(OBJS)
        $(CC) $(CFLAGS) -shared -o libMyFun.so $(OBJS)

$(PWD)/%.o : %.c
        $(CC) $(CFLAGS) -fPIC -c *.c
clean:
        rm -f *.o
        rm -f *.so


 How to Link this shared library to the mainFile.c

mainFile.c


#include<stdio.h>

extern int func1(int, int);
extern int func2(int, int);

int main()
{

  printf("The result of Function 1 is: %d\n", func1(4,5));
  printf("The result of Function 1 is: %d\n", func2(10,20));
  return 0;
}


Build.sh  <Generate the test.exe using small script>

#step 1: clean the Library
make clean

#step 2: Generated the Library
make

#step 3: Generates the mainFile.o

gcc -c mainFile.c

#step 4: clean the .exe
rm -f *.exe

#step 5: Link the Shared library to mainFile.o and
#generates the test.exe file.

gcc -L./ -lMyFun mainFile.o -o test.exe


Run the Build.sh

chmod +x Build.sh
./Build.sh










Tuesday, 7 February 2012

How the Function Pointers are used in real time applications?

What is Function Pointer?
         Function Pointer are pointers i.e. variable, which point to the address of a function. 
One can use them to replace switch/if-statements, to realize your own late-binding or to implement callbacks. 
Function pointers will call  functions during run time. This means the functions are determined during run time, this is called Late Binding or Run time polymorphism (as Virtual Functions).

Virtual functions also use Late binding. In the case of Virtual function, the base class member function should be overridden by derived class member function.This is also called function over riding.

What is the syntax for function Pointer?

returnType  (*function Pointer ) (parameter1, parameter2);

Important point to remember (when you are using function pointer): 

Function pointers always point to a function having a specific signature. Thus, all functions used with the same function pointer must have the same parameters and return type

The function Pointer and function whose address is pointed should have same signature.
Signature means Return Type, Number of parameters and parameters data type of function should be same.

For example:
 // Function pointer "ptr_func" takes two integers as parameters and return integer value.
1. int ( *ptr_func)(int a, int b);

// Function whose address is pointed by the function pointer
2. int plus(int a, int b);


If you observe, the both functions 1 and 2 has same signature. It means both functions has same return type and parameters (data type , No.of Parameters) .


How to Declare function Pointer in C and C++? 
C
int (*ptr_func)(int a, int b);
C++ 
int (BaseClass:: *ptr_func)(int a, int b); 

How to initialize or define the function pointer to NULL?
C
int (*ptr_func)(int a, int b) = NULL;
C++
int (BaseClass:: *ptr_func)(int a, int b) = NULL


How to Assign an Address to a Function Pointer?
C
int add(int a , int b );
int (*ptr_func)(int , int ) = NULL; 

There are two ways of assign an address to a function pointer. 

First way :   
ptr_func = add;  // short Form 
Second way : 
/* correct Assignment using address of the function */
ptr_func = &add;
C++ 
int (BaseClass:: *ptr_func)(int a, int b) = NULL;
class Baseclass
{
public:
   int add(int a, int b)

    { cout << "Baseclass::add"<< endl; return(a+b);
    };
 
};
// correct assignment using address operator
ptr_func = &Baseclass::add;


How to Compare Function Pointers (== or =!)?
C  

You can use either == or =! to compare the function pointers.
 if(ptr_func == &add)
{

   printf("Pointer points to add\n"); }
else
   printf("Pointer not initialized!!\n");

}
C++
if(ptr_func == &Baseclass::add)
   cout << "Pointer points to Baseclass::add" << endl; 

How to call Function using Function Pointer?

C
There are two ways of calling function Pointer in C
int result1 = ptr_func(2,3); 
int result2 = (*ptr_func)(2,3);

C++ 
// Declare the Object for the BaseClass
BaseClass instance1;
// Call the function pointer with Instance1(object)
int result3 = (instance1.*ptr_func)(2,3);

// Call the function pointer with *this (address of object)
int result4 = (*this.*ptr_func)(2,3)
 
// create new object Instance2
BaseClass* instance2 = new BaseClass;
int result4 = (instance2->*ptr_func)(2,3); 
delete instance2;


How to Pass Function pointer as argument? 
The function pointer should be declared as a parameter in  any function, then the address of normal function is passed .
Please refer the below code for better understanding.
Code snippet:
int (*ptr_func)(int, int);

int add(int a, int b)
{
   return (a+b);
}
void operation(int (*ptr_func)(int, int))
{
   result = (*ptr_func)(3,4);
   cout<<"The result is\n"<<result;
}
int main()
{
    Operation(&add);
}



How to return Function Pointer?

There are two ways to Return function pointer.

First way of declaration
========================
int add(int a, int b)
{
   return (a+b);
}
/* function Pointer */
int (*ptr_func)(int a, int b);

/*  Return the address of function based on Operation */
int (*Getfunction(char operation))(int, int);

// solution: Function takes a char and returns a pointer to a
// function which is taking two int and returns a int. 

// <operation> specifies which function to return
int (*Getfunction(char operation)(int, int)
{
   if(operation == '+')
   {
      return &add;
   }
   else
   {
      return &sub;
   }
}
int main()
{
  int result;

  /* This function returns the Function address *

  ptr_func = (*Getfunction)('+'); or // Getfunction)('+');

  result  =  (*ptr_func)(2,3);

  cout<<"The result"<<result;
}
Second way:
=============
// Solution using a typedef: Define a pointer to a function which is taking  two int and returns a int
typedef int(*pt2Func)(int, int);

// Function takes a char and returns a function pointer which is defined with the typedef above. Operation specifies which function to return
pt2Func Getfunction(char operation)
{
   if(operation == '+')
      return &Plus;
   else
      return &Minus; // default if invalid operator was passed
}
int main()
{
  int result;

  /* This function returns the Function address */
  ptr_func = (*Getfunction)('+'); or // Getfunction)('+');

  result  =  (*ptr_func)(2,3);
}

How to Declare and Use array of Function Pointers?

In Real time applications, array of function pointers have been used extensively.

e.g: 
1. Let's take a example, There is a process called xyzProcess in which there are three modules Xmodule, Ymodule and Zmodule. ZModule receives the messages from other process or system via sockets.
2.After decoding these message in Zmodule and take a decision to send these messages to either Xmodule or Ymodule.
3.These Module functions are called dynamically using a call back functions(function Pointers).

Simple way to declare a array of function pointers:
C
It uses a typedef  -> typedef  int (*ptrfunc)(int, int);

First way using the typedef:
// This is array with 10 pointers to functions which takes two integers and returns int.  
ptrFunc funcArray1[10] = {NULL};
//The second way directly defines the array. 
// 2nd way directly defining the array
int (*funcArray2[10])(int,int) = {NULL};
C++
// type-definition: 'ptrfunc' now can be used as type
typedef int (Baseclass::*ptrfunc)(int, int);// first way using the typedef
ptrfunc functionArray1[10] = {NULL};
Second way: 

// 2nd way of directly defining the array
 int (BaseClass::*functionArray2[10])(int, int) = {NULL};

How to assign address of functions to array of function pointers?

// assign the function's address
// assign the address of add and sub functions.
funcArray1[0] = funcArray1[1] = &add;
funcArray1[1] = funcArray2[0] = &sub;

How to call the array of function pointers?
C
// short form
 funcArray1[0](2,3) 
 // Correct way of calling
  (*funcArray1[0])(2,3) 
C++
funcionArray1[1] = functionArray2[0] = &BaseClass::add;
BaseClass instance;
cout << (instance.*funcionArray1[1])(2,3) << endl;


Example Code of simple Function Pointer:

#include<stdio.h>

/*Function Pointer */
int (*ptr_func)(int,int);

/* General Function */
/* Addition */
int add(int, int);

/* Subtraction */
int sub(int, int);

/* multiplication */
int mul(int, int);

int add(int a, int b)
{
   return (a+b);
}

int sub(int a, int b)
{
   if(a>b)
     return (a-b);
   else
     return (b-a);  
}
int mul(int a, int b)
{
   return (a*b);  
}

int main()
{
   int result1;

   /* Store the Address of add function in to Function Pointer */
   ptr_func = &add;  /* or ptr_func = add */
     
   /* call add  function */ 
   result1= (*ptr_func)(2,3);   /* or ptr_func(2,3); */

   printf("The Addition Result is : %d\n", result1);

   /* Store the address of sub function in to Function Pointer */
   ptr_func = &sub;  /* or ptr_func = sub */
    
   /* call sub  function */
   result1= (*ptr_func)(5,3);   /* or ptr_func(5,3); */

   printf("The subtraction Result is : %d\n", result1);

   /* Store the address of Mul function in to Function Pointer */
   ptr_func = &mul;  /* or ptr_func = mul */
     
   /* call Mul  function */
   result1= (*ptr_func)(2,1);   /* or ptr_func(2,1); */

   printf("The Multiplication Result is : %d\n", result1);

   return 0;
}

Note: In the above code example, the general functions and function pointer signature is same.

Example Code of Array of Function Pointers:

#include<stdio.h>
#define MAX_MODULES 2

/* Step 1 and 2 defines the array of function Pointers */

/* step 1: */
/* Typedef Function Pointer */
typedef int (*ptr_func)(int,int);

/* step 2: */
/* Define the array of Function pointers (MAX array will be 2) */
ptr_func funcArray[MAX_MODULES];
/* Define a Enum */
typedef enum
{
  XProcessModule=0,
  YProcessModule=1 
}Module;


/* Register the function in to ARRAY of Pointers using Module ID */
void registerWithZprocess(Module moduleId, int (*func_ptr)(int,int))
{
    if(!funcArray[moduleId])
    {
        funcArray[moduleId] = func_ptr;
    }
    else
    {
        printf("Module is already resigtered with Z Process:%d", moduleId);
    }       
}

/* General Function */
/* Addition */
int add(int, int);

/* Subtraction */
int sub(int, int);

int add(int a, int b)
{
   return (a+b);
}

int sub(int a, int b)
{
   if(a>b)
     return (a-b);
   else
     return (b-a);  
}

int main()
{
    int operation, result1;

    /* Registers Xprocess */
    registerWithZprocess(XProcessModule, &add);

    /* Registers Yprocess */
    registerWithZprocess(YProcessModule, &sub);

    printf("Enter the what operation to be performed\n");
    scanf("%d", &operation);

    if(operation == 0)
    {
         /* call the Add functionality */
         result1 = funcArray[XProcessModule](2,3);
    }
    else
    {
       /* call the Sub functionality */
         result1 = funcArray[YProcessModule](2,3);
    }    
   printf(" The Result of the Operation[%d] is: %d", operation, result1 );
   return 0;
}

Wednesday, 1 February 2012

How to send and recieve data via UDP sockets?

What is UDP?
UDP is Layer 4 (Transport Layer ) protocol which is used for carrying the data from one peer to another peer.

UDP is Connection Oriented or Connection less Protocol?
UDP is connection less protocol, means there is no guarantee that packet is delivered or not.
This UDP sockets also called as Datagram sockets.

Connection Oriented Vs Connection Less

A packet transmitted in a connectionless mode is frequently called a datagram.

In connection-oriented communication the communicating peers must first establish a logical or physical data channel or connection in a dialog preceding the exchange of user data.

The connectionless communication mode has the advantage over a connection-oriented mode in that it has low overhead. It also allows for multicast and broadcast operations, which may save even more network resources when the same data needs to be transmitted to several recipients. In contrast, a connection is always unicast (point-to-point).


Unfortunately, in connectionless mode transmission of a packet, the service provider usually cannot guarantee that there will be no loss, error insertion, misdelivery, duplication, or out-of-sequence delivery of the packet. (However, the risk of these hazards may be reduced by providing a reliable transmission service at a higher protocol layer of the OSI Reference Model.)
Another drawback of the connectionless mode is that no optimizations are possible when sending several frames between the same two peers.

What is socket:
Socket is an endpoint of an inter process communication flow across a computer network.
Socket is useful to communicate between two different process.(e.g  client.exe  <-> server.exe ).

Types of Sockets:
  • Datagram Sockets
  • Stream Sockets
  • Raw Sockets

What is Socket Address:
A socket address is the combination of an IP address and a port number, much like one end of a telephone connection is the combination of a phone number and a particular extension. Based on this address, internet sockets deliver incoming data packets to the appropriate application process or thread.


UDP Client and Server Communication:  

When UDP client wants to send any data to server, then UDP client should fill the server socket address parameters appropriately and call send function.  
Server socket address means server IP address and server Port number.

At server side, server socket should bind to a specific port number. The server just waits, listening on the specific port in which client is sending data.


Note:  client side server port and server side listening port should be same, Then only packets will reach.

How to create socket?

#include <sys/socket.h>

int socket(int domain, int type, int protocol);


e.g: sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
Returns sock file descriptor (sockfd) which can be used for sending and recieving data  

domain
Specifies the communications domain in which a socket is to be created.
type
Specifies the type of socket to be created.
protocol
Specifies a particular protocol to be used with the socket. Specifying a protocol of 0 causes socket() to use an unspecified default protocol appropriate for the requested socket type.
How to send Message on socket?

#include <sys/socket.h>

ssize_t sendto(int
socket, const void *message, size_t length,
       int
flags, const struct sockaddr *dest_addr,
       socklen_t
dest_len);


e.g:  
   /* Server Socket */
   struct sockaddr_in sendsocket;



  /* Server address or Parameters , Sending System Address and Port Num */
   memset(&sendsocket, 0, sizeof(sendsocket));
   sendsocket.sin_family = AF_INET;
   sendsocket.sin_addr.s_addr = inet_addr("10.0.0.1");
   sendsocket.sin_port = htons(2905);//same port Num should mention at server side

if (sendto(sockfd, buffer, sendlen, 0,
           (struct sockaddr *) &sendsocket, sizeof(sendsocket)) != sendlen)

{
      perror("sendto");
      return -1;
}

socket
Specifies the socket file descriptor.
message
Points to a buffer containing the message to be sent.
length
Specifies the size of the message in bytes.
flags
It can be Zero
dest_addr
Points to a sockaddr structure containing the destination address. The length and format of the address depend on the address family of the socket.
dest_len
Specifies the length of the sockaddr structure pointed to by the dest_addr argument.

How to bind  to the socket?
Generally in UDP sockets binding should be done on the server sockets.
If there is a requirement  to send and receive the data in both client and server side , then binding is required in client side as well as server side.

In other words, where ever you have recvfrom() function, then should bind to that socket()

#include <sys/socket.h>


int bind(int
socket, const struct sockaddr *address,
       socklen_t
address_len);


e.g: bind to local address of the system, IP address and Port Num.


/* client Socket */
struct sockaddr_in receivesocket;

memset(&receivesocket, 0, sizeof(receivesocket));
receivesocket.sin_family = AF_INET;
receivesocket.sin_addr.s_addr = htonl(INADDR_ANY);
receivesocket.sin_port = htons(2905);
 

receivelen = sizeof(receivesocket);
 

/* Bind the my Socket */
if (bind(sock, (struct sockaddr *) &receivesocket, receivelen) < 0) 

{
     perror("bind");
     return -1;
}
 

 How to receive Message from socket?

#include <sys/socket.h>

ssize_t recvfrom(int
socket, void *restrict buffer, size_t length,
       int
flags, struct sockaddr *restrict address,
       socklen_t *restrict
address_len);



e.g:

unsigned char buf[5096];
    while(true)
    {
        memset(buf, 0, BUFFSIZE);


        /* Recieve the Data from Other system */
        if ((receivedLen = recvfrom(sockfd, buf, BUFFSIZE, 0, NULL, NULL)) < 0)
        {
                perror("recvfrom");
                return 0;
        }

        else
        {
            printf("Data");
        }
}



How to check in Linux machine on which port Server is listening?

> netstat -nlp | grep -i <PortNum>

UDP Client Code:


#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <arpa/inet.h>
#include<sys/socket.h>

#define BUFFSIZE 5096

int sendlen, sentCnt;

unsigned char buffer[BUFFSIZE];

/* Server Socket */
struct sockaddr_in sendsocket;

/* Sock FD */
int sockFd;

/* Number of Times you need */
unsigned int ch;
unsigned int noOfTimes;

/* Send UDP Data */
int sendUDPData();

int main(int argc, char *argv[])
{

   /* Create the UDP socket */
   if ((sockFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
   {
        perror("socket");
        return -1;
   }

   /* Server address or Parameters , Sending System Address and Port Num */
   memset(&sendsocket, 0, sizeof(sendsocket));
   sendsocket.sin_family = AF_INET;


   /* server Machine IP address as 10.1.1.1 and Having Port Num 2905 */
   sendsocket.sin_addr.s_addr = inet_addr("135.254.253.241");
   sendsocket.sin_port = htons(2905);

   /* Do Loop -> Send UDP Data */
   do
    {
       cout<<endl;
       cout<<" Enter your choice:\t"<<endl;
       cout<<" 1. Send UDP Data" <<endl;
       cout<<" 2. exit" <<endl;
       cin>>ch;
       cout<<endl;

       switch(ch)
       {
           case 1:
                   cout<<"Enter the Length of the Payload "<<endl;
                   cin>>sendlen;
                   cout<<"Enter How many times you want to send data "<<endl;
                   cin>>noOfTimes;
                   /* Send UDP Data */
                   sendUDPData();
                   break;

           default:
                  cout<<"Invalid Choice\n";
                  break;
       }
   }while(ch!=2);
   return 0;

}

int sendUDPData()
{
    int count=0;

    /* Memset the Buffer */
    memset(buffer, 0x2, sendlen);

    /* Number of Times we need to send the packet */
    for(count=0; count< noOfTimes;  count++)
    {
         /* Send the UDP Data */
         if (sendto(sockFd, buffer, sendlen, 0,
            (struct sockaddr *) &sendsocket, sizeof(sendsocket)) != sendlen)    

         {
                perror("sendto");
                return -1;
         }
         else
         {
                sentCnt++;
         }
   }
   return 0;
}

Server Code.

#include <stdio.h>
#include <iostream.h>
#include <arpa/inet.h>
#include <string.h>

#define BUFFSIZE 5096

unsigned char buf[BUFFSIZE];

/* client Socket */
struct sockaddr_in receivesocket;

/* Sock FD */
int sockFd;

void dumpData(unsigned char *data,  unsigned int len);

int main(int argc, char *argv[])
{
   int receivelen= 0, length;

   /* Create the UDP socket */
   if ((sockFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
           perror("socket");
           return -1;
   }

   /* my address or Parameters 
    ( These are required for Binding the Port and IP Address )
     Bind to my own port and Address */

   memset(&receivesocket, 0, sizeof(receivesocket));
   receivesocket.sin_family = AF_INET;
   receivesocket.sin_addr.s_addr = htonl(INADDR_ANY);
      receivesocket.sin_port = htons(2905);

   receivelen = sizeof(receivesocket);

   /* Bind the my Socket */
   if (bind(sockFd, (struct sockaddr *) &receivesocket, receivelen) < 0)
   {
      perror("bind");
      return -1;
   }
   while (1)
   {
        memset(buf, 0, BUFFSIZE);

        /* Recieve the Data from Other system */
        if ((length = recvfrom(sockFd, buf, BUFFSIZE, 0, NULL, NULL)) < 0)
        {
                perror("recvfrom");
                return 0;
        }
        else if(length == 0)
        {
             cout<< " The Return Value is 0";
        }
        else
        {
              /* Print The data */
             cout<< " Recvd Byte length" << length <<endl;
             dumpData(buf, length);
        }
   }
}
/*
 * Dump Data
 */
void dumpData(unsigned char *data,  unsigned int len)
{
    unsigned int uIndx;

    if(data)
    {
        for(uIndx=0; uIndx<len; ++uIndx)
        {
           if(uIndx%32 == 0)
           {
              printf("\n%4d:", uIndx);
           }
           if(uIndx%4 == 0)
           {
                 printf(" ");
           }
           printf("%02x", data[uIndx]);
        }
    }
    printf(" Length of Bytes: %d\n", len);
    printf("\n");
}

Both send and Receive in one File:

#include <stdio.h>
#include <iostream.h>
#include <arpa/inet.h>
#include <string.h>

#define BUFFSIZE 5096

int sendlen, receivelen;
int i,count, sentCnt=0;
unsigned char buffer[BUFFSIZE];
/* client Socket */
struct sockaddr_in receivesocket;
/* Server Socket */
struct sockaddr_in sendsocket;

/* Sock FD */
int sockFd;

/* Number of Times you need */
unsigned int ch;
unsigned int noOfTimes;

/* Send UDP Data */
int sendUDPData();

/* Receive Call Back Function */
void *recvNetfilterData(void *);


int main(int argc, char *argv[]) {
int ret = 0;

   /* Create the UDP socket */
   if ((sockFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
           perror("socket");
           return -1;
   }

   /* my address or Parameters ( These are required for Binding the Port and
        IP Address )
     Bind to my own port and Address */
   memset(&receivesocket, 0, sizeof(receivesocket));
   receivesocket.sin_family = AF_INET;
   receivesocket.sin_addr.s_addr = htonl(INADDR_ANY);
   receivesocket.sin_port = htons(2905);

   receivelen = sizeof(receivesocket);

   /* Bind the my Socket */
   if (bind(sockFd, (struct sockaddr *) &receivesocket, receivelen) < 0) {
           perror("bind");
           return -1;
   }

   /* Server address or Parameters , Sending System Address and Port Num */
   memset(&sendsocket, 0, sizeof(sendsocket));
   sendsocket.sin_family = AF_INET;
   /* give Proper IP address */
   sendsocket.sin_addr.s_addr = inet_addr("10.1.1.1");
   sendsocket.sin_port = htons(2905);

   /* Create Seperate Thread */
   /* Start the Receiving Thread */

   pthread_t threadId;
   if(pthread_create(&threadId, NULL, recvNetfilterData, NULL))
   {
       cout<<"Error in creating receiver thread";
       return 0;
   }


   /* Do Loop -> Send UDP Data */
   do
    {
       cout<<endl;
       cout<<" Enter your choice:\t"<<endl;
       cout<<" 1. Send UDP Data" <<endl;
       cout<<" 2. exit" <<endl;
       cin>>ch;
       cout<<endl;

       switch(ch)
       {

           case 1:
                   cout<<"Enter the Length of the Payload "<<endl;
                   cin>>sendlen;
                   cout<<"Enter How many times you want to send data "<<endl;
                   cin>>noOfTimes;
                   /* Send UDP Data */
                   sendUDPData();
                   break;

           default:
                  cout<<"Invalid Choice\n";
                  break;
       }
 }while(ch!=2);
return 0;
}
/*
 *  sendUDPData
 */
int sendUDPData()
{
        int count=0;
        memset(buffer, 31, sendlen);

        for(count=0; count< noOfTimes;  count++)
        {
           /* Send the UDP Data */
           if (sendto(sockFd, buffer, sendlen, 0,
                (struct sockaddr *) &sendsocket, sizeof(sendsocket)) != sendlen)                   {
                perror("sendto");
                return -1;
           }
           else
           {
                sentCnt++;
           }
         }
    return 0;
}
/*
 * Dump Data
 */
void dumpData(unsigned char *data,  unsigned int len)
{
    unsigned int uIndx;
     if(data)
    {
        for(uIndx=0; uIndx<len; ++uIndx)
        {
           if(uIndx%32 == 0)
           {
              printf("\n%4d:", uIndx);
           }
           if(uIndx%4 == 0)
           {
                 printf(" ");
           }
           printf("%02x", data[uIndx]);
        }
    }
    printf(" Length of Bytes: %d\n", len);
    printf("\n");
}

/*
 * recvNetfilterData()
 */
void *recvNetfilterData(void *args)
{
    unsigned char buf[5096];
    int receivedLen = 0;

    while(true)
    {
        memset(buf, 0, BUFFSIZE);
        /* Recieve the Data from Other system */
        if ((receivedLen = recvfrom(sockFd, buf, BUFFSIZE, 0, NULL, NULL)) < 0)
        {
  perror("recvfrom");
                return 0;
        }
        else if(receivedLen == 0)
        {
             cout<< " The Return Value is 0";
        }
        else
        {
              /* Print The data */
             cout<< " Recvd Byte length" << receivedLen <<endl;
             dumpData(buf, receivedLen);
        }
    }
}


       Note: Change IP address and Port Number appropriately while sending /Recieving data. 
                 Sending Port Number and Listening port Number should be same.                                  

Monday, 30 January 2012

How to Detect Memory Leaks Using Valgrind memcheck Tool?

       In order to handle memory related issues in C/C++ code, there is a most popular open source tool called as VALGRIND.
Along with Memcheck tool, there are several tools which are supplied to ease the debugging for the programmer.
Several Other Tools available with VALGRIND
  • Memcheck is a memory error detector. It helps you make your programs, particularly those written in C and C++, more correct.
  • Cachegrind is a cache and branch-prediction profiler. It helps you make your programs run faster.
  • Callgrind is a call-graph generating cache profiler. It has some overlap with Cachegrind, but also gathers some information that Cachegrind does not.
  • Helgrind is a thread error detector. It helps you make your multi-threaded programs more correct.
  • DRD is also a thread error detector. It is similar to Helgrind but uses different analysis techniques and so may find different problems.
  • Massif is a heap profiler. It helps you make your programs use less memory.
  • DHAT is a different kind of heap profiler. It helps you understand issues of block lifetimes, block utilisation, and layout inefficiencies.
  • SGcheck is an experimental tool that can detect overruns of stack and global arrays. Its functionality is complementary to that of Memcheck: SGcheck finds problems that Memcheck can’t, and vice versa..
  • BBV is an experimental SimPoint basic block vector generator. It is useful to people doing computer architecture research and development.

Usage of Valgrind Memcheck Tool

The memcheck tool is used as follows :

valgrind --tool=memcheck ./a.out
 
As clear from the command above, the main binary is ‘Valgrind’ and the tool which we want to use is specified by the option ‘–tool’. The ‘a.out’ above signifies the executable over which we want to run memcheck.

To use this on our example program, test.c find below, try
gcc -o test -g test.c

This creates an executable named test.  To check for memory leaks during the execution of test, try  
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes 
                                    --num-callers=20 --track-fds=yes ./test

Explanation about Command:
--tool = memcheck
--leak-check = Yes , It means find the memory leaks and display in the screen.
--num-callers =20, This will give stack trace, the functions which pushed in to stack
--track-fds = Yes, It will give info about socket Fds. It will give error  if sock fd is opened and same Fd is not closed
--show-reachable = Yes
 "Still reachable" means you haven't deallocated a block of memory before exiting, but had a pointer to it.
In a C++ program this means that some object could have not been deleted and therefore its destructor might not have been run and thus say some data might have not been saved onto disk for example and some other action might not have been taken and thus your program might produce unexpected behavior.
However there're no destructors in C programs, so your program just can't depend on that. Also deallocating memory takes some time, so by not freeing memory on exit you can save some time - your program will exit faster (this can be significant for programs with lots of data).
So IMO if your C program has "still reachable" blocks it's not a problem but this indicates that some code in the program doesn't free memory and so you can expect bugs when reusing that code.

How to save valgrind  output into separate file?

valgrind --log-file=<filename>
where <filename> is the file name for output. Later you can view this file with less or text editor.

 This tool can detect the following memory related problems :
  • Use of uninitialized memory
  • Reading/writing memory after it has been freed
  • Reading/writing off the end of malloc’d blocks
  • Memory leaks
  • Mismatched use of malloc/new/new[] vs free/delete/delete[]
  • Doubly freed memory


This outputs a report to the terminal like
==9704== Memcheck, a memory error detector for x86-linux.
==9704== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==9704== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==9704== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==9704== For more details, rerun with: -v
==9704== 
==9704== 
==9704== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==9704== malloc/free: in use at exit: 35 bytes in 2 blocks.
==9704== malloc/free: 3 allocs, 1 frees, 47 bytes allocated.
==9704== For counts of detected errors, rerun with: -v
==9704== searching for pointers to 2 not-freed blocks.
==9704== checked 1420940 bytes.
==9704== 
==9704== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==9704==    at 0x1B903D38: malloc (vg_replace_malloc.c:131)
==9704==    by 0x80483BF: main (test.c:15)
==9704== 
==9704== 
==9704== 19 bytes in 1 blocks are definitely lost in loss record 2 of 2
==9704==    at 0x1B903D38: malloc (vg_replace_malloc.c:131)
==9704==    by 0x8048391: main (test.c:8)
==9704== 
==9704== LEAK SUMMARY:
==9704==    definitely lost: 35 bytes in 2 blocks.
==9704==    possibly lost:   0 bytes in 0 blocks.
==9704==    still reachable: 0 bytes in 0 blocks.
==9704==         suppressed: 0 bytes in 0 blocks.

Let's look at the code to see what happened. Allocation #1 (19 byte leak) is lost because p is pointed elsewhere before the memory from Allocation #1 is free'd. To help us track it down, Valgrind gives us a stack trace showing where the bytes were allocated. In the 19 byte leak entry, the bytes were allocate in test.c, line 8. Allocation #2 (12 byte leak) doesn't show up in the list because it is free'd. Allocation #3 shows up in the list even though there is still a reference to it (p) at program termination. This is still a memory leak! Again, Valgrind tells us where to look for the allocation (test.c line 15).
test.c file
#include <stdio.h>

int main()
{
  char *p;

  // Allocation #1 of 19 bytes
  p = (char *) malloc(19);

  // Allocation #2 of 12 bytes
  p = (char *) malloc(12);
  free(p);

  // Allocation #3 of 16 bytes
  p = (char *) malloc(16);

  return 0;
}
More Info and examples can be found at:
http://www.thegeekstuff.com/2011/11/valgrind-memcheck/