annotate gcc/ada/libgnat/memtrack.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT RUN-TIME COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- S Y S T E M . M E M O R Y --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 2001-2017, Free Software Foundation, Inc. --
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 -- This version contains allocation tracking capability
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 -- The object file corresponding to this instrumented version is to be found
kono
parents:
diff changeset
35 -- in libgmem.
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 -- When enabled, the subsystem logs all the calls to __gnat_malloc and
kono
parents:
diff changeset
38 -- __gnat_free. This log can then be processed by gnatmem to detect
kono
parents:
diff changeset
39 -- dynamic memory leaks.
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 -- To use this functionality, you must compile your application with -g
kono
parents:
diff changeset
42 -- and then link with this object file:
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 -- gnatmake -g program -largs -lgmem
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 -- After compilation, you may use your program as usual except that upon
kono
parents:
diff changeset
47 -- completion, it will generate in the current directory the file gmem.out.
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 -- You can then investigate for possible memory leaks and mismatch by calling
kono
parents:
diff changeset
50 -- gnatmem with this file as an input:
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 -- gnatmem -i gmem.out program
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 -- See gnatmem section in the GNAT User's Guide for more details
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 -- NOTE: This capability is currently supported on the following targets:
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 -- Windows
kono
parents:
diff changeset
59 -- AIX
kono
parents:
diff changeset
60 -- GNU/Linux
kono
parents:
diff changeset
61 -- HP-UX
kono
parents:
diff changeset
62 -- Solaris
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 -- NOTE FOR FUTURE PLATFORMS SUPPORT: It is assumed that type Duration is
kono
parents:
diff changeset
65 -- 64 bit. If the need arises to support architectures where this assumption
kono
parents:
diff changeset
66 -- is incorrect, it will require changing the way timestamps of allocation
kono
parents:
diff changeset
67 -- events are recorded.
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 pragma Source_File_Name (System.Memory, Body_File_Name => "memtrack.adb");
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 with Ada.Exceptions;
kono
parents:
diff changeset
72 with System.Soft_Links;
kono
parents:
diff changeset
73 with System.Traceback;
kono
parents:
diff changeset
74 with System.Traceback_Entries;
kono
parents:
diff changeset
75 with GNAT.IO;
kono
parents:
diff changeset
76 with System.OS_Primitives;
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 package body System.Memory is
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 use Ada.Exceptions;
kono
parents:
diff changeset
81 use System.Soft_Links;
kono
parents:
diff changeset
82 use System.Traceback;
kono
parents:
diff changeset
83 use System.Traceback_Entries;
kono
parents:
diff changeset
84 use GNAT.IO;
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 function c_malloc (Size : size_t) return System.Address;
kono
parents:
diff changeset
87 pragma Import (C, c_malloc, "malloc");
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 procedure c_free (Ptr : System.Address);
kono
parents:
diff changeset
90 pragma Import (C, c_free, "free");
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 function c_realloc
kono
parents:
diff changeset
93 (Ptr : System.Address; Size : size_t) return System.Address;
kono
parents:
diff changeset
94 pragma Import (C, c_realloc, "realloc");
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 subtype File_Ptr is System.Address;
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 function fopen (Path : String; Mode : String) return File_Ptr;
kono
parents:
diff changeset
99 pragma Import (C, fopen);
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 procedure OS_Exit (Status : Integer);
kono
parents:
diff changeset
102 pragma Import (C, OS_Exit, "__gnat_os_exit");
kono
parents:
diff changeset
103 pragma No_Return (OS_Exit);
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 procedure fwrite
kono
parents:
diff changeset
106 (Ptr : System.Address;
kono
parents:
diff changeset
107 Size : size_t;
kono
parents:
diff changeset
108 Nmemb : size_t;
kono
parents:
diff changeset
109 Stream : File_Ptr);
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 procedure fwrite
kono
parents:
diff changeset
112 (Str : String;
kono
parents:
diff changeset
113 Size : size_t;
kono
parents:
diff changeset
114 Nmemb : size_t;
kono
parents:
diff changeset
115 Stream : File_Ptr);
kono
parents:
diff changeset
116 pragma Import (C, fwrite);
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 procedure fputc (C : Integer; Stream : File_Ptr);
kono
parents:
diff changeset
119 pragma Import (C, fputc);
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 procedure fclose (Stream : File_Ptr);
kono
parents:
diff changeset
122 pragma Import (C, fclose);
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 procedure Finalize;
kono
parents:
diff changeset
125 pragma Export (C, Finalize, "__gnat_finalize");
kono
parents:
diff changeset
126 -- Replace the default __gnat_finalize to properly close the log file
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 Address_Size : constant := System.Address'Max_Size_In_Storage_Elements;
kono
parents:
diff changeset
129 -- Size in bytes of a pointer
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 Max_Call_Stack : constant := 200;
kono
parents:
diff changeset
132 -- Maximum number of frames supported
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 Tracebk : Tracebacks_Array (1 .. Max_Call_Stack);
kono
parents:
diff changeset
135 Num_Calls : aliased Integer := 0;
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 Gmemfname : constant String := "gmem.out" & ASCII.NUL;
kono
parents:
diff changeset
138 -- Allocation log of a program is saved in a file gmem.out
kono
parents:
diff changeset
139 -- ??? What about Ada.Command_Line.Command_Name & ".out" instead of static
kono
parents:
diff changeset
140 -- gmem.out
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 Gmemfile : File_Ptr;
kono
parents:
diff changeset
143 -- Global C file pointer to the allocation log
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 Needs_Init : Boolean := True;
kono
parents:
diff changeset
146 -- Reset after first call to Gmem_Initialize
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148 procedure Gmem_Initialize;
kono
parents:
diff changeset
149 -- Initialization routine; opens the file and writes a header string. This
kono
parents:
diff changeset
150 -- header string is used as a magic-tag to know if the .out file is to be
kono
parents:
diff changeset
151 -- handled by GDB or by the GMEM (instrumented malloc/free) implementation.
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 First_Call : Boolean := True;
kono
parents:
diff changeset
154 -- Depending on implementation, some of the traceback routines may
kono
parents:
diff changeset
155 -- themselves do dynamic allocation. We use First_Call flag to avoid
kono
parents:
diff changeset
156 -- infinite recursion
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 -----------
kono
parents:
diff changeset
159 -- Alloc --
kono
parents:
diff changeset
160 -----------
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 function Alloc (Size : size_t) return System.Address is
kono
parents:
diff changeset
163 Result : aliased System.Address;
kono
parents:
diff changeset
164 Actual_Size : aliased size_t := Size;
kono
parents:
diff changeset
165 Timestamp : aliased Duration;
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 begin
kono
parents:
diff changeset
168 if Size = size_t'Last then
kono
parents:
diff changeset
169 Raise_Exception (Storage_Error'Identity, "object too large");
kono
parents:
diff changeset
170 end if;
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 -- Change size from zero to non-zero. We still want a proper pointer
kono
parents:
diff changeset
173 -- for the zero case because pointers to zero length objects have to
kono
parents:
diff changeset
174 -- be distinct, but we can't just go ahead and allocate zero bytes,
kono
parents:
diff changeset
175 -- since some malloc's return zero for a zero argument.
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 if Size = 0 then
kono
parents:
diff changeset
178 Actual_Size := 1;
kono
parents:
diff changeset
179 end if;
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 Lock_Task.all;
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 Result := c_malloc (Actual_Size);
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 if First_Call then
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 -- Logs allocation call
kono
parents:
diff changeset
188 -- format is:
kono
parents:
diff changeset
189 -- 'A' <mem addr> <size chunk> <len backtrace> <addr1> ... <addrn>
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 First_Call := False;
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 if Needs_Init then
kono
parents:
diff changeset
194 Gmem_Initialize;
kono
parents:
diff changeset
195 end if;
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 Timestamp := System.OS_Primitives.Clock;
kono
parents:
diff changeset
198 Call_Chain
kono
parents:
diff changeset
199 (Tracebk, Max_Call_Stack, Num_Calls, Skip_Frames => 2);
kono
parents:
diff changeset
200 fputc (Character'Pos ('A'), Gmemfile);
kono
parents:
diff changeset
201 fwrite (Result'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
202 fwrite (Actual_Size'Address, size_t'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
203 Gmemfile);
kono
parents:
diff changeset
204 fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
205 Gmemfile);
kono
parents:
diff changeset
206 fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
207 Gmemfile);
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 for J in Tracebk'First .. Tracebk'First + Num_Calls - 1 loop
kono
parents:
diff changeset
210 declare
kono
parents:
diff changeset
211 Ptr : System.Address := PC_For (Tracebk (J));
kono
parents:
diff changeset
212 begin
kono
parents:
diff changeset
213 fwrite (Ptr'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
214 end;
kono
parents:
diff changeset
215 end loop;
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 First_Call := True;
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 end if;
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 Unlock_Task.all;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 if Result = System.Null_Address then
kono
parents:
diff changeset
224 Raise_Exception (Storage_Error'Identity, "heap exhausted");
kono
parents:
diff changeset
225 end if;
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 return Result;
kono
parents:
diff changeset
228 end Alloc;
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 --------------
kono
parents:
diff changeset
231 -- Finalize --
kono
parents:
diff changeset
232 --------------
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 procedure Finalize is
kono
parents:
diff changeset
235 begin
kono
parents:
diff changeset
236 if not Needs_Init then
kono
parents:
diff changeset
237 fclose (Gmemfile);
kono
parents:
diff changeset
238 end if;
kono
parents:
diff changeset
239 end Finalize;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 ----------
kono
parents:
diff changeset
242 -- Free --
kono
parents:
diff changeset
243 ----------
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 procedure Free (Ptr : System.Address) is
kono
parents:
diff changeset
246 Addr : aliased constant System.Address := Ptr;
kono
parents:
diff changeset
247 Timestamp : aliased Duration;
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 begin
kono
parents:
diff changeset
250 Lock_Task.all;
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 if First_Call then
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 -- Logs deallocation call
kono
parents:
diff changeset
255 -- format is:
kono
parents:
diff changeset
256 -- 'D' <mem addr> <len backtrace> <addr1> ... <addrn>
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 First_Call := False;
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 if Needs_Init then
kono
parents:
diff changeset
261 Gmem_Initialize;
kono
parents:
diff changeset
262 end if;
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 Call_Chain
kono
parents:
diff changeset
265 (Tracebk, Max_Call_Stack, Num_Calls, Skip_Frames => 2);
kono
parents:
diff changeset
266 Timestamp := System.OS_Primitives.Clock;
kono
parents:
diff changeset
267 fputc (Character'Pos ('D'), Gmemfile);
kono
parents:
diff changeset
268 fwrite (Addr'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
269 fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
270 Gmemfile);
kono
parents:
diff changeset
271 fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
272 Gmemfile);
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 for J in Tracebk'First .. Tracebk'First + Num_Calls - 1 loop
kono
parents:
diff changeset
275 declare
kono
parents:
diff changeset
276 Ptr : System.Address := PC_For (Tracebk (J));
kono
parents:
diff changeset
277 begin
kono
parents:
diff changeset
278 fwrite (Ptr'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
279 end;
kono
parents:
diff changeset
280 end loop;
kono
parents:
diff changeset
281
kono
parents:
diff changeset
282 c_free (Ptr);
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 First_Call := True;
kono
parents:
diff changeset
285 end if;
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 Unlock_Task.all;
kono
parents:
diff changeset
288 end Free;
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 ---------------------
kono
parents:
diff changeset
291 -- Gmem_Initialize --
kono
parents:
diff changeset
292 ---------------------
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 procedure Gmem_Initialize is
kono
parents:
diff changeset
295 Timestamp : aliased Duration;
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 begin
kono
parents:
diff changeset
298 if Needs_Init then
kono
parents:
diff changeset
299 Needs_Init := False;
kono
parents:
diff changeset
300 System.OS_Primitives.Initialize;
kono
parents:
diff changeset
301 Timestamp := System.OS_Primitives.Clock;
kono
parents:
diff changeset
302 Gmemfile := fopen (Gmemfname, "wb" & ASCII.NUL);
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 if Gmemfile = System.Null_Address then
kono
parents:
diff changeset
305 Put_Line ("Couldn't open gnatmem log file for writing");
kono
parents:
diff changeset
306 OS_Exit (255);
kono
parents:
diff changeset
307 end if;
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 fwrite ("GMEM DUMP" & ASCII.LF, 10, 1, Gmemfile);
kono
parents:
diff changeset
310 fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
311 Gmemfile);
kono
parents:
diff changeset
312 end if;
kono
parents:
diff changeset
313 end Gmem_Initialize;
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 -------------
kono
parents:
diff changeset
316 -- Realloc --
kono
parents:
diff changeset
317 -------------
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 function Realloc
kono
parents:
diff changeset
320 (Ptr : System.Address;
kono
parents:
diff changeset
321 Size : size_t) return System.Address
kono
parents:
diff changeset
322 is
kono
parents:
diff changeset
323 Addr : aliased constant System.Address := Ptr;
kono
parents:
diff changeset
324 Result : aliased System.Address;
kono
parents:
diff changeset
325 Timestamp : aliased Duration;
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 begin
kono
parents:
diff changeset
328 -- For the purposes of allocations logging, we treat realloc as a free
kono
parents:
diff changeset
329 -- followed by malloc. This is not exactly accurate, but is a good way
kono
parents:
diff changeset
330 -- to fit it into malloc/free-centered reports.
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 if Size = size_t'Last then
kono
parents:
diff changeset
333 Raise_Exception (Storage_Error'Identity, "object too large");
kono
parents:
diff changeset
334 end if;
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 Abort_Defer.all;
kono
parents:
diff changeset
337 Lock_Task.all;
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 if First_Call then
kono
parents:
diff changeset
340 First_Call := False;
kono
parents:
diff changeset
341
kono
parents:
diff changeset
342 -- We first log deallocation call
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 if Needs_Init then
kono
parents:
diff changeset
345 Gmem_Initialize;
kono
parents:
diff changeset
346 end if;
kono
parents:
diff changeset
347 Call_Chain
kono
parents:
diff changeset
348 (Tracebk, Max_Call_Stack, Num_Calls, Skip_Frames => 2);
kono
parents:
diff changeset
349 Timestamp := System.OS_Primitives.Clock;
kono
parents:
diff changeset
350 fputc (Character'Pos ('D'), Gmemfile);
kono
parents:
diff changeset
351 fwrite (Addr'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
352 fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
353 Gmemfile);
kono
parents:
diff changeset
354 fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
355 Gmemfile);
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 for J in Tracebk'First .. Tracebk'First + Num_Calls - 1 loop
kono
parents:
diff changeset
358 declare
kono
parents:
diff changeset
359 Ptr : System.Address := PC_For (Tracebk (J));
kono
parents:
diff changeset
360 begin
kono
parents:
diff changeset
361 fwrite (Ptr'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
362 end;
kono
parents:
diff changeset
363 end loop;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 -- Now perform actual realloc
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 Result := c_realloc (Ptr, Size);
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 -- Log allocation call using the same backtrace
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 fputc (Character'Pos ('A'), Gmemfile);
kono
parents:
diff changeset
372 fwrite (Result'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
373 fwrite (Size'Address, size_t'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
374 Gmemfile);
kono
parents:
diff changeset
375 fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
376 Gmemfile);
kono
parents:
diff changeset
377 fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
kono
parents:
diff changeset
378 Gmemfile);
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 for J in Tracebk'First .. Tracebk'First + Num_Calls - 1 loop
kono
parents:
diff changeset
381 declare
kono
parents:
diff changeset
382 Ptr : System.Address := PC_For (Tracebk (J));
kono
parents:
diff changeset
383 begin
kono
parents:
diff changeset
384 fwrite (Ptr'Address, Address_Size, 1, Gmemfile);
kono
parents:
diff changeset
385 end;
kono
parents:
diff changeset
386 end loop;
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 First_Call := True;
kono
parents:
diff changeset
389 end if;
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 Unlock_Task.all;
kono
parents:
diff changeset
392 Abort_Undefer.all;
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 if Result = System.Null_Address then
kono
parents:
diff changeset
395 Raise_Exception (Storage_Error'Identity, "heap exhausted");
kono
parents:
diff changeset
396 end if;
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 return Result;
kono
parents:
diff changeset
399 end Realloc;
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 end System.Memory;