Opened 16 months ago

#358 new defect

initiate command fails to handle allocation error from hcs_$status_

Reported by: Gary Dixon Owned by: Eric Swenson
Priority: minor Milestone:
Component: Administration Version: MR12.6e
Keywords: Cc:

Description

An hcs_$status_ call in initiate.pl1 can report an error_table_$notalloc error when it successfully allocates storage in an extensible area. Symptoms seen are shown in the com_err_ messages below.

azm:  ec event_channel_table.azmec
initiate: Allocation could not be performed. Unable to get names of >udd>m>gd>w>ect>token
initiate: Allocation could not be performed. Unable to get names of >udd>m>gd>w>ect>bit_string

In ect.azmec are two calls the initiate commands to ensure the uninstalled tools are found by the exec_com.

      e initiate &ec_dir>token -force -all                  &-     - Needs new token command/AF used by this exec_com
      e initiate &ec_dir>bit_string -force -all             &-     - Needs new bit_string command/AF used by this exec_com

Since the error refers to failure to allocate names, I presume that code implementing the -all control argument is causing the problem.

In initiate.pl1, -all turns on all_sw. Since we are supplying a full pathname to initiate command, the affected code is shown below.

     if ^got_path then do;
          call expand_pathname_ (arg, dn, en, code);
          if code ^= 0 then do;
               call com_err_ (code, "initiate", "^a", arg);
               return;
          end;
          got_path = "1"b;

          if all_sw then do;
              got_refname = "1"b;
               area_ptr = get_system_free_area_ ();
               on condition (cleanup) call clean_up;
               call hcs_$status_ (dn, en, fixed (chase_sw, 1), 
                         addr (branch_status), area_ptr, code);
               if code ^= 0 then do;
                    call com_err_ (code, "initiate",
                         "Unable to get names of ^a^[>^]^a", dn, dn ^= ">", en);
                    return;
               end;

Notice the”Unable to get names of …” error. The status code is error_table_$notalloc. From error_table_.alm:

ec  notalloc,,
          (Allocation could not be performed.)

The hcs_$status_ gate entry transfers to status_$status_ with an area_ptr set to the system free area for the user ring of the calling process. status_.pl1 references the error_table_$notalloc code in only one place:

          on area call fatal_error (error_table_$noalloc);

          if n_names_to_allocate > 0
          then do;
               if have_s_permission
               then allocate return_names in (return_area) set (return_names_ptr);
               else n_names_to_allocate = 0; /* if no status, we have no name structure to copy */
            end;
          if pathname_length_to_allocate > 0
          then allocate return_pathname in (return_area) set (return_pathname_ptr);

          if return_names_ptr ^= null | return_pathname_ptr ^= null
          then do;
               if (return_names_ptr ^= null & baseno (return_names_ptr) ^= baseno (return_area_ptr))
                | (return_pathname_ptr ^= null
                & baseno (return_pathname_ptr) ^= baseno (return_area_ptr))
               then call fatal_error (error_table_$notalloc);

This code checks that both return_names_ptr and return_pathname_ptr are non-null and point to an allocation space in the first extent of the possibly extensible area pointer they were passed.

1 branch_status aligned,                /* automatic: hcs_$status uses a pointer */
  2 type bit(2) unaligned,              /* type of entry: link, segment, dir */
  2 number_names bit(16) unaligned,     /* unused by directory_status_ */
  2 names_rel_pointer bit(18) unaligned,/* unused by directory_status_ */
              ...

If the allocations were done in one of the additional extents of that area, then the allocated names array is returned as an offset value from the base of the return_area_ptr, but the allocated space is in a different segment (extent) than the first extent of that area.

This is a limitation of the data return protocol of hcs_$status. The only way to avoid the problem is to pass in a non-extensible area which has enough space to hold the names array. For example, space for 100 segment names requires 3200 characters of storage (or 800 words). initiate.pl1 could create a 1-page area in its stack frame to hold this storage (rather than using the system free area).

  dcl  area area (1024);

  call hcs_$status_ (dn, en, fixed (chase_sw,1), addr (branch_status), addr(area), code);

By using an automatic area, the cleanup condition handler is no longer necessary, because the area is abandoned when the initiate command returns to its caller. Initialization of the area is performed by the prologue code of the initiate entry point (the same code that pushes the stack frame and initializes other automatic variables).

Change History (0)

Note: See TracTickets for help on using tickets.