Commit 8cc39ff2 by Vasiliy Fofanov Committed by Arnaud Charlet

gmem.c: Add support for timestamps on memory operations.

2007-04-20  Vasiliy Fofanov  <fofanov@adacore.com>

	* gmem.c: Add support for timestamps on memory operations.

	* memtrack.adb, gnatmem.adb: Add support for timestamps on memory
	operations (not used currently, just foundation for future
	enhancements). Add possibility to perform full dump of gmem.out file.
	(Print_Back_Traces): Declare accesses to root arrays constants since
	they aren't modified.
	(Print_Back_Traces): allocate root arrays on the heap rather than stack.

From-SVN: r125419
parent 9fd79385
......@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
* Copyright (C) 2000-2006, Free Software Foundation, Inc. *
* Copyright (C) 2000-2007, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
......@@ -31,7 +31,7 @@
****************************************************************************/
/* This unit reads the allocation tracking log produced by augmented
__gnat_malloc and __gnat_free procedures (see file a-raise.c) and
__gnat_malloc and __gnat_free procedures (see file memtrack.adb) and
provides GNATMEM tool with gdb-compliant output. The output is
processed by GNATMEM to detect dynamic memory allocation errors.
......@@ -43,9 +43,11 @@
GNU/Linux x86
Solaris (sparc and x86) (*)
Windows 98/95/NT (x86)
Alpha OpenVMS
(*) on these targets, the compilation must be done with -funwind-tables to
be able to build the stack backtrace.
*/
#include <stdio.h>
......@@ -65,6 +67,7 @@ struct struct_storage_elmt {
char Elmt;
void * Address;
size_t Size;
long long Timestamp;
};
static void
......@@ -108,14 +111,15 @@ gmem_read_backtrace (void)
cur_tb_pos = 0;
}
/* initialize gmem feature from the dumpname file. It returns 1 if the
dumpname has been generated by GMEM (instrumented malloc/free) and 0 if not
(i.e. probably a GDB generated file).
/* initialize gmem feature from the dumpname file. It returns t0 timestamp
if the dumpname has been generated by GMEM (instrumented malloc/free)
and 0 if not.
*/
int __gnat_gmem_initialize (char *dumpname)
long long __gnat_gmem_initialize (char *dumpname)
{
char header [10];
long long t0;
gmemfile = fopen (dumpname, "rb");
fread (header, 10, 1, gmemfile);
......@@ -127,7 +131,9 @@ int __gnat_gmem_initialize (char *dumpname)
return 0;
}
return 1;
fread (&t0, sizeof (long long), 1, gmemfile);
return t0;
}
/* initialize addr2line library */
......@@ -163,10 +169,12 @@ __gnat_gmem_read_next (struct struct_storage_elmt *buf)
buf->Elmt = LOG_ALLOC;
fread (&(buf->Address), sizeof (void *), 1, gmemfile);
fread (&(buf->Size), sizeof (size_t), 1, gmemfile);
fread (&(buf->Timestamp), sizeof (long long), 1, gmemfile);
break;
case 'D' :
buf->Elmt = LOG_DEALL;
fread (&(buf->Address), sizeof (void *), 1, gmemfile);
fread (&(buf->Timestamp), sizeof (long long), 1, gmemfile);
break;
default:
puts ("GNATMEM dump file corrupt");
......
......@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
-- Copyright (C) 2001-2005 Free Software Foundation, Inc. --
-- Copyright (C) 2001-2007, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
......@@ -64,6 +64,12 @@
-- Irix
-- Solaris
-- Tru64
-- Alpha OpenVMS
-- NOTE FOR FUTURE PLATFORMS SUPPORT: It is assumed that type Duration is
-- 64 bit. If the need arises to support architectures where this assumption
-- is incorrect, it will require changing the way timestamps of allocation
-- events are recorded.
pragma Source_File_Name (System.Memory, Body_File_Name => "memtrack.adb");
......@@ -72,6 +78,7 @@ with System.Soft_Links;
with System.Traceback;
with System.Traceback_Entries;
with GNAT.IO;
with System.OS_Primitives;
package body System.Memory is
......@@ -140,6 +147,9 @@ package body System.Memory is
Gmemfile : File_Ptr;
-- Global C file pointer to the allocation log
Needs_Init : Boolean := True;
-- Reset after first call to Gmem_Initialize
procedure Gmem_Initialize;
-- Initialization routine; opens the file and writes a header string. This
-- header string is used as a magic-tag to know if the .out file is to be
......@@ -157,6 +167,7 @@ package body System.Memory is
function Alloc (Size : size_t) return System.Address is
Result : aliased System.Address;
Actual_Size : aliased size_t := Size;
Timestamp : aliased Duration;
begin
if Size = size_t'Last then
......@@ -184,13 +195,19 @@ package body System.Memory is
First_Call := False;
Gmem_Initialize;
if Needs_Init then
Gmem_Initialize;
end if;
Timestamp := System.OS_Primitives.Clock;
Call_Chain (Tracebk'Address, Max_Call_Stack, Num_Calls,
Skip_Frames => 2);
fputc (Character'Pos ('A'), Gmemfile);
fwrite (Result'Address, Address_Size, 1, Gmemfile);
fwrite (Actual_Size'Address, size_t'Max_Size_In_Storage_Elements, 1,
Gmemfile);
fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
Gmemfile);
fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
Gmemfile);
......@@ -219,9 +236,6 @@ package body System.Memory is
-- Finalize --
--------------
Needs_Init : Boolean := True;
-- Reset after first call to Gmem_Initialize
procedure Finalize is
begin
if not Needs_Init then
......@@ -234,7 +248,8 @@ package body System.Memory is
----------
procedure Free (Ptr : System.Address) is
Addr : aliased constant System.Address := Ptr;
Addr : aliased constant System.Address := Ptr;
Timestamp : aliased Duration;
begin
Lock_Task.all;
......@@ -247,11 +262,17 @@ package body System.Memory is
First_Call := False;
Gmem_Initialize;
if Needs_Init then
Gmem_Initialize;
end if;
Call_Chain (Tracebk'Address, Max_Call_Stack, Num_Calls,
Skip_Frames => 2);
Timestamp := System.OS_Primitives.Clock;
fputc (Character'Pos ('D'), Gmemfile);
fwrite (Addr'Address, Address_Size, 1, Gmemfile);
fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
Gmemfile);
fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
Gmemfile);
......@@ -276,9 +297,13 @@ package body System.Memory is
---------------------
procedure Gmem_Initialize is
Timestamp : aliased Duration;
begin
if Needs_Init then
Needs_Init := False;
System.OS_Primitives.Initialize;
Timestamp := System.OS_Primitives.Clock;
Gmemfile := fopen (Gmemfname, "wb" & ASCII.NUL);
if Gmemfile = System.Null_Address then
......@@ -287,6 +312,8 @@ package body System.Memory is
end if;
fwrite ("GMEM DUMP" & ASCII.LF, 10, 1, Gmemfile);
fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
Gmemfile);
end if;
end Gmem_Initialize;
......@@ -295,10 +322,12 @@ package body System.Memory is
-------------
function Realloc
(Ptr : System.Address; Size : size_t) return System.Address
(Ptr : System.Address;
Size : size_t) return System.Address
is
Addr : aliased constant System.Address := Ptr;
Result : aliased System.Address;
Addr : aliased constant System.Address := Ptr;
Result : aliased System.Address;
Timestamp : aliased Duration;
begin
-- For the purposes of allocations logging, we treat realloc as a free
......@@ -317,11 +346,16 @@ package body System.Memory is
-- We first log deallocation call
Gmem_Initialize;
if Needs_Init then
Gmem_Initialize;
end if;
Call_Chain (Tracebk'Address, Max_Call_Stack, Num_Calls,
Skip_Frames => 2);
Timestamp := System.OS_Primitives.Clock;
fputc (Character'Pos ('D'), Gmemfile);
fwrite (Addr'Address, Address_Size, 1, Gmemfile);
fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
Gmemfile);
fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
Gmemfile);
......@@ -343,6 +377,8 @@ package body System.Memory is
fwrite (Result'Address, Address_Size, 1, Gmemfile);
fwrite (Size'Address, size_t'Max_Size_In_Storage_Elements, 1,
Gmemfile);
fwrite (Timestamp'Address, Duration'Max_Size_In_Storage_Elements, 1,
Gmemfile);
fwrite (Num_Calls'Address, Integer'Max_Size_In_Storage_Elements, 1,
Gmemfile);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment