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-2019, 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-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 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 34with System.Machine_State_Operations; 35 36package 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 137end System.Traceback; 138