HPlogo System Debug Reference Manual > Chapter 7 Symbolic Formatting Symbolic Access

Using the Symbolic Formatter

MPE documents

Complete PDF
Table of Contents
Index

E0201 Edition 4 ♥
E0300 Edition 3
E0692 Edition 3

This section gives several examples of how to use the symbolic formatting facility.

Formatting Types


Refer to the beginning of this chapter to review the type declarations used in this section.

After the source types are converted into a symbolic data type file, the file is SYMOPENed and given a symbolic name of grades.

   $nmdebug > SYMOPEN gradtyp.demo grades

The symbolic formatter is now able to display type information and format actual data using this symbolic data type file:

   $nmdebug > FT "grades:StudentRecord"

   RECORD
      NAME     : NAMESTR ;
      ID       : INTEGER ;
      YEAR     : CLASS ;
      NUMGRADES: GRADERANGE ;
      GRADES   : GRADESARRAY ;
   END

Display the structure of StudentRecord. The symname part of the path specification is optional. If none is given, the last accessed symbolic file is assumed.

   $nmdebug > FT "studentrecord" MAP

   RECORD
      NAME     : NAMESTR ;   ( 0.0 @ 10.0 )
      ID       : INTEGER ;   ( 10.0 @ 4.0 )
      YEAR     : CLASS ;   ( 14.0 @ 1.0 )
      NUMGRADES: GRADERANGE ;   ( 15.0 @ 1.0 )
      GRADES   : GRADESARRAY ;   ( 18.0 @ 28.0 )
   END ;
   RECORD Size: 40 bytes

The MAP option of the FT command causes a location map to be printed for components of complex data structures such as records or arrays. The format of the location map is similar to the one generated by the $MAPINFO ON$ option of the Pascal compiler.

   $nmdebug > FT "studentrecord.grades"

   ARRAY [ GRADERANGE  ] OF INTEGER

   $nmdebug > FT "graderange"

   1 .. 10

   $nmdebug > FT "maxgrades"

   INTEGER

   $nmdebug > FT "class"

   ( SENIOR, JUNIOR, SOPHOMORE, FRESHMAN )

Display various types. Notice that path specification is not limited to a simple type or constant name, but rather it may consist of any composite path specification.

The examples in the following pages include variant records and pointers. The following set of type declarations is used:

   $nmdebug > ft "PersonPtr"

   ^ PERSON

   $nmdebug > ft "PersonPtr^"

   RECORD
      NEXT: PERSONPTR ;
      NAME: STRING[ 10 ];
      SEX : ( MALE, FEMALE );
      CASE MS: MSTYPE OF
         MARRIED : ( NUMKIDS: INTEGER );
         DIVORCED: ( HOWLONG: INTEGER );
         SINGLE  : ( LOOKING: BOOLEAN );
         WIDOWED : ( );
   END

   $nmdebug > ft "PersonPtr^.Sex"

   ( MALE, FEMALE )

Notice that you can refer to a type with a pointer dereference. That is, "Show me the type that this pointer points to."

Formatting Data


The FV command allows you to format data at any virtual address using a given data structure:

   format  at_any_virtual_address as_if_it_were_a_specific_type

