Downcasting Tagged Types

From OC Systems Wiki!
Revision as of 23:23, 30 March 2017 by Swn (talk | contribs) (Down-casting Ada tagged types in a probe.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Normally, logging a parameter using the target expression $r will be fine, but the parameter's value will be displayed using the type of the parameter. For tagged types, a parameter value may be any derived type. To log the value as a particular derived type you will have to down-cast the value to the desired type.

There is no dynamic type checking in probes, so you are responsible for assuring that the value is of the correct type to be down-cast (by checking the tag).

Ada Example

In the following Ada code a tagged base type, Base, is declared and a second tagged type, Derived, is derived from that base tagged type.

Package Base is

  type MyRec is tagged 
  record
     Field1 : Integer;
  end record;

  procedure Proc1(R : in out MyRec);

end Base;


with Base;

package Derived is

  type Extended is new Base.MyRec with 
  record
     Field2 : Integer;
  end record;

  procedure Proc2(R : in out Extended);

end Derived;

with Base;
with Derived;

procedure Main is
   Var1 : Base.MyRec := (Field1 => 1234);
   Var2 : Derived.Extended := (Field1 => 1, Field2 => 2);
begin
   Base.Proc1(Var1);
   Base.Proc1(Base.MyRec(Var2));
   Derived.Proc1(Var2);
end Main;

The following probe is used to log the value of the parameter R in the subprogram Base.Proc1() as a value of type Derived.Extended using a down-cast. The down-cast is accomplished by Derived.Extended in the probe, ands using

// Define a macro to reference the type Derived.Extended
#ifdef _AIX
         // For PowerAda use the -unit modifier
#define EXTENDED typeof($(Extended, "-unit lib/derived"))
#else
         // For Gnat use the file
#define EXTENDED typeof($(Extended, "-file derived.adb"))
#endif

probe thread
{
   probe "base.proc1"
   {
      on_entry
      {
         // This would log the parameter value as Base.MyRec
         //log("$R = ", $r);
         // Down-cast the parameter value to Derived.Extended
         log("$R(down-cast) = ", *(EXTENDED*)$r);
      }
   }
}

On PowerAda the following is logged.

$R(down-cast) = {
  _tag = 0x0
  _AnonField_1 = {
    field1 = 11
  }
  _AnonField_2 = {
    field2 = 10
  }
}
$R(down-cast) = {
  _tag = 0x1
  _AnonField_1 = {
    field1 = 12
  }
  _AnonField_2 = {
    field2 = 16
  }
}
$R(down-cast) = {
  _tag = 0x1
  _AnonField_1 = {
    field1 = 12
  }
  _AnonField_2 = {
    field2 = 16
  }
}

On Gnat the following is logged:

$R(down-cast) = {
  _parent = {
    _tag = 0x0
      field1 = 11
    }
  field2 = 10
}
$R(down-cast) = {
  _parent = {
    _tag = 0x1
      field1 = 12
    }
  field2 = 16
}
$R(down-cast) = {
  _parent = {
    _tag = 0x1
      field1 = 12
    }
  field2 = 16
}