diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-27 13:56:19 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-27 13:56:19 +0000 |
commit | fb8cddab45b070d302c62f4d4e2d1c01f29c89d8 (patch) | |
tree | 15153eba8be51ec43a9e0a2ffcc89dfc446ed6ae /gcc/ada/gnat_ugn.texi | |
parent | 8c3828db106ca2bf4289d30d8c147c9f005ac1ce (diff) | |
download | gcc-fb8cddab45b070d302c62f4d4e2d1c01f29c89d8.tar.gz |
2004-10-26 Cyrille Comar <comar@act-europe.fr>
Vasiliy Fofanov <fofanov@act-europe.fr>
Vincent Celier <celier@gnat.com>
* gnat_ugn.texi: Generalize "finding memory problems" section into a
"memory management issues" section and document some of the useful
memory pools provided as part of the GNAT library.
Remove "virtual" from declaration of A::method2 in
the simple example of Ada/C++ mixed system.
Library Projects may be virtually extended: their virtual extensions
are not Library Projects.
Added section on extending project hierarchies.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89678 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/gnat_ugn.texi')
-rw-r--r-- | gcc/ada/gnat_ugn.texi | 472 |
1 files changed, 309 insertions, 163 deletions
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index c8da0d86467..4b2c00a131a 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -187,7 +187,7 @@ Ada Core Technologies, Inc.@* * GNAT and Libraries:: * Using the GNU make Utility:: @end ifclear -* Finding Memory Problems:: +* Memory Management Issues:: * Creating Sample Bodies Using gnatstub:: * Other Utility Programs:: * Running and Debugging Ada Programs:: @@ -368,6 +368,7 @@ GNAT Project Manager * Objects and Sources in Project Files:: * Importing Projects:: * Project Extension:: +* Project Hierarchy Extension:: * External References in Project Files:: * Packages in Project Files:: * Variables from Imported Projects:: @@ -445,12 +446,17 @@ Using the GNU make Utility * Overcoming Command Line Length Limits:: @end ifclear -Finding Memory Problems +Memory Management Issues +* Some Useful Memory Pools:: +* The GNAT Debug Pool Facility:: @ifclear vms * The gnatmem Tool:: @end ifclear -* The GNAT Debug Pool Facility:: + +Some Useful Memory Pools + +The GNAT Debug Pool Facility @ifclear vms The gnatmem Tool @@ -460,9 +466,7 @@ The gnatmem Tool * Example of gnatmem Usage:: @end ifclear -The GNAT Debug Pool Facility - -Creating Sample Bodies Using gnatstub + Sample Bodies Using gnatstub * Running gnatstub:: * Switches for gnatstub:: @@ -758,12 +762,13 @@ the GNAT toolset in Makefiles. @end ifclear @item -@ref{Finding Memory Problems}, describes +@ref{Memory Management Issues}, describes some useful predefined storage pools +and in particular the GNAT Debug Pool facility, which helps detect incorrect +memory references. @ifclear vms -@command{gnatmem}, a utility that monitors dynamic allocation and deallocation -and helps detect ``memory leaks'', and +It also describes @command{gnatmem}, a utility that monitors dynamic +allocation and deallocation and helps detect ``memory leaks''. @end ifclear -the GNAT Debug Pool facility, which helps detect incorrect memory references. @item @ref{Creating Sample Bodies Using gnatstub}, discusses @code{gnatstub}, @@ -3258,7 +3263,7 @@ class Origin @{ class A : public Origin @{ public: void method1 (void); - virtual void method2 (int v); + void method2 (int v); A(); int a_value; @}; @@ -10286,6 +10291,7 @@ are used in this example. * Objects and Sources in Project Files:: * Importing Projects:: * Project Extension:: +* Project Hierarchy Extension:: * External References in Project Files:: * Packages in Project Files:: * Variables from Imported Projects:: @@ -12030,6 +12036,78 @@ projects. A project is not allowed to import directly or indirectly at the same time a child project and any of its ancestors. +@c ******************************* +@c * Project Hierarchy Extension * +@c ******************************* + +@node Project Hierarchy Extension +@section Project Hierarchy Extension + +@noindent +When extending a large system spanning multiple projects, it is often +inconvenient to extend every project in the hierarchy that is impacted by a +small change introduced. In such cases, it is possible to create a virtual +extension of entire hierarchy using @code{extends all} relationship. + +When the project is extended using @code{extends all} inheritance, all projects +that are imported by it, both directly and indirectly, are considered virtually +extended. That is, the Project Manager creates "virtual projects" +that extend every project in the hierarchy; all these virtual projects have +no sources of their own and have as object directory the object directory of +the root of "extending all" project. + +It is possible to explicitly extend one or more projects in the hierarchy +in order to modify the sources. These extending projects must be imported by +the "extending all" project, which will replace the corresponding virtual +projects with the explicit ones. + +When building such a project hierarchy extension, the Project Manager will +ensure that both modified sources and sources in virtual extending projects +that depend on them, are recompiled. + +By means of example, consider the following hierarchy of projects. + +@enumerate +@item +project A, containing package P1 +@item +project B importing A and containing package P2 which depends on P1 +@item +project C importing B and containing package P3 which depends on P2 +@end enumerate + +@noindent +We want to modify packages P1 and P3. + +This project hierarchy will need to be extended as follows: + +@enumerate +@item +Create project A1 that extends A, placing modified P1 there: + +@smallexample @c 0projectfile +project A1 extends "(...)/A" is +end A1; +@end smallexample + +@item +Create project C1 that "extends all" C and imports A1, placing modified +P3 there: + +@smallexample @c 0projectfile +with "(...)/A1"; +project C1 extends all "(...)/C" is +end C1; +@end smallexample +@end enumerate + +When you build project C1, your entire modified project space will be +recompiled, including the virtual project B1 that has been impacted by the +"extending all" inheritance of project C. + +Note that if a Library Project in the hierarchy is virtually extended, +the virtual project that extends the Library Project is not a Library Project. + @c **************************************** @c * External References in Project Files * @c **************************************** @@ -17137,25 +17215,237 @@ all: @end smallexample @end ifclear -@node Finding Memory Problems -@chapter Finding Memory Problems +@node Memory Management Issues +@chapter Memory Management Issues @noindent -This chapter describes +This chapter describes some useful memory pools provided in the GNAT library +and in particular the GNAT Debug Pool facility, which can be used to detect +incorrect uses of access values (including ``dangling references''). @ifclear vms -the @command{gnatmem} tool, which can be used to track down -``memory leaks'', and +It also describes the @command{gnatmem} tool, which can be used to track down +``memory leaks''. @end ifclear -the GNAT Debug Pool facility, which can be used to detect incorrect uses of -access values (including ``dangling references''). @menu +* Some Useful Memory Pools:: +* The GNAT Debug Pool Facility:: @ifclear vms * The gnatmem Tool:: @end ifclear -* The GNAT Debug Pool Facility:: @end menu +@node Some Useful Memory Pools +@section Some Useful Memory Pools +@findex Memory Pool +@cindex storage, pool + +@noindent +The @code{System.Pool_Global} package offers the Unbounded_No_Reclaim_Pool +storage pool. Allocations use the standard system call @code{malloc} while +deallocations use the standard system call @code{free}. No reclamation is +performed when the pool goes out of scope. For performance reasons, the +standard default Ada allocators/deallocators do not use any explicit storage +pools but if they did, they could use this storage pool without any change in +behavior. That is why this storage pool is used when the user +manages to make the default implicit allocator explicit as in this example: +@smallexample @c ada + type T1 is access Something; + -- no Storage pool is defined for T2 + type T2 is access Something_Else; + for T2'Storage_Pool use T1'Storage_Pool; + -- the above is equivalent to + for T2'Storage_Pool use System.Pool_Global.Global_Pool_Object; +@end smallexample + +@noindent +The @code{System.Pool_Local} package offers the Unbounded_Reclaim_Pool storage +pool. The allocation strategy is similar to @code{Pool_Local}'s +except that the all +storage allocated with this pool is reclaimed when the pool object goes out of +scope. This pool provides a explicit mechanism similar to the implicit one +provided by several Ada 83 compilers for allocations performed through a local +access type and whose purpose was to reclaim memory when exiting the +scope of a given local access. As an example, the following program does not +leak memory even though it does not perform explicit deallocation: + +@smallexample @c ada +with System.Pool_Local; +procedure Pooloc1 is + procedure Internal is + type A is access Integer; + X : System.Pool_Local.Unbounded_Reclaim_Pool; + for A'Storage_Pool use X; + v : A; + begin + for I in 1 .. 50 loop + v := new Integer; + end loop; + end Internal; +begin + for I in 1 .. 100 loop + Internal; + end loop; +end Pooloc1; +@end smallexample + +@noindent +The @code{System.Pool_Size} package implements the Stack_Bounded_Pool used when +@code{Storage_Size} is specified for an access type. +The whole storage for the pool is +allocated at once, usually on the stack at the point where the access type is +elaborated. It is automatically reclaimed when exiting the scope where the +access type is defined. This package is not intended to be used directly by the +user and it is implicitly used for each such declaration: + +@smallexample @c ada + type T1 is access Something; + for T1'Storage_Size use 10_000; +@end smallexample + + +@node The GNAT Debug Pool Facility +@section The GNAT Debug Pool Facility +@findex Debug Pool +@cindex storage, pool, memory corruption + +@noindent +The use of unchecked deallocation and unchecked conversion can easily +lead to incorrect memory references. The problems generated by such +references are usually difficult to tackle because the symptoms can be +very remote from the origin of the problem. In such cases, it is +very helpful to detect the problem as early as possible. This is the +purpose of the Storage Pool provided by @code{GNAT.Debug_Pools}. + +In order to use the GNAT specific debugging pool, the user must +associate a debug pool object with each of the access types that may be +related to suspected memory problems. See Ada Reference Manual 13.11. +@smallexample @c ada +type Ptr is access Some_Type; +Pool : GNAT.Debug_Pools.Debug_Pool; +for Ptr'Storage_Pool use Pool; +@end smallexample + +@noindent +@code{GNAT.Debug_Pools} is derived from a GNAT-specific kind of +pool: the @code{Checked_Pool}. Such pools, like standard Ada storage pools, +allow the user to redefine allocation and deallocation strategies. They +also provide a checkpoint for each dereference, through the use of +the primitive operation @code{Dereference} which is implicitly called at +each dereference of an access value. + +Once an access type has been associated with a debug pool, operations on +values of the type may raise four distinct exceptions, +which correspond to four potential kinds of memory corruption: +@itemize @bullet +@item +@code{GNAT.Debug_Pools.Accessing_Not_Allocated_Storage} +@item +@code{GNAT.Debug_Pools.Accessing_Deallocated_Storage} +@item +@code{GNAT.Debug_Pools.Freeing_Not_Allocated_Storage} +@item +@code{GNAT.Debug_Pools.Freeing_Deallocated_Storage } +@end itemize + +@noindent +For types associated with a Debug_Pool, dynamic allocation is performed using +the standard GNAT allocation routine. References to all allocated chunks of +memory are kept in an internal dictionary. Several deallocation strategies are +provided, whereupon the user can choose to release the memory to the system, +keep it allocated for further invalid access checks, or fill it with an easily +recognizable pattern for debug sessions. The memory pattern is the old IBM +hexadecimal convention: @code{16#DEADBEEF#}. + +See the documentation in the file g-debpoo.ads for more information on the +various strategies. + +Upon each dereference, a check is made that the access value denotes a +properly allocated memory location. Here is a complete example of use of +@code{Debug_Pools}, that includes typical instances of memory corruption: +@smallexample @c ada +@iftex +@leftskip=0cm +@end iftex +with Gnat.Io; use Gnat.Io; +with Unchecked_Deallocation; +with Unchecked_Conversion; +with GNAT.Debug_Pools; +with System.Storage_Elements; +with Ada.Exceptions; use Ada.Exceptions; +procedure Debug_Pool_Test is + + type T is access Integer; + type U is access all T; + + P : GNAT.Debug_Pools.Debug_Pool; + for T'Storage_Pool use P; + + procedure Free is new Unchecked_Deallocation (Integer, T); + function UC is new Unchecked_Conversion (U, T); + A, B : aliased T; + + procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line); + +begin + Info (P); + A := new Integer; + B := new Integer; + B := A; + Info (P); + Free (A); + begin + Put_Line (Integer'Image(B.all)); + exception + when E : others => Put_Line ("raised: " & Exception_Name (E)); + end; + begin + Free (B); + exception + when E : others => Put_Line ("raised: " & Exception_Name (E)); + end; + B := UC(A'Access); + begin + Put_Line (Integer'Image(B.all)); + exception + when E : others => Put_Line ("raised: " & Exception_Name (E)); + end; + begin + Free (B); + exception + when E : others => Put_Line ("raised: " & Exception_Name (E)); + end; + Info (P); +end Debug_Pool_Test; +@end smallexample + +@noindent +The debug pool mechanism provides the following precise diagnostics on the +execution of this erroneous program: +@smallexample +Debug Pool info: + Total allocated bytes : 0 + Total deallocated bytes : 0 + Current Water Mark: 0 + High Water Mark: 0 + +Debug Pool info: + Total allocated bytes : 8 + Total deallocated bytes : 0 + Current Water Mark: 8 + High Water Mark: 8 + +raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE +raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE +raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE +raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE +Debug Pool info: + Total allocated bytes : 8 + Total deallocated bytes : 4 + Current Water Mark: 4 + High Water Mark: 8 +@end smallexample + @ifclear vms @node The gnatmem Tool @section The @command{gnatmem} Tool @@ -17498,150 +17788,6 @@ and #3 thanks to the more precise associated backtrace. @end ifclear -@node The GNAT Debug Pool Facility -@section The GNAT Debug Pool Facility -@findex Debug Pool -@cindex storage, pool, memory corruption - -@noindent -The use of unchecked deallocation and unchecked conversion can easily -lead to incorrect memory references. The problems generated by such -references are usually difficult to tackle because the symptoms can be -very remote from the origin of the problem. In such cases, it is -very helpful to detect the problem as early as possible. This is the -purpose of the Storage Pool provided by @code{GNAT.Debug_Pools}. - -In order to use the GNAT specific debugging pool, the user must -associate a debug pool object with each of the access types that may be -related to suspected memory problems. See Ada Reference Manual 13.11. -@smallexample @c ada -type Ptr is access Some_Type; -Pool : GNAT.Debug_Pools.Debug_Pool; -for Ptr'Storage_Pool use Pool; -@end smallexample - -@noindent -@code{GNAT.Debug_Pools} is derived from a GNAT-specific kind of -pool: the @code{Checked_Pool}. Such pools, like standard Ada storage pools, -allow the user to redefine allocation and deallocation strategies. They -also provide a checkpoint for each dereference, through the use of -the primitive operation @code{Dereference} which is implicitly called at -each dereference of an access value. - -Once an access type has been associated with a debug pool, operations on -values of the type may raise four distinct exceptions, -which correspond to four potential kinds of memory corruption: -@itemize @bullet -@item -@code{GNAT.Debug_Pools.Accessing_Not_Allocated_Storage} -@item -@code{GNAT.Debug_Pools.Accessing_Deallocated_Storage} -@item -@code{GNAT.Debug_Pools.Freeing_Not_Allocated_Storage} -@item -@code{GNAT.Debug_Pools.Freeing_Deallocated_Storage } -@end itemize - -@noindent -For types associated with a Debug_Pool, dynamic allocation is performed using -the standard -GNAT allocation routine. References to all allocated chunks of memory -are kept in an internal dictionary. -Several deallocation strategies are provided, whereupon the user can choose -to release the memory to the system, keep it allocated for further invalid -access checks, or fill it with an easily recognizable pattern for debug -sessions. -The memory pattern is the old IBM hexadecimal convention: @code{16#DEADBEEF#}. - -See the documentation in the file g-debpoo.ads for more information on the -various strategies. - -Upon each dereference, a check is made that the access value denotes a -properly allocated memory location. Here is a complete example of use of -@code{Debug_Pools}, that includes typical instances of memory corruption: -@smallexample @c ada -@iftex -@leftskip=0cm -@end iftex -with Gnat.Io; use Gnat.Io; -with Unchecked_Deallocation; -with Unchecked_Conversion; -with GNAT.Debug_Pools; -with System.Storage_Elements; -with Ada.Exceptions; use Ada.Exceptions; -procedure Debug_Pool_Test is - - type T is access Integer; - type U is access all T; - - P : GNAT.Debug_Pools.Debug_Pool; - for T'Storage_Pool use P; - - procedure Free is new Unchecked_Deallocation (Integer, T); - function UC is new Unchecked_Conversion (U, T); - A, B : aliased T; - - procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line); - -begin - Info (P); - A := new Integer; - B := new Integer; - B := A; - Info (P); - Free (A); - begin - Put_Line (Integer'Image(B.all)); - exception - when E : others => Put_Line ("raised: " & Exception_Name (E)); - end; - begin - Free (B); - exception - when E : others => Put_Line ("raised: " & Exception_Name (E)); - end; - B := UC(A'Access); - begin - Put_Line (Integer'Image(B.all)); - exception - when E : others => Put_Line ("raised: " & Exception_Name (E)); - end; - begin - Free (B); - exception - when E : others => Put_Line ("raised: " & Exception_Name (E)); - end; - Info (P); -end Debug_Pool_Test; -@end smallexample - -@noindent -The debug pool mechanism provides the following precise diagnostics on the -execution of this erroneous program: -@smallexample -Debug Pool info: - Total allocated bytes : 0 - Total deallocated bytes : 0 - Current Water Mark: 0 - High Water Mark: 0 - -Debug Pool info: - Total allocated bytes : 8 - Total deallocated bytes : 0 - Current Water Mark: 8 - High Water Mark: 8 - -raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE -raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE -raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE -raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE -Debug Pool info: - Total allocated bytes : 8 - Total deallocated bytes : 4 - Current Water Mark: 4 - High Water Mark: 8 -@end smallexample - @node Creating Sample Bodies Using gnatstub @chapter Creating Sample Bodies Using @command{gnatstub} @findex gnatstub |