OSDN Git Service

* config/pa/fptr.c: Update license header.
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-exextr.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                      ADA.EXCEPTIONS.EXCEPTION_TRACES                     --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2007, Free Software Foundation, Inc.         --
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 2,  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.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- As a special exception,  if other files  instantiate  generics from this --
23 -- unit, or you link  this unit with other files  to produce an executable, --
24 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
25 -- covered  by the  GNU  General  Public  License.  This exception does not --
26 -- however invalidate  any other reasons why  the executable file  might be --
27 -- covered by the  GNU Public License.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 with Ada.Unchecked_Conversion;
35
36 pragma Warnings (Off);
37 with Ada.Exceptions.Last_Chance_Handler;
38 pragma Warnings (On);
39 --  Bring last chance handler into closure
40
41 separate (Ada.Exceptions)
42 package body Exception_Traces is
43
44    Nline : constant String := String'(1 => ASCII.LF);
45    --  Convenient shortcut
46
47    type Exception_Action is access procedure (E : Exception_Occurrence);
48    Global_Action : Exception_Action := null;
49    pragma Export
50      (Ada, Global_Action, "__gnat_exception_actions_global_action");
51    --  Global action, executed whenever an exception is raised.  Changing the
52    --  export name must be coordinated with code in g-excact.adb.
53
54    Raise_Hook_Initialized : Boolean := False;
55    pragma Export
56      (Ada, Raise_Hook_Initialized, "__gnat_exception_actions_initialized");
57
58    procedure Last_Chance_Handler
59      (Except :  Exception_Occurrence);
60    pragma Import (C, Last_Chance_Handler, "__gnat_last_chance_handler");
61    pragma No_Return (Last_Chance_Handler);
62    --  Users can replace the default version of this routine,
63    --  Ada.Exceptions.Last_Chance_Handler.
64
65    function To_Action is new Ada.Unchecked_Conversion
66      (Raise_Action, Exception_Action);
67
68    -----------------------
69    -- Local Subprograms --
70    -----------------------
71
72    procedure Notify_Exception (Excep : EOA; Is_Unhandled : Boolean);
73    --  Factorizes the common processing for Notify_Handled_Exception and
74    --  Notify_Unhandled_Exception. Is_Unhandled is set to True only in the
75    --  latter case because Notify_Handled_Exception may be called for an
76    --  actually unhandled occurrence in the Front-End-SJLJ case.
77
78    --------------------------------
79    -- Import Run-Time C Routines --
80    --------------------------------
81
82    --  The purpose of the following pragma Import is to ensure that we
83    --  generate appropriate subprogram descriptors for all C routines in
84    --  the standard GNAT library that can raise exceptions. This ensures
85    --  that the exception propagation can properly find these routines
86
87    pragma Propagate_Exceptions;
88
89    ----------------------
90    -- Notify_Exception --
91    ----------------------
92
93    procedure Notify_Exception (Excep : EOA; Is_Unhandled : Boolean) is
94    begin
95       --  Output the exception information required by the Exception_Trace
96       --  configuration. Take care not to output information about internal
97       --  exceptions.
98
99       --  ??? In the Front-End ZCX case, the traceback entries we have at this
100       --  point only include the ones we stored while walking up the stack *up
101       --  to the handler*. All the frames above the subprogram in which the
102       --  handler is found are missing.
103
104       if not Excep.Id.Not_Handled_By_Others
105         and then
106         (Exception_Trace = Every_Raise
107           or else (Exception_Trace = Unhandled_Raise and then Is_Unhandled))
108       then
109          To_Stderr (Nline);
110
111          if Is_Unhandled then
112             To_Stderr ("Unhandled ");
113          end if;
114
115          To_Stderr ("Exception raised");
116          To_Stderr (Nline);
117          To_Stderr (Tailored_Exception_Information (Excep.all));
118       end if;
119
120       --  Call the user-specific actions
121       --  ??? We should presumably look at the reraise status here.
122
123       if Raise_Hook_Initialized
124         and then Exception_Data_Ptr (Excep.Id).Raise_Hook /= null
125       then
126          To_Action (Exception_Data_Ptr (Excep.Id).Raise_Hook) (Excep.all);
127       end if;
128
129       if Global_Action /= null then
130          Global_Action (Excep.all);
131       end if;
132    end Notify_Exception;
133
134    ------------------------------
135    -- Notify_Handled_Exception --
136    ------------------------------
137
138    procedure Notify_Handled_Exception is
139    begin
140       Notify_Exception (Get_Current_Excep.all, Is_Unhandled => False);
141    end Notify_Handled_Exception;
142
143    --------------------------------
144    -- Notify_Unhandled_Exception --
145    --------------------------------
146
147    procedure Notify_Unhandled_Exception is
148       Excep : constant EOA := Get_Current_Excep.all;
149
150    begin
151       --  Check whether there is any termination handler to be executed for
152       --  the environment task, and execute it if needed. Here we handle both
153       --  the Abnormal and Unhandled_Exception task termination. Normal
154       --  task termination routine is executed elsewhere (either in the
155       --  Task_Wrapper or in the Adafinal routine for the environment task).
156
157       Task_Termination_Handler.all (Excep.all);
158
159       Notify_Exception (Excep, Is_Unhandled => True);
160       Debug_Unhandled_Exception (SSL.Exception_Data_Ptr (Excep.Id));
161    end Notify_Unhandled_Exception;
162
163    -----------------------------------
164    -- Unhandled_Exception_Terminate --
165    -----------------------------------
166
167    procedure Unhandled_Exception_Terminate is
168       Excep : constant EOA := Save_Occurrence (Get_Current_Excep.all.all);
169       --  This occurrence will be used to display a message after finalization.
170       --  It is necessary to save a copy here, or else the designated value
171       --  could be overwritten if an exception is raised during finalization
172       --  (even if that exception is caught).
173
174    begin
175       Last_Chance_Handler (Excep.all);
176    end Unhandled_Exception_Terminate;
177
178    ------------------------------------
179    -- Handling GNAT.Exception_Traces --
180    ------------------------------------
181
182    --  The bulk of exception traces output is centralized in Notify_Exception,
183    --  for both the Handled and Unhandled cases. Extra task specific output is
184    --  triggered in the task wrapper for unhandled occurrences in tasks. It is
185    --  not performed in this unit to avoid dragging dependencies against the
186    --  tasking units here.
187
188    --  We used to rely on the output performed by Unhanded_Exception_Terminate
189    --  for the case of an unhandled occurrence in the environment thread, and
190    --  the task wrapper was responsible for the whole output in the tasking
191    --  case.
192
193    --  This initial scheme had a drawback: the output from Terminate only
194    --  occurs after finalization is done, which means possibly never if some
195    --  tasks keep hanging around.
196
197    --  The first "presumably obvious" fix consists in moving the Terminate
198    --  output before the finalization. It has not been retained because it
199    --  introduces annoying changes in output orders when the finalization
200    --  itself issues outputs, this also in "regular" cases not resorting to
201    --  Exception_Traces.
202
203    --  Today's solution has the advantage of simplicity and better isolates
204    --  the Exception_Traces machinery.
205
206    --  It currently outputs the information about unhandled exceptions twice
207    --  in the environment thread, once in the notification routine and once in
208    --  the termination routine. Avoiding the second output is possible but so
209    --  far has been considered undesirable. It would mean changing the order
210    --  of outputs between the two runs with or without exception traces, while
211    --  it seems preferrable to only have additional outputs in the former
212    --  case.
213
214 end Exception_Traces;