File : s-traceb-mastop.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --                     S Y S T E M . T R A C E B A C K                      --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --                     Copyright (C) 1999-2015, AdaCore                     --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 --  This version uses System.Machine_State_Operations routines
  33 
  34 with System.Machine_State_Operations;
  35 
  36 package body System.Traceback is
  37 
  38    use System.Machine_State_Operations;
  39 
  40    procedure Call_Chain
  41      (Traceback   : System.Address;
  42       Max_Len     : Natural;
  43       Len         : out Natural;
  44       Exclude_Min : System.Address := System.Null_Address;
  45       Exclude_Max : System.Address := System.Null_Address;
  46       Skip_Frames : Natural := 1);
  47    --  Same as the exported version, but takes Traceback as an Address
  48 
  49    ----------------
  50    -- Call_Chain --
  51    ----------------
  52 
  53    procedure Call_Chain
  54      (Traceback : System.Address;
  55       Max_Len   : Natural;
  56       Len       : out Natural;
  57       Exclude_Min : System.Address := System.Null_Address;
  58       Exclude_Max : System.Address := System.Null_Address;
  59       Skip_Frames : Natural := 1)
  60    is
  61       type Tracebacks_Array is array (1 .. Max_Len) of Code_Loc;
  62       pragma Suppress_Initialization (Tracebacks_Array);
  63 
  64       M     : Machine_State;
  65       Code  : Code_Loc;
  66 
  67       Trace : Tracebacks_Array;
  68       for Trace'Address use Traceback;
  69 
  70       N_Skips  : Natural := 0;
  71 
  72    begin
  73       M := Allocate_Machine_State;
  74       Set_Machine_State (M);
  75 
  76       --  Skip the requested number of frames
  77 
  78       loop
  79          Code := Get_Code_Loc (M);
  80          exit when Code = Null_Address or else N_Skips = Skip_Frames;
  81 
  82          Pop_Frame (M);
  83          N_Skips := N_Skips + 1;
  84       end loop;
  85 
  86       --  Now, record the frames outside the exclusion bounds, updating
  87       --  the Len output value along the way.
  88 
  89       Len := 0;
  90       loop
  91          Code := Get_Code_Loc (M);
  92          exit when Code = Null_Address or else Len = Max_Len;
  93 
  94          if Code < Exclude_Min or else Code > Exclude_Max then
  95             Len := Len + 1;
  96             Trace (Len) := Code;
  97          end if;
  98 
  99          Pop_Frame (M);
 100       end loop;
 101 
 102       Free_Machine_State (M);
 103    end Call_Chain;
 104 
 105    procedure Call_Chain
 106      (Traceback   : in out System.Traceback_Entries.Tracebacks_Array;
 107       Max_Len     : Natural;
 108       Len         : out Natural;
 109       Exclude_Min : System.Address := System.Null_Address;
 110       Exclude_Max : System.Address := System.Null_Address;
 111       Skip_Frames : Natural := 1)
 112    is
 113    begin
 114       Call_Chain
 115         (Traceback'Address, Max_Len, Len,
 116          Exclude_Min, Exclude_Max,
 117 
 118          --  Skip one extra frame to skip the other Call_Chain entry as well
 119 
 120          Skip_Frames => Skip_Frames + 1);
 121    end Call_Chain;
 122 
 123    ------------------
 124    -- C_Call_Chain --
 125    ------------------
 126 
 127    function C_Call_Chain
 128      (Traceback : System.Address;
 129       Max_Len   : Natural) return Natural
 130    is
 131       Val : Natural;
 132    begin
 133       Call_Chain (Traceback, Max_Len, Val);
 134       return Val;
 135    end C_Call_Chain;
 136 
 137 end System.Traceback;