Sunday 4 September 2011

Debugging Running Process in Linux

A running process may not behave in a expected manner. This calls for anatomy of the running process.
There are various ways in which we can debug and understand the current state of the process.

Below are the three ways which i am familiar with and have been doing.
1. Using gdb command.
        gdb can be attached to a running process then using  breakpoint, watch and backtrace we can analyze the process behaviour and zero down to the location affecting the process behaviour.

2. Generating core dump of the running process
            core dump of the running process can be created using kill -11 command. The best part of this is core dump captures the current state of the process. The core dump can be analyzed without the need of the running process and at leisure.

3. Using gstack.
      This dumps the stack trace of all the running threads of the process. Running gstack on the process at different intervals gives a perspective of the process, number of threads and the methods taking up the time of the running threads.

Saturday 28 May 2011

C++ Up-Casting & Down-Casting in Inheritance Hierarchy


1. Upcasting / Down Casting in Brief

Upcasting : Upcasting is casting a derived class object to its Base Class Object. This is casting up the hierarchy and this is always allowed as the Base class object is subclass of the derived class.








Figure 1 : Inheritance hierarchy

D* pd = new D();
B* pb = pd;

DownCasting : DownCasting is casting a base class object pointer to its derived class object pointer. As the actual object contained in the derived class object pointer can be the Base class object or the derived class object . Therefore the compiler does  not performs the implicit conversion.
         DownCasting requires explicit casting by the user. static_cast and dynamic_cast are used for this purpose.

static_cast : Static cast is unsafe cast and does not performs any check if the object being converted is complete. As long as the conversion is in the same Inheritance hierarchy the code compiles. Since this does not has any overhead it is not expensive.

dynamic_cast : dynamic_cast is a safe cast as it performs a check if the object being converted  to is complete. If the check fails it returns NULL in pointer conversion and 'bad_cast' exception in reference conversion.
    dynamic_cast can only be used in polymorphic classes because it consults VTABLE to perform the check.

2. Casting in Single Inheritance :
   Casting in single inheritance is straightforward and does not needs any pointer arithmetic to be performed on the part of the compiler.

class A
{
public:
     virtual void foo();
};
class B : public A
{
public:
     virtual void foo();
};







Figure 2 : Memory Layout of object B

B *pb = new B();
A *pa = pb; // Upcasting from B to A.

For the Single Inheritance case Upcasting/Downcasting does not requires any pointer arithmetic, as both pointer to A and pointer to B points to the same location in memory. As shown in the above memory layout of the object B.


3. Casting in Multiple Inheritance :

Casting in multiple inheritance requires movement of pointer by some offset ( for the classes on the right hand side of the multiple inheritance). Lets see this in the below example


        









Figure 3: Memory Layout of Object D.

The contrast difference between single inheritance and multiple inheritance is in single inheritance we have one 'vptr' for an object irrespective of how deep down it is in inheritance hierarchy. Whereas in multiple Inheritance we have 'vptr' for each of the hierarchial path. In the above case the object D has 2 vptr.
Thus casting in multiple inheritance requires addition/subtraction of offset by the compiler.

D *pd = new D();
A *pa = pd;    // No pointer arithmetic pa points to same location as pd.
B *pb = pd;   // No pointer arithmetic pb points to same location as pd.
C *pc = pd;   // Compiles fine, but compiler has to subtract( in few cases add based on the memory layout )
                     //  offset from the D pointer in order to point pc to the Object C location. The pc location is
                     //  shown in the memory model.
All of the above compiles, whereas in the third case the compiler had to do pointer arithmetic as the Object C in the object model is embedded in the object D and does not shares A & B address space. Thus the pc does not points to the same location as that of 'pd'.

DownCasting :
D *pd = static_cast<D*>(pa);   // No Pointer Arithmetic performed by compiler, pa and pd points to same location
D *pd = static_cast<D*>(pb);  // No Pointer Arithmetic performed by compiler, pb and pd points to same location
D *pd = static_cast<D*>(pc);  // compiler had to adjust the pointer ( add/subtract ) in order to point it to D object address.

In the case 1 and 2 no change in the pointer whereas in case 3, pointer has to be adjusted to point it to the D's object address.

3. Casting in Virtual Inheritance :
             Whenever we have a common base class in the inheritance hierarchy. Then this common base class is added more than once in the derived class ( i.e added once for each path). In order to have only one instance of Base class we need to use virtual inheritance.















Figure 4: Memory Layout of Object D using Virtual Inheritance

The memory layout of virtual inheritance is not trivial. consult the "virtual inheritance in detail"  section for detailed information.
As the memory layout is not trivial it adds more load on the casting.


Upcasting :

D* pd = new D();
B* pb = pd;    // No Pointer Arithmetic performed by compiler, pb and pd points to same location
C* pc = pd;    // Compiler had to pointer arithmetic in order to point pc to the Object C location.
A* pa = pd;    // Compiler had to pointer arithmetic in order to point pa to the Object A location.

All of the above compiles fine, conversion from pd to pc does not requires any pointer arithmetic.
Whereas conversion from object pointet of D to object pointer of C and object pointer of A required pointer arithmetic to be performed by the compiler.

DownCasting :
   In Single Inheritance and Multiple Inheritance down casting is achieved by static_cast (dynamic_cast is required only when we require safecasting in polymorphic classes).

D *pd1 = static_cast<D*>(pb);  // compiles fine : No pointer arithmetic
D *pd2 = static_cast<D*>(pc);  // compiles fine : but compiler performs pointer arithme
D *pd3 = static_cast<D*>(pa);  // Compilation ERROR

The last statement gives the following error on one of my compilers : "Cannot convert from base A to derived type D via virtual base A". That is pretty clear: Given the layout just shown you can understand why is the error.
you cannot cast from a virtual base class to the derived class using static_cast

We had to chase(pointer to Base A) a pointer to get from a B, C or D oject pointer to the A Sub-Object, but there is no way to go to the opposite direction.
  Whereas the virtual funciton mechanism works properly on A. It recovers object D from pointer to A.

pa->foo();  // calls D::foo()

dynamic_cast is used to convert or Downcast from virtual base class pointer to the derived object pointer.

D *pd3 = dynamic_cast<D*>(pa);

dynamic_cast references the virtual table to get the offset information to convert the A object pointer into D object pointer. It moves the pointer by the offset and returns the pointer to D.

NOTE: In order to use dynamic_cast on the virtual base class. The virtual base class has to be polymorphic.





Monday 28 March 2011

Typename v/s class

The key words 'typename' and 'class' are a matter of choice in below case.


template<typename T>
class New{....}


whereas i prefer using typename as the typename was introduced specifically to name a type.


It is not matter of choice always, for line number 6 and 7, class cannot be used as a substitute for typename.
  - i is of independent type ( its not dependent on type T ).
  - d is a dependent type, it depends on the template parameter T.
  - begin is of Nested dependent type, as it type depends on the nested class iterator present within the dependent type T.

typename has to be prefixed on the Nested dependent type.


  1. template <typename Type>
  2. bool doSomeCrap
  3. {
  4.       int i;
  5.       T d;
  6.      typename Type::iterator begin = cont.begin();  
  7.      typename Type::iterator end = cont.end() - 1;  
  8.      return *begin > *end;
  9. }


Stan Lippman speaks about the historical reasons for supporting both  here. I found it interesting...