Before proceeding to some examples, we must deal with the question, "How do I find the virtual address of the data structure I want to format?" Most language compilers use the following conventions (as detailed in the Procedure Calling Conventions Manual:
  • Global data is stored relative to DP (data pointer). DP is an alias for R27.

  • Procedure local variables are stored relative to SP (stack pointer). SP is an alias for R30.

  • Procedure parameters are stored in the argument registers (ARG0-ARG3) and in the stack relative to PSP (previous stack pointer). PSP is not contained in a register but is a pseudo-register that is computed by System Debug.

A variable map is required to find the location of a variable at any given time. These maps are generated as part of the program listing by the language compilers. Each compiler has a unique compiler option, which must be specified in order for the variable map to be included in the listing. For Pascal, the option is $TABLES ON$. For additional details on generating and interpreting this information, refer to the appropriate language reference manual. Each language also has a programmers manual which provides detailed language-specific examples illustrating how to use Debug to debug a program.


CAUTION: If code optimization is done by the compiler, the location of the variables at any given time is indeterminable. Refer to the appropriate language manual for other issues concerning optimized code.

In the following examples, we assume that the System Debug variable addr1 contains the address of a data structure corresponding to the type StudentArray. In addition, located at dp+8 is a data structure defined by the person record. For example,

   $nmdebug > fv addr1 "StudentRecord"
   RECORD
      NAME      : 'Bill'
      ID        : 1
      YEAR      : SENIOR
      NUMGRADES : 4
      GRADES    :
         [ 1 ]: 2d
         [ 2 ]: 41
         [ 3 ]: 4e
         [ 4 ]: 42
         [ 5 ]: 0
         [ 6 ]: 0
         [ 7 ]: 0
         [ 8 ]: 0
         [ 9 ]: 0
         [ a ]: 0
   END


   $nmdebug > fv dp+8 "person"
   RECORD
      NEXT : 40200024
      NAME : 'Mrs. Smith'
      SEX  : FEMALE
      MS   : MARRIED
         NUMKIDS : 3
   END

The above examples show complete formatted record structures. Note that for variants with stored tags, the variants formatted are determined by the actual tag values.

When only a small portion of a large data structure needs to be examined, a path specification may be used to specify an item of interest, either simple or composite:

   $nmdebug > fv addr1 "StudentRecord.Name"

   'Bill'

   $nmdebug > fv addr1 "StudentRecord.Year"

   SENIOR

   $nmdebug > fv dp+8 "Person.sex"

   FEMALE

The above examples show how any field within a record may be formatted. Note that the address supplied is always the address for the beginning of the record, not the address of the field of interest.

As with field selection, array elements can also be selected. The command

   $nmdebug > fv addr1 "StudentRecord.Grades[3]" 

4e

displays only the third element of the field grades within the record StudentRecord.

As we saw in the person example above, if a data structure contains a pointer, its value (that is, the address of the pointed-to structure) is displayed. If the target of the pointer is desired, the caret (^) is used to indicate dereferencing. Consider the following examples:


   $nmdebug > fv dp+8 "person.next"
   40200024

   $nmdebug > fv dp+8 "person.next^"
   RECORD
      NEXT : 40200300
      NAME : 'Mr. Jones'
      SEX  : MALE
      MS   : SINGLE
         LOOKING : TRUE
   END

   $nmdebug > fv dp+8 "person.next^.next^.next^.next^.name"
   'Mrs. Robinson'

If you try to dereference a field which contains a nil or invalid pointer, an error message is generated and the formatter stops formatting.

For variant records in which the tag fields are not stored, the variants to be used when formatting them may be specified by including tag field values. If no field is supplied, the first variant of the structure is assumed. The following examples are based on these types:

   bit8 = 0 .. 255;

   CoerceRec = RECORD
      CASE integer OF
           0 : (int   : integer);
           1 : (ch    : PACKED ARRAY [1..4]  OF char);
           2 : (byte  : PACKED ARRAY [1..4]  OF bit8);
           3 : (bool  : PACKED ARRAY [1..32] OF boolean);
   END;

Consider the following examples assuming that the System Debug variable addr contains the address of some data corresponding to a CoerceRec data structure:

   $nmdat > FV addr2 "CoerceRec"

   RECORD
         INT : 4a554e4b
   END

We assume the first variant for the CoerceRec and print out the data as an integer value. We now ask for an explicit variant:

   $nmdat > FV addr2 "CoerceRec,1"

   RECORD
         CH : 'JUNK'
   END

We may explicitly ask for the data to be formatted in any of the possible variants. In the above example we asked for variant 1 (as characters). Notice that since this is a packed array of char (PAC), the formatter prints the data as a character string. To have PACs printed as arrays, specify the NOPAC option:

   $nmdat > FV addr2 "CoerceRec,1" NOPAC

   RECORD
         CH : [ 1 ]: 'J'
              [ 2 ]: 'U'
              [ 3 ]: 'N'
              [ 4 ]: 'K'
   END

Also note that packed array of Boolean (PAB) are printed as a string of bits. To have such structures printed as arrays, you can specify the NOPAB options.


   $nmdat > FV addr2 "CoerceRec,3"

   RECORD
         BOOL :
            [ 1 ]: 01001010010101010100111001001011
   END


   $nmdat > FV addr2 "CoerceRec,3" NOPAB

   RECORD
         BOOL :
            [  1 ]: FALSE
            [  2 ]: TRUE
            [  3 ]: FALSE
                 .
                 .  <etc for the rest of the array>
              .
            [ 32 ]: TRUE
   END




The Path Specification


Using Symbolic Access