OSDN Git Service

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