Difference between revisions of "Logging variables"

From OC Systems Wiki!
Jump to: navigation, search
m
Line 18: Line 18:
 
$(global-var, "-file file.c")
 
$(global-var, "-file file.c")
 
$(file-static, "-file file.c")
 
$(file-static, "-file file.c")
$(ada-global-var, "-unit sec/pkg")
+
$(powerada-global-var, "-unit sec/pkg")
 +
$(gnat-global-var, "-file pkg.adb")
 
</nowiki>
 
</nowiki>
  

Revision as of 18:17, 4 May 2017

Logging variables from applications with debug information is simple. In general, it is easy to log a variable using the log() probe directive and the variable's "target name." The variable must be logged from a probe in a scope where the variable is visible or you must specify the variable scope in the target expression.

From a probed function you can log parameters, local variables, function-static variables, file-static variables and globals within the same file using the target expression for the variable.

You can log global and static variables from any scope using the target expression modifiers -file or -unit (see examples below).

In most case, the target expression is just the variable name preceded by a dollar sign, for example:

$var
$structvar.field
$structptr->field

For global and file-static variables you may need to use target expression modifiers to locate the variable scope, for example:

$(global-var, "-file file.c")
$(file-static, "-file file.c")
$(powerada-global-var, "-unit sec/pkg")
$(gnat-global-var, "-file pkg.adb")

You can use the apcgen tool generate probes for logging functions, lines, and parameters. Version 4.4.6d of apcgen supports logging locals and globals.

If you don't have debug information in the application, you can still log parameters using positional notation ($1, $2, $3, ...). You can even cast the positional parameters to local types you declare in the probe.

C/C++ Example

For this C program:

int global = 1234;

static int file_local = 5678;

void p1(int param)
{
  static int func_static = 9876;

  int func_local = param * 10;

  {
     int block_local = param * 100;

     printf("b = %d\n", block_local);
     global += block_local;
  }
}

The following probe:

probe thread
{
   on_entry
   {
      // This probe not in any scope so we have to use the "-file" modifier to specify the scope. 
      log ("\"global\" = ", $(global, "-file main.c"));
      log ("\"file_local\" = ", $(file_local, "-file main.c"));
   }

   probe "p1"
   {
      // all target expressions are in the scope containing the variable so no modifiers needed.
      on_entry
      {
         log ("\"global\" = ", $global);
         log ("\"file_local\" = ", $file_local);
         log ("\"func_static\" = ", $func_static);
         log ("\"param\" = ", $param);
      }
      on_line(17)
      {
         log ("\"func_local\" = ", $func_local);
         log ("\"block_local\" = ", $block_local);
      }
   }
}

Produces the following output:

"global" = 1234
"file_local" = 5678
"global" = 1234
"file_local" = 5678
"func_static" = 9876
"param" = 1234
"func_local" = 12340
"block_local" = 123400

Ada Example

For an Ada program:

package Pkg is

  function P1(Param : in Integer) return Integer;

  PkgGlobal : Integer := 53;

end Pkg;

with Text_Io;

package body Pkg is

  PkgLocal : Integer := 27;

  function P1(Param : in Integer) return Integer is
    PLocal : Integer := Param * 5;
  begin
    Text_Io.Put_Line("PkgGlobal = " & Integer'Image(PkgGlobal));
    Text_Io.Put_Line("PkgLocal = " & Integer'Image(PkgLocal));
    Text_Io.Put_Line("Param = " & Integer'Image(Param));
    Text_Io.Put_Line("PLocal = " & Integer'Image(PLocal));
    declare
       PBlock : Integer := Param * 3;
    begin
       Text_Io.Put_Line("PBlock = " & Integer'Image(PBlock));
       PLocal := PLocal + PBlock;
    end;
    return PLocal;
  end P1;

The following probe:

probe thread
{
   probe "pkg.p1"
   {
      on_entry
      {
#ifdef _AIX
         // Must specify the PowerAda unit name to access global
         log ("\"PkgGlobal\" = ", $(PkgGlobal, "-unit lib/pkg"));
#else
         log ("\"PkgGlobal\" = ", $PkgGlobal);
#endif
         log ("\"PkgLocal\" = ", $PkgLocal);
         log ("\"Param\" = ", $Param);
      }
      on_line(18)
      {
         log ("\"PLocal\" = ", $PLocal);
         log ("\"PBlock\" = ", $PBlock);
      }
      on_exit
      {
         log ("\"Return\" = ", $return);
      }
   }
}

Produces the following output:

"PkgGlobal" = 53
"PkgLocal" = 27
"Param" = 1234
"PLocal" = 6170
"PBlock" = 3702
"Return" = 9872