aboutsummaryrefslogtreecommitdiff
path: root/manual/memory.texi
diff options
context:
space:
mode:
Diffstat (limited to 'manual/memory.texi')
-rw-r--r--manual/memory.texi3504
1 files changed, 0 insertions, 3504 deletions
diff --git a/manual/memory.texi b/manual/memory.texi
deleted file mode 100644
index fb6b594ef1..0000000000
--- a/manual/memory.texi
+++ /dev/null
@@ -1,3504 +0,0 @@
-@node Memory, Character Handling, Error Reporting, Top
-@chapter Virtual Memory Allocation And Paging
-@c %MENU% Allocating virtual memory and controlling paging
-@cindex memory allocation
-@cindex storage allocation
-
-This chapter describes how processes manage and use memory in a system
-that uses @theglibc{}.
-
-@Theglibc{} has several functions for dynamically allocating
-virtual memory in various ways. They vary in generality and in
-efficiency. The library also provides functions for controlling paging
-and allocation of real memory.
-
-
-@menu
-* Memory Concepts:: An introduction to concepts and terminology.
-* Memory Allocation:: Allocating storage for your program data
-* Resizing the Data Segment:: @code{brk}, @code{sbrk}
-* Locking Pages:: Preventing page faults
-@end menu
-
-Memory mapped I/O is not discussed in this chapter. @xref{Memory-mapped I/O}.
-
-
-
-@node Memory Concepts
-@section Process Memory Concepts
-
-One of the most basic resources a process has available to it is memory.
-There are a lot of different ways systems organize memory, but in a
-typical one, each process has one linear virtual address space, with
-addresses running from zero to some huge maximum. It need not be
-contiguous; i.e., not all of these addresses actually can be used to
-store data.
-
-The virtual memory is divided into pages (4 kilobytes is typical).
-Backing each page of virtual memory is a page of real memory (called a
-@dfn{frame}) or some secondary storage, usually disk space. The disk
-space might be swap space or just some ordinary disk file. Actually, a
-page of all zeroes sometimes has nothing at all backing it -- there's
-just a flag saying it is all zeroes.
-@cindex page frame
-@cindex frame, real memory
-@cindex swap space
-@cindex page, virtual memory
-
-The same frame of real memory or backing store can back multiple virtual
-pages belonging to multiple processes. This is normally the case, for
-example, with virtual memory occupied by @glibcadj{} code. The same
-real memory frame containing the @code{printf} function backs a virtual
-memory page in each of the existing processes that has a @code{printf}
-call in its program.
-
-In order for a program to access any part of a virtual page, the page
-must at that moment be backed by (``connected to'') a real frame. But
-because there is usually a lot more virtual memory than real memory, the
-pages must move back and forth between real memory and backing store
-regularly, coming into real memory when a process needs to access them
-and then retreating to backing store when not needed anymore. This
-movement is called @dfn{paging}.
-
-When a program attempts to access a page which is not at that moment
-backed by real memory, this is known as a @dfn{page fault}. When a page
-fault occurs, the kernel suspends the process, places the page into a
-real page frame (this is called ``paging in'' or ``faulting in''), then
-resumes the process so that from the process' point of view, the page
-was in real memory all along. In fact, to the process, all pages always
-seem to be in real memory. Except for one thing: the elapsed execution
-time of an instruction that would normally be a few nanoseconds is
-suddenly much, much, longer (because the kernel normally has to do I/O
-to complete the page-in). For programs sensitive to that, the functions
-described in @ref{Locking Pages} can control it.
-@cindex page fault
-@cindex paging
-
-Within each virtual address space, a process has to keep track of what
-is at which addresses, and that process is called memory allocation.
-Allocation usually brings to mind meting out scarce resources, but in
-the case of virtual memory, that's not a major goal, because there is
-generally much more of it than anyone needs. Memory allocation within a
-process is mainly just a matter of making sure that the same byte of
-memory isn't used to store two different things.
-
-Processes allocate memory in two major ways: by exec and
-programmatically. Actually, forking is a third way, but it's not very
-interesting. @xref{Creating a Process}.
-
-Exec is the operation of creating a virtual address space for a process,
-loading its basic program into it, and executing the program. It is
-done by the ``exec'' family of functions (e.g. @code{execl}). The
-operation takes a program file (an executable), it allocates space to
-load all the data in the executable, loads it, and transfers control to
-it. That data is most notably the instructions of the program (the
-@dfn{text}), but also literals and constants in the program and even
-some variables: C variables with the static storage class (@pxref{Memory
-Allocation and C}).
-@cindex executable
-@cindex literals
-@cindex constants
-
-Once that program begins to execute, it uses programmatic allocation to
-gain additional memory. In a C program with @theglibc{}, there
-are two kinds of programmatic allocation: automatic and dynamic.
-@xref{Memory Allocation and C}.
-
-Memory-mapped I/O is another form of dynamic virtual memory allocation.
-Mapping memory to a file means declaring that the contents of certain
-range of a process' addresses shall be identical to the contents of a
-specified regular file. The system makes the virtual memory initially
-contain the contents of the file, and if you modify the memory, the
-system writes the same modification to the file. Note that due to the
-magic of virtual memory and page faults, there is no reason for the
-system to do I/O to read the file, or allocate real memory for its
-contents, until the program accesses the virtual memory.
-@xref{Memory-mapped I/O}.
-@cindex memory mapped I/O
-@cindex memory mapped file
-@cindex files, accessing
-
-Just as it programmatically allocates memory, the program can
-programmatically deallocate (@dfn{free}) it. You can't free the memory
-that was allocated by exec. When the program exits or execs, you might
-say that all its memory gets freed, but since in both cases the address
-space ceases to exist, the point is really moot. @xref{Program
-Termination}.
-@cindex execing a program
-@cindex freeing memory
-@cindex exiting a program
-
-A process' virtual address space is divided into segments. A segment is
-a contiguous range of virtual addresses. Three important segments are:
-
-@itemize @bullet
-
-@item
-
-The @dfn{text segment} contains a program's instructions and literals and
-static constants. It is allocated by exec and stays the same size for
-the life of the virtual address space.
-
-@item
-The @dfn{data segment} is working storage for the program. It can be
-preallocated and preloaded by exec and the process can extend or shrink
-it by calling functions as described in @xref{Resizing the Data
-Segment}. Its lower end is fixed.
-
-@item
-The @dfn{stack segment} contains a program stack. It grows as the stack
-grows, but doesn't shrink when the stack shrinks.
-
-@end itemize
-
-
-
-@node Memory Allocation
-@section Allocating Storage For Program Data
-
-This section covers how ordinary programs manage storage for their data,
-including the famous @code{malloc} function and some fancier facilities
-special to @theglibc{} and GNU Compiler.
-
-@menu
-* Memory Allocation and C:: How to get different kinds of allocation in C.
-* The GNU Allocator:: An overview of the GNU @code{malloc}
- implementation.
-* Unconstrained Allocation:: The @code{malloc} facility allows fully general
- dynamic allocation.
-* Allocation Debugging:: Finding memory leaks and not freed memory.
-* Replacing malloc:: Using your own @code{malloc}-style allocator.
-* Obstacks:: Obstacks are less general than malloc
- but more efficient and convenient.
-* Variable Size Automatic:: Allocation of variable-sized blocks
- of automatic storage that are freed when the
- calling function returns.
-@end menu
-
-
-@node Memory Allocation and C
-@subsection Memory Allocation in C Programs
-
-The C language supports two kinds of memory allocation through the
-variables in C programs:
-
-@itemize @bullet
-@item
-@dfn{Static allocation} is what happens when you declare a static or
-global variable. Each static or global variable defines one block of
-space, of a fixed size. The space is allocated once, when your program
-is started (part of the exec operation), and is never freed.
-@cindex static memory allocation
-@cindex static storage class
-
-@item
-@dfn{Automatic allocation} happens when you declare an automatic
-variable, such as a function argument or a local variable. The space
-for an automatic variable is allocated when the compound statement
-containing the declaration is entered, and is freed when that
-compound statement is exited.
-@cindex automatic memory allocation
-@cindex automatic storage class
-
-In GNU C, the size of the automatic storage can be an expression
-that varies. In other C implementations, it must be a constant.
-@end itemize
-
-A third important kind of memory allocation, @dfn{dynamic allocation},
-is not supported by C variables but is available via @glibcadj{}
-functions.
-@cindex dynamic memory allocation
-
-@subsubsection Dynamic Memory Allocation
-@cindex dynamic memory allocation
-
-@dfn{Dynamic memory allocation} is a technique in which programs
-determine as they are running where to store some information. You need
-dynamic allocation when the amount of memory you need, or how long you
-continue to need it, depends on factors that are not known before the
-program runs.
-
-For example, you may need a block to store a line read from an input
-file; since there is no limit to how long a line can be, you must
-allocate the memory dynamically and make it dynamically larger as you
-read more of the line.
-
-Or, you may need a block for each record or each definition in the input
-data; since you can't know in advance how many there will be, you must
-allocate a new block for each record or definition as you read it.
-
-When you use dynamic allocation, the allocation of a block of memory is
-an action that the program requests explicitly. You call a function or
-macro when you want to allocate space, and specify the size with an
-argument. If you want to free the space, you do so by calling another
-function or macro. You can do these things whenever you want, as often
-as you want.
-
-Dynamic allocation is not supported by C variables; there is no storage
-class ``dynamic'', and there can never be a C variable whose value is
-stored in dynamically allocated space. The only way to get dynamically
-allocated memory is via a system call (which is generally via a @glibcadj{}
-function call), and the only way to refer to dynamically
-allocated space is through a pointer. Because it is less convenient,
-and because the actual process of dynamic allocation requires more
-computation time, programmers generally use dynamic allocation only when
-neither static nor automatic allocation will serve.
-
-For example, if you want to allocate dynamically some space to hold a
-@code{struct foobar}, you cannot declare a variable of type @code{struct
-foobar} whose contents are the dynamically allocated space. But you can
-declare a variable of pointer type @code{struct foobar *} and assign it the
-address of the space. Then you can use the operators @samp{*} and
-@samp{->} on this pointer variable to refer to the contents of the space:
-
-@smallexample
-@{
- struct foobar *ptr
- = (struct foobar *) malloc (sizeof (struct foobar));
- ptr->name = x;
- ptr->next = current_foobar;
- current_foobar = ptr;
-@}
-@end smallexample
-
-@node The GNU Allocator
-@subsection The GNU Allocator
-@cindex gnu allocator
-
-The @code{malloc} implementation in @theglibc{} is derived from ptmalloc
-(pthreads malloc), which in turn is derived from dlmalloc (Doug Lea malloc).
-This malloc may allocate memory in two different ways depending on their size
-and certain parameters that may be controlled by users. The most common way is
-to allocate portions of memory (called chunks) from a large contiguous area of
-memory and manage these areas to optimize their use and reduce wastage in the
-form of unusable chunks. Traditionally the system heap was set up to be the one
-large memory area but the @glibcadj{} @code{malloc} implementation maintains
-multiple such areas to optimize their use in multi-threaded applications. Each
-such area is internally referred to as an @dfn{arena}.
-
-As opposed to other versions, the @code{malloc} in @theglibc{} does not round
-up chunk sizes to powers of two, neither for large nor for small sizes.
-Neighboring chunks can be coalesced on a @code{free} no matter what their size
-is. This makes the implementation suitable for all kinds of allocation
-patterns without generally incurring high memory waste through fragmentation.
-The presence of multiple arenas allows multiple threads to allocate
-memory simultaneously in separate arenas, thus improving performance.
-
-The other way of memory allocation is for very large blocks, i.e. much larger
-than a page. These requests are allocated with @code{mmap} (anonymous or via
-@file{/dev/zero}; @pxref{Memory-mapped I/O})). This has the great advantage
-that these chunks are returned to the system immediately when they are freed.
-Therefore, it cannot happen that a large chunk becomes ``locked'' in between
-smaller ones and even after calling @code{free} wastes memory. The size
-threshold for @code{mmap} to be used is dynamic and gets adjusted according to
-allocation patterns of the program. @code{mallopt} can be used to statically
-adjust the threshold using @code{M_MMAP_THRESHOLD} and the use of @code{mmap}
-can be disabled completely with @code{M_MMAP_MAX};
-@pxref{Malloc Tunable Parameters}.
-
-A more detailed technical description of the GNU Allocator is maintained in
-the @glibcadj{} wiki. See
-@uref{https://sourceware.org/glibc/wiki/MallocInternals}.
-
-It is possible to use your own custom @code{malloc} instead of the
-built-in allocator provided by @theglibc{}. @xref{Replacing malloc}.
-
-@node Unconstrained Allocation
-@subsection Unconstrained Allocation
-@cindex unconstrained memory allocation
-@cindex @code{malloc} function
-@cindex heap, dynamic allocation from
-
-The most general dynamic allocation facility is @code{malloc}. It
-allows you to allocate blocks of memory of any size at any time, make
-them bigger or smaller at any time, and free the blocks individually at
-any time (or never).
-
-@menu
-* Basic Allocation:: Simple use of @code{malloc}.
-* Malloc Examples:: Examples of @code{malloc}. @code{xmalloc}.
-* Freeing after Malloc:: Use @code{free} to free a block you
- got with @code{malloc}.
-* Changing Block Size:: Use @code{realloc} to make a block
- bigger or smaller.
-* Allocating Cleared Space:: Use @code{calloc} to allocate a
- block and clear it.
-* Aligned Memory Blocks:: Allocating specially aligned memory.
-* Malloc Tunable Parameters:: Use @code{mallopt} to adjust allocation
- parameters.
-* Heap Consistency Checking:: Automatic checking for errors.
-* Hooks for Malloc:: You can use these hooks for debugging
- programs that use @code{malloc}.
-* Statistics of Malloc:: Getting information about how much
- memory your program is using.
-* Summary of Malloc:: Summary of @code{malloc} and related functions.
-@end menu
-
-@node Basic Allocation
-@subsubsection Basic Memory Allocation
-@cindex allocation of memory with @code{malloc}
-
-To allocate a block of memory, call @code{malloc}. The prototype for
-this function is in @file{stdlib.h}.
-@pindex stdlib.h
-
-@comment malloc.h stdlib.h
-@comment ISO
-@deftypefun {void *} malloc (size_t @var{size})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c Malloc hooks and __morecore pointers, as well as such parameters as
-@c max_n_mmaps and max_mmapped_mem, are accessed without guards, so they
-@c could pose a thread safety issue; in order to not declare malloc
-@c MT-unsafe, it's modifying the hooks and parameters while multiple
-@c threads are active that is regarded as unsafe. An arena's next field
-@c is initialized and never changed again, except for main_arena's,
-@c that's protected by list_lock; next_free is only modified while
-@c list_lock is held too. All other data members of an arena, as well
-@c as the metadata of the memory areas assigned to it, are only modified
-@c while holding the arena's mutex (fastbin pointers use catomic ops
-@c because they may be modified by free without taking the arena's
-@c lock). Some reassurance was needed for fastbins, for it wasn't clear
-@c how they were initialized. It turns out they are always
-@c zero-initialized: main_arena's, for being static data, and other
-@c arena's, for being just-mmapped memory.
-
-@c Leaking file descriptors and memory in case of cancellation is
-@c unavoidable without disabling cancellation, but the lock situation is
-@c a bit more complicated: we don't have fallback arenas for malloc to
-@c be safe to call from within signal handlers. Error-checking mutexes
-@c or trylock could enable us to try and use alternate arenas, even with
-@c -DPER_THREAD (enabled by default), but supporting interruption
-@c (cancellation or signal handling) while holding the arena list mutex
-@c would require more work; maybe blocking signals and disabling async
-@c cancellation while manipulating the arena lists?
-
-@c __libc_malloc @asulock @aculock @acsfd @acsmem
-@c force_reg ok
-@c *malloc_hook unguarded
-@c arena_lock @asulock @aculock @acsfd @acsmem
-@c mutex_lock @asulock @aculock
-@c arena_get2 @asulock @aculock @acsfd @acsmem
-@c get_free_list @asulock @aculock
-@c mutex_lock (list_lock) dup @asulock @aculock
-@c mutex_unlock (list_lock) dup @aculock
-@c mutex_lock (arena lock) dup @asulock @aculock [returns locked]
-@c __get_nprocs ext ok @acsfd
-@c NARENAS_FROM_NCORES ok
-@c catomic_compare_and_exchange_bool_acq ok
-@c _int_new_arena ok @asulock @aculock @acsmem
-@c new_heap ok @acsmem
-@c mmap ok @acsmem
-@c munmap ok @acsmem
-@c mprotect ok
-@c chunk2mem ok
-@c set_head ok
-@c tsd_setspecific dup ok
-@c mutex_init ok
-@c mutex_lock (just-created mutex) ok, returns locked
-@c mutex_lock (list_lock) dup @asulock @aculock
-@c atomic_write_barrier ok
-@c mutex_unlock (list_lock) @aculock
-@c catomic_decrement ok
-@c reused_arena @asulock @aculock
-@c reads&writes next_to_use and iterates over arena next without guards
-@c those are harmless as long as we don't drop arenas from the
-@c NEXT list, and we never do; when a thread terminates,
-@c arena_thread_freeres prepends the arena to the free_list
-@c NEXT_FREE list, but NEXT is never modified, so it's safe!
-@c mutex_trylock (arena lock) @asulock @aculock
-@c mutex_lock (arena lock) dup @asulock @aculock
-@c tsd_setspecific dup ok
-@c _int_malloc @acsfd @acsmem
-@c checked_request2size ok
-@c REQUEST_OUT_OF_RANGE ok
-@c request2size ok
-@c get_max_fast ok
-@c fastbin_index ok
-@c fastbin ok
-@c catomic_compare_and_exhange_val_acq ok
-@c malloc_printerr dup @mtsenv
-@c if we get to it, we're toast already, undefined behavior must have
-@c been invoked before
-@c libc_message @mtsenv [no leaks with cancellation disabled]
-@c FATAL_PREPARE ok
-@c pthread_setcancelstate disable ok
-@c libc_secure_getenv @mtsenv
-@c getenv @mtsenv
-@c open_not_cancel_2 dup @acsfd
-@c strchrnul ok
-@c WRITEV_FOR_FATAL ok
-@c writev ok
-@c mmap ok @acsmem
-@c munmap ok @acsmem
-@c BEFORE_ABORT @acsfd
-@c backtrace ok
-@c write_not_cancel dup ok
-@c backtrace_symbols_fd @aculock
-@c open_not_cancel_2 dup @acsfd
-@c read_not_cancel dup ok
-@c close_not_cancel_no_status dup @acsfd
-@c abort ok
-@c itoa_word ok
-@c abort ok
-@c check_remalloced_chunk ok/disabled
-@c chunk2mem dup ok
-@c alloc_perturb ok
-@c in_smallbin_range ok
-@c smallbin_index ok
-@c bin_at ok
-@c last ok
-@c malloc_consolidate ok
-@c get_max_fast dup ok
-@c clear_fastchunks ok
-@c unsorted_chunks dup ok
-@c fastbin dup ok
-@c atomic_exchange_acq ok
-@c check_inuse_chunk dup ok/disabled
-@c chunk_at_offset dup ok
-@c chunksize dup ok
-@c inuse_bit_at_offset dup ok
-@c unlink dup ok
-@c clear_inuse_bit_at_offset dup ok
-@c in_smallbin_range dup ok
-@c set_head dup ok
-@c malloc_init_state ok
-@c bin_at dup ok
-@c set_noncontiguous dup ok
-@c set_max_fast dup ok
-@c initial_top ok
-@c unsorted_chunks dup ok
-@c check_malloc_state ok/disabled
-@c set_inuse_bit_at_offset ok
-@c check_malloced_chunk ok/disabled
-@c largebin_index ok
-@c have_fastchunks ok
-@c unsorted_chunks ok
-@c bin_at ok
-@c chunksize ok
-@c chunk_at_offset ok
-@c set_head ok
-@c set_foot ok
-@c mark_bin ok
-@c idx2bit ok
-@c first ok
-@c unlink ok
-@c malloc_printerr dup ok
-@c in_smallbin_range dup ok
-@c idx2block ok
-@c idx2bit dup ok
-@c next_bin ok
-@c sysmalloc @acsfd @acsmem
-@c MMAP @acsmem
-@c set_head dup ok
-@c check_chunk ok/disabled
-@c chunk2mem dup ok
-@c chunksize dup ok
-@c chunk_at_offset dup ok
-@c heap_for_ptr ok
-@c grow_heap ok
-@c mprotect ok
-@c set_head dup ok
-@c new_heap @acsmem
-@c MMAP dup @acsmem
-@c munmap @acsmem
-@c top ok
-@c set_foot dup ok
-@c contiguous ok
-@c MORECORE ok
-@c *__morecore ok unguarded
-@c __default_morecore
-@c sbrk ok
-@c force_reg dup ok
-@c *__after_morecore_hook unguarded
-@c set_noncontiguous ok
-@c malloc_printerr dup ok
-@c _int_free (have_lock) @acsfd @acsmem [@asulock @aculock]
-@c chunksize dup ok
-@c mutex_unlock dup @aculock/!have_lock
-@c malloc_printerr dup ok
-@c check_inuse_chunk ok/disabled
-@c chunk_at_offset dup ok
-@c mutex_lock dup @asulock @aculock/@have_lock
-@c chunk2mem dup ok
-@c free_perturb ok
-@c set_fastchunks ok
-@c catomic_and ok
-@c fastbin_index dup ok
-@c fastbin dup ok
-@c catomic_compare_and_exchange_val_rel ok
-@c chunk_is_mmapped ok
-@c contiguous dup ok
-@c prev_inuse ok
-@c unlink dup ok
-@c inuse_bit_at_offset dup ok
-@c clear_inuse_bit_at_offset ok
-@c unsorted_chunks dup ok
-@c in_smallbin_range dup ok
-@c set_head dup ok
-@c set_foot dup ok
-@c check_free_chunk ok/disabled
-@c check_chunk dup ok/disabled
-@c have_fastchunks dup ok
-@c malloc_consolidate dup ok
-@c systrim ok
-@c MORECORE dup ok
-@c *__after_morecore_hook dup unguarded
-@c set_head dup ok
-@c check_malloc_state ok/disabled
-@c top dup ok
-@c heap_for_ptr dup ok
-@c heap_trim @acsfd @acsmem
-@c top dup ok
-@c chunk_at_offset dup ok
-@c prev_chunk ok
-@c chunksize dup ok
-@c prev_inuse dup ok
-@c delete_heap @acsmem
-@c munmap dup @acsmem
-@c unlink dup ok
-@c set_head dup ok
-@c shrink_heap @acsfd
-@c check_may_shrink_heap @acsfd
-@c open_not_cancel_2 @acsfd
-@c read_not_cancel ok
-@c close_not_cancel_no_status @acsfd
-@c MMAP dup ok
-@c madvise ok
-@c munmap_chunk @acsmem
-@c chunksize dup ok
-@c chunk_is_mmapped dup ok
-@c chunk2mem dup ok
-@c malloc_printerr dup ok
-@c munmap dup @acsmem
-@c check_malloc_state ok/disabled
-@c arena_get_retry @asulock @aculock @acsfd @acsmem
-@c mutex_unlock dup @aculock
-@c mutex_lock dup @asulock @aculock
-@c arena_get2 dup @asulock @aculock @acsfd @acsmem
-@c mutex_unlock @aculock
-@c mem2chunk ok
-@c chunk_is_mmapped ok
-@c arena_for_chunk ok
-@c chunk_non_main_arena ok
-@c heap_for_ptr ok
-This function returns a pointer to a newly allocated block @var{size}
-bytes long, or a null pointer if the block could not be allocated.
-@end deftypefun
-
-The contents of the block are undefined; you must initialize it yourself
-(or use @code{calloc} instead; @pxref{Allocating Cleared Space}).
-Normally you would cast the value as a pointer to the kind of object
-that you want to store in the block. Here we show an example of doing
-so, and of initializing the space with zeros using the library function
-@code{memset} (@pxref{Copying Strings and Arrays}):
-
-@smallexample
-struct foo *ptr;
-@dots{}
-ptr = (struct foo *) malloc (sizeof (struct foo));
-if (ptr == 0) abort ();
-memset (ptr, 0, sizeof (struct foo));
-@end smallexample
-
-You can store the result of @code{malloc} into any pointer variable
-without a cast, because @w{ISO C} automatically converts the type
-@code{void *} to another type of pointer when necessary. But the cast
-is necessary in contexts other than assignment operators or if you might
-want your code to run in traditional C.
-
-Remember that when allocating space for a string, the argument to
-@code{malloc} must be one plus the length of the string. This is
-because a string is terminated with a null character that doesn't count
-in the ``length'' of the string but does need space. For example:
-
-@smallexample
-char *ptr;
-@dots{}
-ptr = (char *) malloc (length + 1);
-@end smallexample
-
-@noindent
-@xref{Representation of Strings}, for more information about this.
-
-@node Malloc Examples
-@subsubsection Examples of @code{malloc}
-
-If no more space is available, @code{malloc} returns a null pointer.
-You should check the value of @emph{every} call to @code{malloc}. It is
-useful to write a subroutine that calls @code{malloc} and reports an
-error if the value is a null pointer, returning only if the value is
-nonzero. This function is conventionally called @code{xmalloc}. Here
-it is:
-
-@smallexample
-void *
-xmalloc (size_t size)
-@{
- void *value = malloc (size);
- if (value == 0)
- fatal ("virtual memory exhausted");
- return value;
-@}
-@end smallexample
-
-Here is a real example of using @code{malloc} (by way of @code{xmalloc}).
-The function @code{savestring} will copy a sequence of characters into
-a newly allocated null-terminated string:
-
-@smallexample
-@group
-char *
-savestring (const char *ptr, size_t len)
-@{
- char *value = (char *) xmalloc (len + 1);
- value[len] = '\0';
- return (char *) memcpy (value, ptr, len);
-@}
-@end group
-@end smallexample
-
-The block that @code{malloc} gives you is guaranteed to be aligned so
-that it can hold any type of data. On @gnusystems{}, the address is
-always a multiple of eight on 32-bit systems, and a multiple of 16 on
-64-bit systems. Only rarely is any higher boundary (such as a page
-boundary) necessary; for those cases, use @code{aligned_alloc} or
-@code{posix_memalign} (@pxref{Aligned Memory Blocks}).
-
-Note that the memory located after the end of the block is likely to be
-in use for something else; perhaps a block already allocated by another
-call to @code{malloc}. If you attempt to treat the block as longer than
-you asked for it to be, you are liable to destroy the data that
-@code{malloc} uses to keep track of its blocks, or you may destroy the
-contents of another block. If you have already allocated a block and
-discover you want it to be bigger, use @code{realloc} (@pxref{Changing
-Block Size}).
-
-@node Freeing after Malloc
-@subsubsection Freeing Memory Allocated with @code{malloc}
-@cindex freeing memory allocated with @code{malloc}
-@cindex heap, freeing memory from
-
-When you no longer need a block that you got with @code{malloc}, use the
-function @code{free} to make the block available to be allocated again.
-The prototype for this function is in @file{stdlib.h}.
-@pindex stdlib.h
-
-@comment malloc.h stdlib.h
-@comment ISO
-@deftypefun void free (void *@var{ptr})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c __libc_free @asulock @aculock @acsfd @acsmem
-@c releasing memory into fastbins modifies the arena without taking
-@c its mutex, but catomic operations ensure safety. If two (or more)
-@c threads are running malloc and have their own arenas locked when
-@c each gets a signal whose handler free()s large (non-fastbin-able)
-@c blocks from each other's arena, we deadlock; this is a more general
-@c case of @asulock.
-@c *__free_hook unguarded
-@c mem2chunk ok
-@c chunk_is_mmapped ok, chunk bits not modified after allocation
-@c chunksize ok
-@c munmap_chunk dup @acsmem
-@c arena_for_chunk dup ok
-@c _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
-The @code{free} function deallocates the block of memory pointed at
-by @var{ptr}.
-@end deftypefun
-
-Freeing a block alters the contents of the block. @strong{Do not expect to
-find any data (such as a pointer to the next block in a chain of blocks) in
-the block after freeing it.} Copy whatever you need out of the block before
-freeing it! Here is an example of the proper way to free all the blocks in
-a chain, and the strings that they point to:
-
-@smallexample
-struct chain
- @{
- struct chain *next;
- char *name;
- @}
-
-void
-free_chain (struct chain *chain)
-@{
- while (chain != 0)
- @{
- struct chain *next = chain->next;
- free (chain->name);
- free (chain);
- chain = next;
- @}
-@}
-@end smallexample
-
-Occasionally, @code{free} can actually return memory to the operating
-system and make the process smaller. Usually, all it can do is allow a
-later call to @code{malloc} to reuse the space. In the meantime, the
-space remains in your program as part of a free-list used internally by
-@code{malloc}.
-
-There is no point in freeing blocks at the end of a program, because all
-of the program's space is given back to the system when the process
-terminates.
-
-@node Changing Block Size
-@subsubsection Changing the Size of a Block
-@cindex changing the size of a block (@code{malloc})
-
-Often you do not know for certain how big a block you will ultimately need
-at the time you must begin to use the block. For example, the block might
-be a buffer that you use to hold a line being read from a file; no matter
-how long you make the buffer initially, you may encounter a line that is
-longer.
-
-You can make the block longer by calling @code{realloc} or
-@code{reallocarray}. These functions are declared in @file{stdlib.h}.
-@pindex stdlib.h
-
-@comment malloc.h stdlib.h
-@comment ISO
-@deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c It may call the implementations of malloc and free, so all of their
-@c issues arise, plus the realloc hook, also accessed without guards.
-
-@c __libc_realloc @asulock @aculock @acsfd @acsmem
-@c *__realloc_hook unguarded
-@c __libc_free dup @asulock @aculock @acsfd @acsmem
-@c __libc_malloc dup @asulock @aculock @acsfd @acsmem
-@c mem2chunk dup ok
-@c chunksize dup ok
-@c malloc_printerr dup ok
-@c checked_request2size dup ok
-@c chunk_is_mmapped dup ok
-@c mremap_chunk
-@c chunksize dup ok
-@c __mremap ok
-@c set_head dup ok
-@c MALLOC_COPY ok
-@c memcpy ok
-@c munmap_chunk dup @acsmem
-@c arena_for_chunk dup ok
-@c mutex_lock (arena mutex) dup @asulock @aculock
-@c _int_realloc @acsfd @acsmem
-@c malloc_printerr dup ok
-@c check_inuse_chunk dup ok/disabled
-@c chunk_at_offset dup ok
-@c chunksize dup ok
-@c set_head_size dup ok
-@c chunk_at_offset dup ok
-@c set_head dup ok
-@c chunk2mem dup ok
-@c inuse dup ok
-@c unlink dup ok
-@c _int_malloc dup @acsfd @acsmem
-@c mem2chunk dup ok
-@c MALLOC_COPY dup ok
-@c _int_free (have_lock) dup @acsfd @acsmem
-@c set_inuse_bit_at_offset dup ok
-@c set_head dup ok
-@c mutex_unlock (arena mutex) dup @aculock
-@c _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
-
-The @code{realloc} function changes the size of the block whose address is
-@var{ptr} to be @var{newsize}.
-
-Since the space after the end of the block may be in use, @code{realloc}
-may find it necessary to copy the block to a new address where more free
-space is available. The value of @code{realloc} is the new address of the
-block. If the block needs to be moved, @code{realloc} copies the old
-contents.
-
-If you pass a null pointer for @var{ptr}, @code{realloc} behaves just
-like @samp{malloc (@var{newsize})}. This can be convenient, but beware
-that older implementations (before @w{ISO C}) may not support this
-behavior, and will probably crash when @code{realloc} is passed a null
-pointer.
-@end deftypefun
-
-@comment malloc.h stdlib.h
-@comment BSD
-@deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-
-The @code{reallocarray} function changes the size of the block whose address
-is @var{ptr} to be long enough to contain a vector of @var{nmemb} elements,
-each of size @var{size}. It is equivalent to @samp{realloc (@var{ptr},
-@var{nmemb} * @var{size})}, except that @code{reallocarray} fails safely if
-the multiplication overflows, by setting @code{errno} to @code{ENOMEM},
-returning a null pointer, and leaving the original block unchanged.
-
-@code{reallocarray} should be used instead of @code{realloc} when the new size
-of the allocated block is the result of a multiplication that might overflow.
-
-@strong{Portability Note:} This function is not part of any standard. It was
-first introduced in OpenBSD 5.6.
-@end deftypefun
-
-Like @code{malloc}, @code{realloc} and @code{reallocarray} may return a null
-pointer if no memory space is available to make the block bigger. When this
-happens, the original block is untouched; it has not been modified or
-relocated.
-
-In most cases it makes no difference what happens to the original block
-when @code{realloc} fails, because the application program cannot continue
-when it is out of memory, and the only thing to do is to give a fatal error
-message. Often it is convenient to write and use a subroutine,
-conventionally called @code{xrealloc}, that takes care of the error message
-as @code{xmalloc} does for @code{malloc}:
-
-@smallexample
-void *
-xrealloc (void *ptr, size_t size)
-@{
- void *value = realloc (ptr, size);
- if (value == 0)
- fatal ("Virtual memory exhausted");
- return value;
-@}
-@end smallexample
-
-You can also use @code{realloc} or @code{reallocarray} to make a block
-smaller. The reason you would do this is to avoid tying up a lot of memory
-space when only a little is needed.
-@comment The following is no longer true with the new malloc.
-@comment But it seems wise to keep the warning for other implementations.
-In several allocation implementations, making a block smaller sometimes
-necessitates copying it, so it can fail if no other space is available.
-
-If the new size you specify is the same as the old size, @code{realloc} and
-@code{reallocarray} are guaranteed to change nothing and return the same
-address that you gave.
-
-@node Allocating Cleared Space
-@subsubsection Allocating Cleared Space
-
-The function @code{calloc} allocates memory and clears it to zero. It
-is declared in @file{stdlib.h}.
-@pindex stdlib.h
-
-@comment malloc.h stdlib.h
-@comment ISO
-@deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c Same caveats as malloc.
-
-@c __libc_calloc @asulock @aculock @acsfd @acsmem
-@c *__malloc_hook dup unguarded
-@c memset dup ok
-@c arena_get @asulock @aculock @acsfd @acsmem
-@c arena_lock dup @asulock @aculock @acsfd @acsmem
-@c top dup ok
-@c chunksize dup ok
-@c heap_for_ptr dup ok
-@c _int_malloc dup @acsfd @acsmem
-@c arena_get_retry dup @asulock @aculock @acsfd @acsmem
-@c mutex_unlock dup @aculock
-@c mem2chunk dup ok
-@c chunk_is_mmapped dup ok
-@c MALLOC_ZERO ok
-@c memset dup ok
-This function allocates a block long enough to contain a vector of
-@var{count} elements, each of size @var{eltsize}. Its contents are
-cleared to zero before @code{calloc} returns.
-@end deftypefun
-
-You could define @code{calloc} as follows:
-
-@smallexample
-void *
-calloc (size_t count, size_t eltsize)
-@{
- size_t size = count * eltsize;
- void *value = malloc (size);
- if (value != 0)
- memset (value, 0, size);
- return value;
-@}
-@end smallexample
-
-But in general, it is not guaranteed that @code{calloc} calls
-@code{malloc} internally. Therefore, if an application provides its own
-@code{malloc}/@code{realloc}/@code{free} outside the C library, it
-should always define @code{calloc}, too.
-
-@node Aligned Memory Blocks
-@subsubsection Allocating Aligned Memory Blocks
-
-@cindex page boundary
-@cindex alignment (with @code{malloc})
-@pindex stdlib.h
-The address of a block returned by @code{malloc} or @code{realloc} in
-@gnusystems{} is always a multiple of eight (or sixteen on 64-bit
-systems). If you need a block whose address is a multiple of a higher
-power of two than that, use @code{aligned_alloc} or @code{posix_memalign}.
-@code{aligned_alloc} and @code{posix_memalign} are declared in
-@file{stdlib.h}.
-
-@comment stdlib.h
-@deftypefun {void *} aligned_alloc (size_t @var{alignment}, size_t @var{size})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c Alias to memalign.
-The @code{aligned_alloc} function allocates a block of @var{size} bytes whose
-address is a multiple of @var{alignment}. The @var{alignment} must be a
-power of two and @var{size} must be a multiple of @var{alignment}.
-
-The @code{aligned_alloc} function returns a null pointer on error and sets
-@code{errno} to one of the following values:
-
-@table @code
-@item ENOMEM
-There was insufficient memory available to satisfy the request.
-
-@item EINVAL
-@var{alignment} is not a power of two.
-
-This function was introduced in @w{ISO C11} and hence may have better
-portability to modern non-POSIX systems than @code{posix_memalign}.
-@end table
-
-@end deftypefun
-
-@comment malloc.h
-@comment BSD
-@deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c Same issues as malloc. The padding bytes are safely freed in
-@c _int_memalign, with the arena still locked.
-
-@c __libc_memalign @asulock @aculock @acsfd @acsmem
-@c *__memalign_hook dup unguarded
-@c __libc_malloc dup @asulock @aculock @acsfd @acsmem
-@c arena_get dup @asulock @aculock @acsfd @acsmem
-@c _int_memalign @acsfd @acsmem
-@c _int_malloc dup @acsfd @acsmem
-@c checked_request2size dup ok
-@c mem2chunk dup ok
-@c chunksize dup ok
-@c chunk_is_mmapped dup ok
-@c set_head dup ok
-@c chunk2mem dup ok
-@c set_inuse_bit_at_offset dup ok
-@c set_head_size dup ok
-@c _int_free (have_lock) dup @acsfd @acsmem
-@c chunk_at_offset dup ok
-@c check_inuse_chunk dup ok
-@c arena_get_retry dup @asulock @aculock @acsfd @acsmem
-@c mutex_unlock dup @aculock
-The @code{memalign} function allocates a block of @var{size} bytes whose
-address is a multiple of @var{boundary}. The @var{boundary} must be a
-power of two! The function @code{memalign} works by allocating a
-somewhat larger block, and then returning an address within the block
-that is on the specified boundary.
-
-The @code{memalign} function returns a null pointer on error and sets
-@code{errno} to one of the following values:
-
-@table @code
-@item ENOMEM
-There was insufficient memory available to satisfy the request.
-
-@item EINVAL
-@var{boundary} is not a power of two.
-
-@end table
-
-The @code{memalign} function is obsolete and @code{aligned_alloc} or
-@code{posix_memalign} should be used instead.
-@end deftypefun
-
-@comment stdlib.h
-@comment POSIX
-@deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
-@c Calls memalign unless the requirements are not met (powerof2 macro is
-@c safe given an automatic variable as an argument) or there's a
-@c memalign hook (accessed unguarded, but safely).
-The @code{posix_memalign} function is similar to the @code{memalign}
-function in that it returns a buffer of @var{size} bytes aligned to a
-multiple of @var{alignment}. But it adds one requirement to the
-parameter @var{alignment}: the value must be a power of two multiple of
-@code{sizeof (void *)}.
-
-If the function succeeds in allocation memory a pointer to the allocated
-memory is returned in @code{*@var{memptr}} and the return value is zero.
-Otherwise the function returns an error value indicating the problem.
-The possible error values returned are:
-
-@table @code
-@item ENOMEM
-There was insufficient memory available to satisfy the request.
-
-@item EINVAL
-@var{alignment} is not a power of two multiple of @code{sizeof (void *)}.
-
-@end table
-
-This function was introduced in POSIX 1003.1d. Although this function is
-superseded by @code{aligned_alloc}, it is more portable to older POSIX
-systems that do not support @w{ISO C11}.
-@end deftypefun
-
-@comment malloc.h stdlib.h
-@comment BSD
-@deftypefun {void *} valloc (size_t @var{size})
-@safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{} @acsfd{} @acsmem{}}}
-@c __libc_valloc @mtuinit @asuinit @asulock @aculock @acsfd @acsmem
-@c ptmalloc_init (once) @mtsenv @asulock @aculock @acsfd @acsmem
-@c _dl_addr @asucorrupt? @aculock
-@c __rtld_lock_lock_recursive (dl_load_lock) @asucorrupt? @aculock
-@c _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
-@c the ok above assumes no partial updates on dl_ns and _ns_loaded
-@c that could confuse a _dl_addr call in a signal handler
-@c _dl_addr_inside_object ok
-@c determine_info ok
-@c __rtld_lock_unlock_recursive (dl_load_lock) @aculock
-@c *_environ @mtsenv
-@c next_env_entry ok
-@c strcspn dup ok
-@c __libc_mallopt dup @mtasuconst:mallopt [setting mp_]
-@c __malloc_check_init @mtasuconst:malloc_hooks [setting hooks]
-@c *__malloc_initialize_hook unguarded, ok
-@c *__memalign_hook dup ok, unguarded
-@c arena_get dup @asulock @aculock @acsfd @acsmem
-@c _int_valloc @acsfd @acsmem
-@c malloc_consolidate dup ok
-@c _int_memalign dup @acsfd @acsmem
-@c arena_get_retry dup @asulock @aculock @acsfd @acsmem
-@c _int_memalign dup @acsfd @acsmem
-@c mutex_unlock dup @aculock
-Using @code{valloc} is like using @code{memalign} and passing the page size
-as the value of the first argument. It is implemented like this:
-
-@smallexample
-void *
-valloc (size_t size)
-@{
- return memalign (getpagesize (), size);
-@}
-@end smallexample
-
-@ref{Query Memory Parameters} for more information about the memory
-subsystem.
-
-The @code{valloc} function is obsolete and @code{aligned_alloc} or
-@code{posix_memalign} should be used instead.
-@end deftypefun
-
-@node Malloc Tunable Parameters
-@subsubsection Malloc Tunable Parameters
-
-You can adjust some parameters for dynamic memory allocation with the
-@code{mallopt} function. This function is the general SVID/XPG
-interface, defined in @file{malloc.h}.
-@pindex malloc.h
-
-@deftypefun int mallopt (int @var{param}, int @var{value})
-@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
-@c __libc_mallopt @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
-@c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
-@c mutex_lock (main_arena->mutex) @asulock @aculock
-@c malloc_consolidate dup ok
-@c set_max_fast ok
-@c mutex_unlock dup @aculock
-
-When calling @code{mallopt}, the @var{param} argument specifies the
-parameter to be set, and @var{value} the new value to be set. Possible
-choices for @var{param}, as defined in @file{malloc.h}, are:
-
-@comment TODO: @item M_CHECK_ACTION
-@vtable @code
-@item M_MMAP_MAX
-The maximum number of chunks to allocate with @code{mmap}. Setting this
-to zero disables all use of @code{mmap}.
-
-The default value of this parameter is @code{65536}.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_MMAP_MAX_} to the desired value.
-
-@item M_MMAP_THRESHOLD
-All chunks larger than this value are allocated outside the normal
-heap, using the @code{mmap} system call. This way it is guaranteed
-that the memory for these chunks can be returned to the system on
-@code{free}. Note that requests smaller than this threshold might still
-be allocated via @code{mmap}.
-
-If this parameter is not set, the default value is set as 128 KiB and the
-threshold is adjusted dynamically to suit the allocation patterns of the
-program. If the parameter is set, the dynamic adjustment is disabled and the
-value is set statically to the input value.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_MMAP_THRESHOLD_} to the desired value.
-@comment TODO: @item M_MXFAST
-
-@item M_PERTURB
-If non-zero, memory blocks are filled with values depending on some
-low order bits of this parameter when they are allocated (except when
-allocated by @code{calloc}) and freed. This can be used to debug the
-use of uninitialized or freed heap memory. Note that this option does not
-guarantee that the freed block will have any specific values. It only
-guarantees that the content the block had before it was freed will be
-overwritten.
-
-The default value of this parameter is @code{0}.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_MMAP_PERTURB_} to the desired value.
-
-@item M_TOP_PAD
-This parameter determines the amount of extra memory to obtain from the system
-when an arena needs to be extended. It also specifies the number of bytes to
-retain when shrinking an arena. This provides the necessary hysteresis in heap
-size such that excessive amounts of system calls can be avoided.
-
-The default value of this parameter is @code{0}.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_TOP_PAD_} to the desired value.
-
-@item M_TRIM_THRESHOLD
-This is the minimum size (in bytes) of the top-most, releasable chunk
-that will trigger a system call in order to return memory to the system.
-
-If this parameter is not set, the default value is set as 128 KiB and the
-threshold is adjusted dynamically to suit the allocation patterns of the
-program. If the parameter is set, the dynamic adjustment is disabled and the
-value is set statically to the provided input.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_TRIM_THRESHOLD_} to the desired value.
-
-@item M_ARENA_TEST
-This parameter specifies the number of arenas that can be created before the
-test on the limit to the number of arenas is conducted. The value is ignored if
-@code{M_ARENA_MAX} is set.
-
-The default value of this parameter is 2 on 32-bit systems and 8 on 64-bit
-systems.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_ARENA_TEST} to the desired value.
-
-@item M_ARENA_MAX
-This parameter sets the number of arenas to use regardless of the number of
-cores in the system.
-
-The default value of this tunable is @code{0}, meaning that the limit on the
-number of arenas is determined by the number of CPU cores online. For 32-bit
-systems the limit is twice the number of cores online and on 64-bit systems, it
-is eight times the number of cores online. Note that the default value is not
-derived from the default value of M_ARENA_TEST and is computed independently.
-
-This parameter can also be set for the process at startup by setting the
-environment variable @env{MALLOC_ARENA_MAX} to the desired value.
-@end vtable
-
-@end deftypefun
-
-@node Heap Consistency Checking
-@subsubsection Heap Consistency Checking
-
-@cindex heap consistency checking
-@cindex consistency checking, of heap
-
-You can ask @code{malloc} to check the consistency of dynamic memory by
-using the @code{mcheck} function. This function is a GNU extension,
-declared in @file{mcheck.h}.
-@pindex mcheck.h
-
-@comment mcheck.h
-@comment GNU
-@deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
-@safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
-@c The hooks must be set up before malloc is first used, which sort of
-@c implies @mtuinit/@asuinit but since the function is a no-op if malloc
-@c was already used, that doesn't pose any safety issues. The actual
-@c problem is with the hooks, designed for single-threaded
-@c fully-synchronous operation: they manage an unguarded linked list of
-@c allocated blocks, and get temporarily overwritten before calling the
-@c allocation functions recursively while holding the old hooks. There
-@c are no guards for thread safety, and inconsistent hooks may be found
-@c within signal handlers or left behind in case of cancellation.
-
-Calling @code{mcheck} tells @code{malloc} to perform occasional
-consistency checks. These will catch things such as writing
-past the end of a block that was allocated with @code{malloc}.
-
-The @var{abortfn} argument is the function to call when an inconsistency
-is found. If you supply a null pointer, then @code{mcheck} uses a
-default function which prints a message and calls @code{abort}
-(@pxref{Aborting a Program}). The function you supply is called with
-one argument, which says what sort of inconsistency was detected; its
-type is described below.
-
-It is too late to begin allocation checking once you have allocated
-anything with @code{malloc}. So @code{mcheck} does nothing in that
-case. The function returns @code{-1} if you call it too late, and
-@code{0} otherwise (when it is successful).
-
-The easiest way to arrange to call @code{mcheck} early enough is to use
-the option @samp{-lmcheck} when you link your program; then you don't
-need to modify your program source at all. Alternatively you might use
-a debugger to insert a call to @code{mcheck} whenever the program is
-started, for example these gdb commands will automatically call @code{mcheck}
-whenever the program starts:
-
-@smallexample
-(gdb) break main
-Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10
-(gdb) command 1
-Type commands for when breakpoint 1 is hit, one per line.
-End with a line saying just "end".
->call mcheck(0)
->continue
->end
-(gdb) @dots{}
-@end smallexample
-
-This will however only work if no initialization function of any object
-involved calls any of the @code{malloc} functions since @code{mcheck}
-must be called before the first such function.
-
-@end deftypefun
-
-@deftypefun {enum mcheck_status} mprobe (void *@var{pointer})
-@safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
-@c The linked list of headers may be modified concurrently by other
-@c threads, and it may find a partial update if called from a signal
-@c handler. It's mostly read only, so cancelling it might be safe, but
-@c it will modify global state that, if cancellation hits at just the
-@c right spot, may be left behind inconsistent. This path is only taken
-@c if checkhdr finds an inconsistency. If the inconsistency could only
-@c occur because of earlier undefined behavior, that wouldn't be an
-@c additional safety issue problem, but because of the other concurrency
-@c issues in the mcheck hooks, the apparent inconsistency could be the
-@c result of mcheck's own internal data race. So, AC-Unsafe it is.
-
-The @code{mprobe} function lets you explicitly check for inconsistencies
-in a particular allocated block. You must have already called
-@code{mcheck} at the beginning of the program, to do its occasional
-checks; calling @code{mprobe} requests an additional consistency check
-to be done at the time of the call.
-
-The argument @var{pointer} must be a pointer returned by @code{malloc}
-or @code{realloc}. @code{mprobe} returns a value that says what
-inconsistency, if any, was found. The values are described below.
-@end deftypefun
-
-@deftp {Data Type} {enum mcheck_status}
-This enumerated type describes what kind of inconsistency was detected
-in an allocated block, if any. Here are the possible values:
-
-@table @code
-@item MCHECK_DISABLED
-@code{mcheck} was not called before the first allocation.
-No consistency checking can be done.
-@item MCHECK_OK
-No inconsistency detected.
-@item MCHECK_HEAD
-The data immediately before the block was modified.
-This commonly happens when an array index or pointer
-is decremented too far.
-@item MCHECK_TAIL
-The data immediately after the block was modified.
-This commonly happens when an array index or pointer
-is incremented too far.
-@item MCHECK_FREE
-The block was already freed.
-@end table
-@end deftp
-
-Another possibility to check for and guard against bugs in the use of
-@code{malloc}, @code{realloc} and @code{free} is to set the environment
-variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set, a
-special (less efficient) implementation is used which is designed to be
-tolerant against simple errors, such as double calls of @code{free} with
-the same argument, or overruns of a single byte (off-by-one bugs). Not
-all such errors can be protected against, however, and memory leaks can
-result. If @code{MALLOC_CHECK_} is set to @code{0}, any detected heap
-corruption is silently ignored; if set to @code{1}, a diagnostic is
-printed on @code{stderr}; if set to @code{2}, @code{abort} is called
-immediately. This can be useful because otherwise a crash may happen
-much later, and the true cause for the problem is then very hard to
-track down.
-
-There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
-it could possibly be exploited since diverging from the normal programs
-behavior it now writes something to the standard error descriptor.
-Therefore the use of @code{MALLOC_CHECK_} is disabled by default for
-SUID and SGID binaries. It can be enabled again by the system
-administrator by adding a file @file{/etc/suid-debug} (the content is
-not important it could be empty).
-
-So, what's the difference between using @code{MALLOC_CHECK_} and linking
-with @samp{-lmcheck}? @code{MALLOC_CHECK_} is orthogonal with respect to
-@samp{-lmcheck}. @samp{-lmcheck} has been added for backward
-compatibility. Both @code{MALLOC_CHECK_} and @samp{-lmcheck} should
-uncover the same bugs - but using @code{MALLOC_CHECK_} you don't need to
-recompile your application.
-
-@node Hooks for Malloc
-@subsubsection Memory Allocation Hooks
-@cindex allocation hooks, for @code{malloc}
-
-@Theglibc{} lets you modify the behavior of @code{malloc},
-@code{realloc}, and @code{free} by specifying appropriate hook
-functions. You can use these hooks to help you debug programs that use
-dynamic memory allocation, for example.
-
-The hook variables are declared in @file{malloc.h}.
-@pindex malloc.h
-
-@comment malloc.h
-@comment GNU
-@defvar __malloc_hook
-The value of this variable is a pointer to the function that
-@code{malloc} uses whenever it is called. You should define this
-function to look like @code{malloc}; that is, like:
-
-@smallexample
-void *@var{function} (size_t @var{size}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{malloc} function was called. This value allows you to trace
-the memory consumption of the program.
-@end defvar
-
-@comment malloc.h
-@comment GNU
-@defvar __realloc_hook
-The value of this variable is a pointer to function that @code{realloc}
-uses whenever it is called. You should define this function to look
-like @code{realloc}; that is, like:
-
-@smallexample
-void *@var{function} (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{realloc} function was called. This value allows you to trace the
-memory consumption of the program.
-@end defvar
-
-@comment malloc.h
-@comment GNU
-@defvar __free_hook
-The value of this variable is a pointer to function that @code{free}
-uses whenever it is called. You should define this function to look
-like @code{free}; that is, like:
-
-@smallexample
-void @var{function} (void *@var{ptr}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{free} function was called. This value allows you to trace the
-memory consumption of the program.
-@end defvar
-
-@comment malloc.h
-@comment GNU
-@defvar __memalign_hook
-The value of this variable is a pointer to function that @code{aligned_alloc},
-@code{memalign}, @code{posix_memalign} and @code{valloc} use whenever they
-are called. You should define this function to look like @code{aligned_alloc};
-that is, like:
-
-@smallexample
-void *@var{function} (size_t @var{alignment}, size_t @var{size}, const void *@var{caller})
-@end smallexample
-
-The value of @var{caller} is the return address found on the stack when
-the @code{aligned_alloc}, @code{memalign}, @code{posix_memalign} or
-@code{valloc} functions are called. This value allows you to trace the
-memory consumption of the program.
-@end defvar
-
-You must make sure that the function you install as a hook for one of
-these functions does not call that function recursively without restoring
-the old value of the hook first! Otherwise, your program will get stuck
-in an infinite recursion. Before calling the function recursively, one
-should make sure to restore all the hooks to their previous value. When
-coming back from the recursive call, all the hooks should be resaved
-since a hook might modify itself.
-
-An issue to look out for is the time at which the malloc hook functions
-can be safely installed. If the hook functions call the malloc-related
-functions recursively, it is necessary that malloc has already properly
-initialized itself at the time when @code{__malloc_hook} etc. is
-assigned to. On the other hand, if the hook functions provide a
-complete malloc implementation of their own, it is vital that the hooks
-are assigned to @emph{before} the very first @code{malloc} call has
-completed, because otherwise a chunk obtained from the ordinary,
-un-hooked malloc may later be handed to @code{__free_hook}, for example.
-
-Here is an example showing how to use @code{__malloc_hook} and
-@code{__free_hook} properly. It installs a function that prints out
-information every time @code{malloc} or @code{free} is called. We just
-assume here that @code{realloc} and @code{memalign} are not used in our
-program.
-
-@smallexample
-/* Prototypes for __malloc_hook, __free_hook */
-#include <malloc.h>
-
-/* Prototypes for our hooks. */
-static void my_init_hook (void);
-static void *my_malloc_hook (size_t, const void *);
-static void my_free_hook (void*, const void *);
-
-static void
-my_init (void)
-@{
- old_malloc_hook = __malloc_hook;
- old_free_hook = __free_hook;
- __malloc_hook = my_malloc_hook;
- __free_hook = my_free_hook;
-@}
-
-static void *
-my_malloc_hook (size_t size, const void *caller)
-@{
- void *result;
- /* Restore all old hooks */
- __malloc_hook = old_malloc_hook;
- __free_hook = old_free_hook;
- /* Call recursively */
- result = malloc (size);
- /* Save underlying hooks */
- old_malloc_hook = __malloc_hook;
- old_free_hook = __free_hook;
- /* @r{@code{printf} might call @code{malloc}, so protect it too.} */
- printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
- /* Restore our own hooks */
- __malloc_hook = my_malloc_hook;
- __free_hook = my_free_hook;
- return result;
-@}
-
-static void
-my_free_hook (void *ptr, const void *caller)
-@{
- /* Restore all old hooks */
- __malloc_hook = old_malloc_hook;
- __free_hook = old_free_hook;
- /* Call recursively */
- free (ptr);
- /* Save underlying hooks */
- old_malloc_hook = __malloc_hook;
- old_free_hook = __free_hook;
- /* @r{@code{printf} might call @code{free}, so protect it too.} */
- printf ("freed pointer %p\n", ptr);
- /* Restore our own hooks */
- __malloc_hook = my_malloc_hook;
- __free_hook = my_free_hook;
-@}
-
-main ()
-@{
- my_init ();
- @dots{}
-@}
-@end smallexample
-
-The @code{mcheck} function (@pxref{Heap Consistency Checking}) works by
-installing such hooks.
-
-@c __morecore, __after_morecore_hook are undocumented
-@c It's not clear whether to document them.
-
-@node Statistics of Malloc
-@subsubsection Statistics for Memory Allocation with @code{malloc}
-
-@cindex allocation statistics
-You can get information about dynamic memory allocation by calling the
-@code{mallinfo} function. This function and its associated data type
-are declared in @file{malloc.h}; they are an extension of the standard
-SVID/XPG version.
-@pindex malloc.h
-
-@comment malloc.h
-@comment GNU
-@deftp {Data Type} {struct mallinfo}
-This structure type is used to return information about the dynamic
-memory allocator. It contains the following members:
-
-@table @code
-@item int arena
-This is the total size of memory allocated with @code{sbrk} by
-@code{malloc}, in bytes.
-
-@item int ordblks
-This is the number of chunks not in use. (The memory allocator
-internally gets chunks of memory from the operating system, and then
-carves them up to satisfy individual @code{malloc} requests;
-@pxref{The GNU Allocator}.)
-
-@item int smblks
-This field is unused.
-
-@item int hblks
-This is the total number of chunks allocated with @code{mmap}.
-
-@item int hblkhd
-This is the total size of memory allocated with @code{mmap}, in bytes.
-
-@item int usmblks
-This field is unused and always 0.
-
-@item int fsmblks
-This field is unused.
-
-@item int uordblks
-This is the total size of memory occupied by chunks handed out by
-@code{malloc}.
-
-@item int fordblks
-This is the total size of memory occupied by free (not in use) chunks.
-
-@item int keepcost
-This is the size of the top-most releasable chunk that normally
-borders the end of the heap (i.e., the high end of the virtual address
-space's data segment).
-
-@end table
-@end deftp
-
-@comment malloc.h
-@comment SVID
-@deftypefun {struct mallinfo} mallinfo (void)
-@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
-@c Accessing mp_.n_mmaps and mp_.max_mmapped_mem, modified with atomics
-@c but non-atomically elsewhere, may get us inconsistent results. We
-@c mark the statistics as unsafe, rather than the fast-path functions
-@c that collect the possibly inconsistent data.
-
-@c __libc_mallinfo @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
-@c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
-@c mutex_lock dup @asulock @aculock
-@c int_mallinfo @mtasuconst:mallopt [mp_ access on main_arena]
-@c malloc_consolidate dup ok
-@c check_malloc_state dup ok/disabled
-@c chunksize dup ok
-@c fastbin dupo ok
-@c bin_at dup ok
-@c last dup ok
-@c mutex_unlock @aculock
-
-This function returns information about the current dynamic memory usage
-in a structure of type @code{struct mallinfo}.
-@end deftypefun
-
-@node Summary of Malloc
-@subsubsection Summary of @code{malloc}-Related Functions
-
-Here is a summary of the functions that work with @code{malloc}:
-
-@table @code
-@item void *malloc (size_t @var{size})
-Allocate a block of @var{size} bytes. @xref{Basic Allocation}.
-
-@item void free (void *@var{addr})
-Free a block previously allocated by @code{malloc}. @xref{Freeing after
-Malloc}.
-
-@item void *realloc (void *@var{addr}, size_t @var{size})
-Make a block previously allocated by @code{malloc} larger or smaller,
-possibly by copying it to a new location. @xref{Changing Block Size}.
-
-@item void *reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
-Change the size of a block previously allocated by @code{malloc} to
-@code{@var{nmemb} * @var{size}} bytes as with @code{realloc}. @xref{Changing
-Block Size}.
-
-@item void *calloc (size_t @var{count}, size_t @var{eltsize})
-Allocate a block of @var{count} * @var{eltsize} bytes using
-@code{malloc}, and set its contents to zero. @xref{Allocating Cleared
-Space}.
-
-@item void *valloc (size_t @var{size})
-Allocate a block of @var{size} bytes, starting on a page boundary.
-@xref{Aligned Memory Blocks}.
-
-@item void *aligned_alloc (size_t @var{size}, size_t @var{alignment})
-Allocate a block of @var{size} bytes, starting on an address that is a
-multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
-
-@item int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
-Allocate a block of @var{size} bytes, starting on an address that is a
-multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
-
-@item void *memalign (size_t @var{size}, size_t @var{boundary})
-Allocate a block of @var{size} bytes, starting on an address that is a
-multiple of @var{boundary}. @xref{Aligned Memory Blocks}.
-
-@item int mallopt (int @var{param}, int @var{value})
-Adjust a tunable parameter. @xref{Malloc Tunable Parameters}.
-
-@item int mcheck (void (*@var{abortfn}) (void))
-Tell @code{malloc} to perform occasional consistency checks on
-dynamically allocated memory, and to call @var{abortfn} when an
-inconsistency is found. @xref{Heap Consistency Checking}.
-
-@item void *(*__malloc_hook) (size_t @var{size}, const void *@var{caller})
-A pointer to a function that @code{malloc} uses whenever it is called.
-
-@item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}, const void *@var{caller})
-A pointer to a function that @code{realloc} uses whenever it is called.
-
-@item void (*__free_hook) (void *@var{ptr}, const void *@var{caller})
-A pointer to a function that @code{free} uses whenever it is called.
-
-@item void (*__memalign_hook) (size_t @var{size}, size_t @var{alignment}, const void *@var{caller})
-A pointer to a function that @code{aligned_alloc}, @code{memalign},
-@code{posix_memalign} and @code{valloc} use whenever they are called.
-
-@item struct mallinfo mallinfo (void)
-Return information about the current dynamic memory usage.
-@xref{Statistics of Malloc}.
-@end table
-
-@node Allocation Debugging
-@subsection Allocation Debugging
-@cindex allocation debugging
-@cindex malloc debugger
-
-A complicated task when programming with languages which do not use
-garbage collected dynamic memory allocation is to find memory leaks.
-Long running programs must ensure that dynamically allocated objects are
-freed at the end of their lifetime. If this does not happen the system
-runs out of memory, sooner or later.
-
-The @code{malloc} implementation in @theglibc{} provides some
-simple means to detect such leaks and obtain some information to find
-the location. To do this the application must be started in a special
-mode which is enabled by an environment variable. There are no speed
-penalties for the program if the debugging mode is not enabled.
-
-@menu
-* Tracing malloc:: How to install the tracing functionality.
-* Using the Memory Debugger:: Example programs excerpts.
-* Tips for the Memory Debugger:: Some more or less clever ideas.
-* Interpreting the traces:: What do all these lines mean?
-@end menu
-
-@node Tracing malloc
-@subsubsection How to install the tracing functionality
-
-@comment mcheck.h
-@comment GNU
-@deftypefun void mtrace (void)
-@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c Like the mcheck hooks, these are not designed with thread safety in
-@c mind, because the hook pointers are temporarily modified without
-@c regard to other threads, signals or cancellation.
-
-@c mtrace @mtuinit @mtasurace:mtrace @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
-@c __libc_secure_getenv dup @mtsenv
-@c malloc dup @ascuheap @acsmem
-@c fopen dup @ascuheap @asulock @aculock @acsmem @acsfd
-@c fcntl dup ok
-@c setvbuf dup @aculock
-@c fprintf dup (on newly-created stream) @aculock
-@c __cxa_atexit (once) dup @asulock @aculock @acsmem
-@c free dup @ascuheap @acsmem
-When the @code{mtrace} function is called it looks for an environment
-variable named @code{MALLOC_TRACE}. This variable is supposed to
-contain a valid file name. The user must have write access. If the
-file already exists it is truncated. If the environment variable is not
-set or it does not name a valid file which can be opened for writing
-nothing is done. The behavior of @code{malloc} etc. is not changed.
-For obvious reasons this also happens if the application is installed
-with the SUID or SGID bit set.
-
-If the named file is successfully opened, @code{mtrace} installs special
-handlers for the functions @code{malloc}, @code{realloc}, and
-@code{free} (@pxref{Hooks for Malloc}). From then on, all uses of these
-functions are traced and protocolled into the file. There is now of
-course a speed penalty for all calls to the traced functions so tracing
-should not be enabled during normal use.
-
-This function is a GNU extension and generally not available on other
-systems. The prototype can be found in @file{mcheck.h}.
-@end deftypefun
-
-@comment mcheck.h
-@comment GNU
-@deftypefun void muntrace (void)
-@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
-
-@c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
-@c fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
-@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
-The @code{muntrace} function can be called after @code{mtrace} was used
-to enable tracing the @code{malloc} calls. If no (successful) call of
-@code{mtrace} was made @code{muntrace} does nothing.
-
-Otherwise it deinstalls the handlers for @code{malloc}, @code{realloc},
-and @code{free} and then closes the protocol file. No calls are
-protocolled anymore and the program runs again at full speed.
-
-This function is a GNU extension and generally not available on other
-systems. The prototype can be found in @file{mcheck.h}.
-@end deftypefun
-
-@node Using the Memory Debugger
-@subsubsection Example program excerpts
-
-Even though the tracing functionality does not influence the runtime
-behavior of the program it is not a good idea to call @code{mtrace} in
-all programs. Just imagine that you debug a program using @code{mtrace}
-and all other programs used in the debugging session also trace their
-@code{malloc} calls. The output file would be the same for all programs
-and thus is unusable. Therefore one should call @code{mtrace} only if
-compiled for debugging. A program could therefore start like this:
-
-@example
-#include <mcheck.h>
-
-int
-main (int argc, char *argv[])
-@{
-#ifdef DEBUGGING
- mtrace ();
-#endif
- @dots{}
-@}
-@end example
-
-This is all that is needed if you want to trace the calls during the
-whole runtime of the program. Alternatively you can stop the tracing at
-any time with a call to @code{muntrace}. It is even possible to restart
-the tracing again with a new call to @code{mtrace}. But this can cause
-unreliable results since there may be calls of the functions which are
-not called. Please note that not only the application uses the traced
-functions, also libraries (including the C library itself) use these
-functions.
-
-This last point is also why it is not a good idea to call @code{muntrace}
-before the program terminates. The libraries are informed about the
-termination of the program only after the program returns from
-@code{main} or calls @code{exit} and so cannot free the memory they use
-before this time.
-
-So the best thing one can do is to call @code{mtrace} as the very first
-function in the program and never call @code{muntrace}. So the program
-traces almost all uses of the @code{malloc} functions (except those
-calls which are executed by constructors of the program or used
-libraries).
-
-@node Tips for the Memory Debugger
-@subsubsection Some more or less clever ideas
-
-You know the situation. The program is prepared for debugging and in
-all debugging sessions it runs well. But once it is started without
-debugging the error shows up. A typical example is a memory leak that
-becomes visible only when we turn off the debugging. If you foresee
-such situations you can still win. Simply use something equivalent to
-the following little program:
-
-@example
-#include <mcheck.h>
-#include <signal.h>
-
-static void
-enable (int sig)
-@{
- mtrace ();
- signal (SIGUSR1, enable);
-@}
-
-static void
-disable (int sig)
-@{
- muntrace ();
- signal (SIGUSR2, disable);
-@}
-
-int
-main (int argc, char *argv[])
-@{
- @dots{}
-
- signal (SIGUSR1, enable);
- signal (SIGUSR2, disable);
-
- @dots{}
-@}
-@end example
-
-I.e., the user can start the memory debugger any time s/he wants if the
-program was started with @code{MALLOC_TRACE} set in the environment.
-The output will of course not show the allocations which happened before
-the first signal but if there is a memory leak this will show up
-nevertheless.
-
-@node Interpreting the traces
-@subsubsection Interpreting the traces
-
-If you take a look at the output it will look similar to this:
-
-@example
-= Start
-@ [0x8048209] - 0x8064cc8
-@ [0x8048209] - 0x8064ce0
-@ [0x8048209] - 0x8064cf8
-@ [0x80481eb] + 0x8064c48 0x14
-@ [0x80481eb] + 0x8064c60 0x14
-@ [0x80481eb] + 0x8064c78 0x14
-@ [0x80481eb] + 0x8064c90 0x14
-= End
-@end example
-
-What this all means is not really important since the trace file is not
-meant to be read by a human. Therefore no attention is given to
-readability. Instead there is a program which comes with @theglibc{}
-which interprets the traces and outputs a summary in an
-user-friendly way. The program is called @code{mtrace} (it is in fact a
-Perl script) and it takes one or two arguments. In any case the name of
-the file with the trace output must be specified. If an optional
-argument precedes the name of the trace file this must be the name of
-the program which generated the trace.
-
-@example
-drepper$ mtrace tst-mtrace log
-No memory leaks.
-@end example
-
-In this case the program @code{tst-mtrace} was run and it produced a
-trace file @file{log}. The message printed by @code{mtrace} shows there
-are no problems with the code, all allocated memory was freed
-afterwards.
-
-If we call @code{mtrace} on the example trace given above we would get a
-different outout:
-
-@example
-drepper$ mtrace errlog
-- 0x08064cc8 Free 2 was never alloc'd 0x8048209
-- 0x08064ce0 Free 3 was never alloc'd 0x8048209
-- 0x08064cf8 Free 4 was never alloc'd 0x8048209
-
-Memory not freed:
------------------
- Address Size Caller
-0x08064c48 0x14 at 0x80481eb
-0x08064c60 0x14 at 0x80481eb
-0x08064c78 0x14 at 0x80481eb
-0x08064c90 0x14 at 0x80481eb
-@end example
-
-We have called @code{mtrace} with only one argument and so the script
-has no chance to find out what is meant with the addresses given in the
-trace. We can do better:
-
-@example
-drepper$ mtrace tst errlog
-- 0x08064cc8 Free 2 was never alloc'd /home/drepper/tst.c:39
-- 0x08064ce0 Free 3 was never alloc'd /home/drepper/tst.c:39
-- 0x08064cf8 Free 4 was never alloc'd /home/drepper/tst.c:39
-
-Memory not freed:
------------------
- Address Size Caller
-0x08064c48 0x14 at /home/drepper/tst.c:33
-0x08064c60 0x14 at /home/drepper/tst.c:33
-0x08064c78 0x14 at /home/drepper/tst.c:33
-0x08064c90 0x14 at /home/drepper/tst.c:33
-@end example
-
-Suddenly the output makes much more sense and the user can see
-immediately where the function calls causing the trouble can be found.
-
-Interpreting this output is not complicated. There are at most two
-different situations being detected. First, @code{free} was called for
-pointers which were never returned by one of the allocation functions.
-This is usually a very bad problem and what this looks like is shown in
-the first three lines of the output. Situations like this are quite
-rare and if they appear they show up very drastically: the program
-normally crashes.
-
-The other situation which is much harder to detect are memory leaks. As
-you can see in the output the @code{mtrace} function collects all this
-information and so can say that the program calls an allocation function
-from line 33 in the source file @file{/home/drepper/tst-mtrace.c} four
-times without freeing this memory before the program terminates.
-Whether this is a real problem remains to be investigated.
-
-@node Replacing malloc
-@subsection Replacing @code{malloc}
-
-@cindex @code{malloc} replacement
-@cindex @code{LD_PRELOAD} and @code{malloc}
-@cindex alternative @code{malloc} implementations
-@cindex customizing @code{malloc}
-@cindex interposing @code{malloc}
-@cindex preempting @code{malloc}
-@cindex replacing @code{malloc}
-@Theglibc{} supports replacing the built-in @code{malloc} implementation
-with a different allocator with the same interface. For dynamically
-linked programs, this happens through ELF symbol interposition, either
-using shared object dependencies or @code{LD_PRELOAD}. For static
-linking, the @code{malloc} replacement library must be linked in before
-linking against @code{libc.a} (explicitly or implicitly).
-
-@strong{Note:} Failure to provide a complete set of replacement
-functions (that is, all the functions used by the application,
-@theglibc{}, and other linked-in libraries) can lead to static linking
-failures, and, at run time, to heap corruption and application crashes.
-
-The minimum set of functions which has to be provided by a custom
-@code{malloc} is given in the table below.
-
-@table @code
-@item malloc
-@item free
-@item calloc
-@item realloc
-@end table
-
-These @code{malloc}-related functions are required for @theglibc{} to
-work.@footnote{Versions of @theglibc{} before 2.25 required that a
-custom @code{malloc} defines @code{__libc_memalign} (with the same
-interface as the @code{memalign} function).}
-
-The @code{malloc} implementation in @theglibc{} provides additional
-functionality not used by the library itself, but which is often used by
-other system libraries and applications. A general-purpose replacement
-@code{malloc} implementation should provide definitions of these
-functions, too. Their names are listed in the following table.
-
-@table @code
-@item aligned_alloc
-@item malloc_usable_size
-@item memalign
-@item posix_memalign
-@item pvalloc
-@item valloc
-@end table
-
-In addition, very old applications may use the obsolete @code{cfree}
-function.
-
-Further @code{malloc}-related functions such as @code{mallopt} or
-@code{mallinfo} will not have any effect or return incorrect statistics
-when a replacement @code{malloc} is in use. However, failure to replace
-these functions typically does not result in crashes or other incorrect
-application behavior, but may result in static linking failures.
-
-@node Obstacks
-@subsection Obstacks
-@cindex obstacks
-
-An @dfn{obstack} is a pool of memory containing a stack of objects. You
-can create any number of separate obstacks, and then allocate objects in
-specified obstacks. Within each obstack, the last object allocated must
-always be the first one freed, but distinct obstacks are independent of
-each other.
-
-Aside from this one constraint of order of freeing, obstacks are totally
-general: an obstack can contain any number of objects of any size. They
-are implemented with macros, so allocation is usually very fast as long as
-the objects are usually small. And the only space overhead per object is
-the padding needed to start each object on a suitable boundary.
-
-@menu
-* Creating Obstacks:: How to declare an obstack in your program.
-* Preparing for Obstacks:: Preparations needed before you can
- use obstacks.
-* Allocation in an Obstack:: Allocating objects in an obstack.
-* Freeing Obstack Objects:: Freeing objects in an obstack.
-* Obstack Functions:: The obstack functions are both
- functions and macros.
-* Growing Objects:: Making an object bigger by stages.
-* Extra Fast Growing:: Extra-high-efficiency (though more
- complicated) growing objects.
-* Status of an Obstack:: Inquiries about the status of an obstack.
-* Obstacks Data Alignment:: Controlling alignment of objects in obstacks.
-* Obstack Chunks:: How obstacks obtain and release chunks;
- efficiency considerations.
-* Summary of Obstacks::
-@end menu
-
-@node Creating Obstacks
-@subsubsection Creating Obstacks
-
-The utilities for manipulating obstacks are declared in the header
-file @file{obstack.h}.
-@pindex obstack.h
-
-@comment obstack.h
-@comment GNU
-@deftp {Data Type} {struct obstack}
-An obstack is represented by a data structure of type @code{struct
-obstack}. This structure has a small fixed size; it records the status
-of the obstack and how to find the space in which objects are allocated.
-It does not contain any of the objects themselves. You should not try
-to access the contents of the structure directly; use only the functions
-described in this chapter.
-@end deftp
-
-You can declare variables of type @code{struct obstack} and use them as
-obstacks, or you can allocate obstacks dynamically like any other kind
-of object. Dynamic allocation of obstacks allows your program to have a
-variable number of different stacks. (You can even allocate an
-obstack structure in another obstack, but this is rarely useful.)
-
-All the functions that work with obstacks require you to specify which
-obstack to use. You do this with a pointer of type @code{struct obstack
-*}. In the following, we often say ``an obstack'' when strictly
-speaking the object at hand is such a pointer.
-
-The objects in the obstack are packed into large blocks called
-@dfn{chunks}. The @code{struct obstack} structure points to a chain of
-the chunks currently in use.
-
-The obstack library obtains a new chunk whenever you allocate an object
-that won't fit in the previous chunk. Since the obstack library manages
-chunks automatically, you don't need to pay much attention to them, but
-you do need to supply a function which the obstack library should use to
-get a chunk. Usually you supply a function which uses @code{malloc}
-directly or indirectly. You must also supply a function to free a chunk.
-These matters are described in the following section.
-
-@node Preparing for Obstacks
-@subsubsection Preparing for Using Obstacks
-
-Each source file in which you plan to use the obstack functions
-must include the header file @file{obstack.h}, like this:
-
-@smallexample
-#include <obstack.h>
-@end smallexample
-
-@findex obstack_chunk_alloc
-@findex obstack_chunk_free
-Also, if the source file uses the macro @code{obstack_init}, it must
-declare or define two functions or macros that will be called by the
-obstack library. One, @code{obstack_chunk_alloc}, is used to allocate
-the chunks of memory into which objects are packed. The other,
-@code{obstack_chunk_free}, is used to return chunks when the objects in
-them are freed. These macros should appear before any use of obstacks
-in the source file.
-
-Usually these are defined to use @code{malloc} via the intermediary
-@code{xmalloc} (@pxref{Unconstrained Allocation}). This is done with
-the following pair of macro definitions:
-
-@smallexample
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-@end smallexample
-
-@noindent
-Though the memory you get using obstacks really comes from @code{malloc},
-using obstacks is faster because @code{malloc} is called less often, for
-larger blocks of memory. @xref{Obstack Chunks}, for full details.
-
-At run time, before the program can use a @code{struct obstack} object
-as an obstack, it must initialize the obstack by calling
-@code{obstack_init}.
-
-@comment obstack.h
-@comment GNU
-@deftypefun int obstack_init (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{@acsmem{}}}
-@c obstack_init @mtsrace:obstack-ptr @acsmem
-@c _obstack_begin @acsmem
-@c chunkfun = obstack_chunk_alloc (suggested malloc)
-@c freefun = obstack_chunk_free (suggested free)
-@c *chunkfun @acsmem
-@c obstack_chunk_alloc user-supplied
-@c *obstack_alloc_failed_handler user-supplied
-@c -> print_and_abort (default)
-@c
-@c print_and_abort
-@c _ dup @ascuintl
-@c fxprintf dup @asucorrupt @aculock @acucorrupt
-@c exit @acucorrupt?
-Initialize obstack @var{obstack-ptr} for allocation of objects. This
-function calls the obstack's @code{obstack_chunk_alloc} function. If
-allocation of memory fails, the function pointed to by
-@code{obstack_alloc_failed_handler} is called. The @code{obstack_init}
-function always returns 1 (Compatibility notice: Former versions of
-obstack returned 0 if allocation failed).
-@end deftypefun
-
-Here are two examples of how to allocate the space for an obstack and
-initialize it. First, an obstack that is a static variable:
-
-@smallexample
-static struct obstack myobstack;
-@dots{}
-obstack_init (&myobstack);
-@end smallexample
-
-@noindent
-Second, an obstack that is itself dynamically allocated:
-
-@smallexample
-struct obstack *myobstack_ptr
- = (struct obstack *) xmalloc (sizeof (struct obstack));
-
-obstack_init (myobstack_ptr);
-@end smallexample
-
-@comment obstack.h
-@comment GNU
-@defvar obstack_alloc_failed_handler
-The value of this variable is a pointer to a function that
-@code{obstack} uses when @code{obstack_chunk_alloc} fails to allocate
-memory. The default action is to print a message and abort.
-You should supply a function that either calls @code{exit}
-(@pxref{Program Termination}) or @code{longjmp} (@pxref{Non-Local
-Exits}) and doesn't return.
-
-@smallexample
-void my_obstack_alloc_failed (void)
-@dots{}
-obstack_alloc_failed_handler = &my_obstack_alloc_failed;
-@end smallexample
-
-@end defvar
-
-@node Allocation in an Obstack
-@subsubsection Allocation in an Obstack
-@cindex allocation (obstacks)
-
-The most direct way to allocate an object in an obstack is with
-@code{obstack_alloc}, which is invoked almost like @code{malloc}.
-
-@comment obstack.h
-@comment GNU
-@deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_alloc @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_blank dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
-This allocates an uninitialized block of @var{size} bytes in an obstack
-and returns its address. Here @var{obstack-ptr} specifies which obstack
-to allocate the block in; it is the address of the @code{struct obstack}
-object which represents the obstack. Each obstack function or macro
-requires you to specify an @var{obstack-ptr} as the first argument.
-
-This function calls the obstack's @code{obstack_chunk_alloc} function if
-it needs to allocate a new chunk of memory; it calls
-@code{obstack_alloc_failed_handler} if allocation of memory by
-@code{obstack_chunk_alloc} failed.
-@end deftypefun
-
-For example, here is a function that allocates a copy of a string @var{str}
-in a specific obstack, which is in the variable @code{string_obstack}:
-
-@smallexample
-struct obstack string_obstack;
-
-char *
-copystring (char *string)
-@{
- size_t len = strlen (string) + 1;
- char *s = (char *) obstack_alloc (&string_obstack, len);
- memcpy (s, string, len);
- return s;
-@}
-@end smallexample
-
-To allocate a block with specified contents, use the function
-@code{obstack_copy}, declared like this:
-
-@comment obstack.h
-@comment GNU
-@deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_copy @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_grow dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
-This allocates a block and initializes it by copying @var{size}
-bytes of data starting at @var{address}. It calls
-@code{obstack_alloc_failed_handler} if allocation of memory by
-@code{obstack_chunk_alloc} failed.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_copy0 @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_grow0 dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
-Like @code{obstack_copy}, but appends an extra byte containing a null
-character. This extra byte is not counted in the argument @var{size}.
-@end deftypefun
-
-The @code{obstack_copy0} function is convenient for copying a sequence
-of characters into an obstack as a null-terminated string. Here is an
-example of its use:
-
-@smallexample
-char *
-obstack_savestring (char *addr, int size)
-@{
- return obstack_copy0 (&myobstack, addr, size);
-@}
-@end smallexample
-
-@noindent
-Contrast this with the previous example of @code{savestring} using
-@code{malloc} (@pxref{Basic Allocation}).
-
-@node Freeing Obstack Objects
-@subsubsection Freeing Objects in an Obstack
-@cindex freeing (obstacks)
-
-To free an object allocated in an obstack, use the function
-@code{obstack_free}. Since the obstack is a stack of objects, freeing
-one object automatically frees all other objects allocated more recently
-in the same obstack.
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
-@c obstack_free @mtsrace:obstack-ptr @acucorrupt
-@c (obstack_free) @mtsrace:obstack-ptr @acucorrupt
-@c *freefun dup user-supplied
-If @var{object} is a null pointer, everything allocated in the obstack
-is freed. Otherwise, @var{object} must be the address of an object
-allocated in the obstack. Then @var{object} is freed, along with
-everything allocated in @var{obstack-ptr} since @var{object}.
-@end deftypefun
-
-Note that if @var{object} is a null pointer, the result is an
-uninitialized obstack. To free all memory in an obstack but leave it
-valid for further allocation, call @code{obstack_free} with the address
-of the first object allocated on the obstack:
-
-@smallexample
-obstack_free (obstack_ptr, first_object_allocated_ptr);
-@end smallexample
-
-Recall that the objects in an obstack are grouped into chunks. When all
-the objects in a chunk become free, the obstack library automatically
-frees the chunk (@pxref{Preparing for Obstacks}). Then other
-obstacks, or non-obstack allocation, can reuse the space of the chunk.
-
-@node Obstack Functions
-@subsubsection Obstack Functions and Macros
-@cindex macros
-
-The interfaces for using obstacks may be defined either as functions or
-as macros, depending on the compiler. The obstack facility works with
-all C compilers, including both @w{ISO C} and traditional C, but there are
-precautions you must take if you plan to use compilers other than GNU C.
-
-If you are using an old-fashioned @w{non-ISO C} compiler, all the obstack
-``functions'' are actually defined only as macros. You can call these
-macros like functions, but you cannot use them in any other way (for
-example, you cannot take their address).
-
-Calling the macros requires a special precaution: namely, the first
-operand (the obstack pointer) may not contain any side effects, because
-it may be computed more than once. For example, if you write this:
-
-@smallexample
-obstack_alloc (get_obstack (), 4);
-@end smallexample
-
-@noindent
-you will find that @code{get_obstack} may be called several times.
-If you use @code{*obstack_list_ptr++} as the obstack pointer argument,
-you will get very strange results since the incrementation may occur
-several times.
-
-In @w{ISO C}, each function has both a macro definition and a function
-definition. The function definition is used if you take the address of the
-function without calling it. An ordinary call uses the macro definition by
-default, but you can request the function definition instead by writing the
-function name in parentheses, as shown here:
-
-@smallexample
-char *x;
-void *(*funcp) ();
-/* @r{Use the macro}. */
-x = (char *) obstack_alloc (obptr, size);
-/* @r{Call the function}. */
-x = (char *) (obstack_alloc) (obptr, size);
-/* @r{Take the address of the function}. */
-funcp = obstack_alloc;
-@end smallexample
-
-@noindent
-This is the same situation that exists in @w{ISO C} for the standard library
-functions. @xref{Macro Definitions}.
-
-@strong{Warning:} When you do use the macros, you must observe the
-precaution of avoiding side effects in the first operand, even in @w{ISO C}.
-
-If you use the GNU C compiler, this precaution is not necessary, because
-various language extensions in GNU C permit defining the macros so as to
-compute each argument only once.
-
-@node Growing Objects
-@subsubsection Growing Objects
-@cindex growing objects (in obstacks)
-@cindex changing the size of a block (obstacks)
-
-Because memory in obstack chunks is used sequentially, it is possible to
-build up an object step by step, adding one or more bytes at a time to the
-end of the object. With this technique, you do not need to know how much
-data you will put in the object until you come to the end of it. We call
-this the technique of @dfn{growing objects}. The special functions
-for adding data to the growing object are described in this section.
-
-You don't need to do anything special when you start to grow an object.
-Using one of the functions to add data to the object automatically
-starts it. However, it is necessary to say explicitly when the object is
-finished. This is done with the function @code{obstack_finish}.
-
-The actual address of the object thus built up is not known until the
-object is finished. Until then, it always remains possible that you will
-add so much data that the object must be copied into a new chunk.
-
-While the obstack is in use for a growing object, you cannot use it for
-ordinary allocation of another object. If you try to do so, the space
-already added to the growing object will become part of the other object.
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_blank @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c _obstack_newchunk @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c *chunkfun dup @acsmem
-@c *obstack_alloc_failed_handler dup user-supplied
-@c *freefun
-@c obstack_blank_fast dup @mtsrace:obstack-ptr
-The most basic function for adding to a growing object is
-@code{obstack_blank}, which adds space without initializing it.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c memcpy ok
-To add a block of initialized space, use @code{obstack_grow}, which is
-the growing-object analogue of @code{obstack_copy}. It adds @var{size}
-bytes of data to the growing object, copying the contents from
-@var{data}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_grow0 @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c (no sequence point between storing NUL and incrementing next_free)
-@c (multiple changes to next_free => @acucorrupt)
-@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c memcpy ok
-This is the growing-object analogue of @code{obstack_copy0}. It adds
-@var{size} bytes copied from @var{data}, followed by an additional null
-character.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_1grow @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_1grow_fast dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-To add one character at a time, use the function @code{obstack_1grow}.
-It adds a single byte containing @var{c} to the growing object.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_ptr_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_ptr_grow_fast dup @mtsrace:obstack-ptr
-Adding the value of a pointer one can use the function
-@code{obstack_ptr_grow}. It adds @code{sizeof (void *)} bytes
-containing the value of @var{data}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_int_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c obstack_int_grow_fast dup @mtsrace:obstack-ptr
-A single value of type @code{int} can be added by using the
-@code{obstack_int_grow} function. It adds @code{sizeof (int)} bytes to
-the growing object and initializes them with the value of @var{data}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
-@c obstack_finish @mtsrace:obstack-ptr @acucorrupt
-When you are finished growing the object, use the function
-@code{obstack_finish} to close it off and return its final address.
-
-Once you have finished the object, the obstack is available for ordinary
-allocation or for growing another object.
-
-This function can return a null pointer under the same conditions as
-@code{obstack_alloc} (@pxref{Allocation in an Obstack}).
-@end deftypefun
-
-When you build an object by growing it, you will probably need to know
-afterward how long it became. You need not keep track of this as you grow
-the object, because you can find out the length from the obstack just
-before finishing the object with the function @code{obstack_object_size},
-declared as follows:
-
-@comment obstack.h
-@comment GNU
-@deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
-This function returns the current size of the growing object, in bytes.
-Remember to call this function @emph{before} finishing the object.
-After it is finished, @code{obstack_object_size} will return zero.
-@end deftypefun
-
-If you have started growing an object and wish to cancel it, you should
-finish it and then free it, like this:
-
-@smallexample
-obstack_free (obstack_ptr, obstack_finish (obstack_ptr));
-@end smallexample
-
-@noindent
-This has no effect if no object was growing.
-
-@cindex shrinking objects
-You can use @code{obstack_blank} with a negative size argument to make
-the current object smaller. Just don't try to shrink it beyond zero
-length---there's no telling what will happen if you do that.
-
-@node Extra Fast Growing
-@subsubsection Extra Fast Growing Objects
-@cindex efficiency and obstacks
-
-The usual functions for growing objects incur overhead for checking
-whether there is room for the new growth in the current chunk. If you
-are frequently constructing objects in small steps of growth, this
-overhead can be significant.
-
-You can reduce the overhead by using special ``fast growth''
-functions that grow the object without checking. In order to have a
-robust program, you must do the checking yourself. If you do this checking
-in the simplest way each time you are about to add data to the object, you
-have not saved anything, because that is what the ordinary growth
-functions do. But if you can arrange to check less often, or check
-more efficiently, then you make the program faster.
-
-The function @code{obstack_room} returns the amount of room available
-in the current chunk. It is declared as follows:
-
-@comment obstack.h
-@comment GNU
-@deftypefun int obstack_room (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
-This returns the number of bytes that can be added safely to the current
-growing object (or to an object about to be started) in obstack
-@var{obstack-ptr} using the fast growth functions.
-@end deftypefun
-
-While you know there is room, you can use these fast growth functions
-for adding data to a growing object:
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
-@c obstack_1grow_fast @mtsrace:obstack-ptr @acucorrupt @acsmem
-@c (no sequence point between copying c and incrementing next_free)
-The function @code{obstack_1grow_fast} adds one byte containing the
-character @var{c} to the growing object in obstack @var{obstack-ptr}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
-@c obstack_ptr_grow_fast @mtsrace:obstack-ptr
-The function @code{obstack_ptr_grow_fast} adds @code{sizeof (void *)}
-bytes containing the value of @var{data} to the growing object in
-obstack @var{obstack-ptr}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
-@c obstack_int_grow_fast @mtsrace:obstack-ptr
-The function @code{obstack_int_grow_fast} adds @code{sizeof (int)} bytes
-containing the value of @var{data} to the growing object in obstack
-@var{obstack-ptr}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
-@c obstack_blank_fast @mtsrace:obstack-ptr
-The function @code{obstack_blank_fast} adds @var{size} bytes to the
-growing object in obstack @var{obstack-ptr} without initializing them.
-@end deftypefun
-
-When you check for space using @code{obstack_room} and there is not
-enough room for what you want to add, the fast growth functions
-are not safe. In this case, simply use the corresponding ordinary
-growth function instead. Very soon this will copy the object to a
-new chunk; then there will be lots of room available again.
-
-So, each time you use an ordinary growth function, check afterward for
-sufficient space using @code{obstack_room}. Once the object is copied
-to a new chunk, there will be plenty of space again, so the program will
-start using the fast growth functions again.
-
-Here is an example:
-
-@smallexample
-@group
-void
-add_string (struct obstack *obstack, const char *ptr, int len)
-@{
- while (len > 0)
- @{
- int room = obstack_room (obstack);
- if (room == 0)
- @{
- /* @r{Not enough room. Add one character slowly,}
- @r{which may copy to a new chunk and make room.} */
- obstack_1grow (obstack, *ptr++);
- len--;
- @}
- else
- @{
- if (room > len)
- room = len;
- /* @r{Add fast as much as we have room for.} */
- len -= room;
- while (room-- > 0)
- obstack_1grow_fast (obstack, *ptr++);
- @}
- @}
-@}
-@end group
-@end smallexample
-
-@node Status of an Obstack
-@subsubsection Status of an Obstack
-@cindex obstack status
-@cindex status of obstack
-
-Here are functions that provide information on the current status of
-allocation in an obstack. You can use them to learn about an object while
-still growing it.
-
-@comment obstack.h
-@comment GNU
-@deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
-This function returns the tentative address of the beginning of the
-currently growing object in @var{obstack-ptr}. If you finish the object
-immediately, it will have that address. If you make it larger first, it
-may outgrow the current chunk---then its address will change!
-
-If no object is growing, this value says where the next object you
-allocate will start (once again assuming it fits in the current
-chunk).
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
-This function returns the address of the first free byte in the current
-chunk of obstack @var{obstack-ptr}. This is the end of the currently
-growing object. If no object is growing, @code{obstack_next_free}
-returns the same value as @code{obstack_base}.
-@end deftypefun
-
-@comment obstack.h
-@comment GNU
-@deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
-@c dup
-@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
-This function returns the size in bytes of the currently growing object.
-This is equivalent to
-
-@smallexample
-obstack_next_free (@var{obstack-ptr}) - obstack_base (@var{obstack-ptr})
-@end smallexample
-@end deftypefun
-
-@node Obstacks Data Alignment
-@subsubsection Alignment of Data in Obstacks
-@cindex alignment (in obstacks)
-
-Each obstack has an @dfn{alignment boundary}; each object allocated in
-the obstack automatically starts on an address that is a multiple of the
-specified boundary. By default, this boundary is aligned so that
-the object can hold any type of data.
-
-To access an obstack's alignment boundary, use the macro
-@code{obstack_alignment_mask}, whose function prototype looks like
-this:
-
-@comment obstack.h
-@comment GNU
-@deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-The value is a bit mask; a bit that is 1 indicates that the corresponding
-bit in the address of an object should be 0. The mask value should be one
-less than a power of 2; the effect is that all object addresses are
-multiples of that power of 2. The default value of the mask is a value
-that allows aligned objects to hold any type of data: for example, if
-its value is 3, any type of data can be stored at locations whose
-addresses are multiples of 4. A mask value of 0 means an object can start
-on any multiple of 1 (that is, no alignment is required).
-
-The expansion of the macro @code{obstack_alignment_mask} is an lvalue,
-so you can alter the mask by assignment. For example, this statement:
-
-@smallexample
-obstack_alignment_mask (obstack_ptr) = 0;
-@end smallexample
-
-@noindent
-has the effect of turning off alignment processing in the specified obstack.
-@end deftypefn
-
-Note that a change in alignment mask does not take effect until
-@emph{after} the next time an object is allocated or finished in the
-obstack. If you are not growing an object, you can make the new
-alignment mask take effect immediately by calling @code{obstack_finish}.
-This will finish a zero-length object and then do proper alignment for
-the next object.
-
-@node Obstack Chunks
-@subsubsection Obstack Chunks
-@cindex efficiency of chunks
-@cindex chunks
-
-Obstacks work by allocating space for themselves in large chunks, and
-then parceling out space in the chunks to satisfy your requests. Chunks
-are normally 4096 bytes long unless you specify a different chunk size.
-The chunk size includes 8 bytes of overhead that are not actually used
-for storing objects. Regardless of the specified size, longer chunks
-will be allocated when necessary for long objects.
-
-The obstack library allocates chunks by calling the function
-@code{obstack_chunk_alloc}, which you must define. When a chunk is no
-longer needed because you have freed all the objects in it, the obstack
-library frees the chunk by calling @code{obstack_chunk_free}, which you
-must also define.
-
-These two must be defined (as macros) or declared (as functions) in each
-source file that uses @code{obstack_init} (@pxref{Creating Obstacks}).
-Most often they are defined as macros like this:
-
-@smallexample
-#define obstack_chunk_alloc malloc
-#define obstack_chunk_free free
-@end smallexample
-
-Note that these are simple macros (no arguments). Macro definitions with
-arguments will not work! It is necessary that @code{obstack_chunk_alloc}
-or @code{obstack_chunk_free}, alone, expand into a function name if it is
-not itself a function name.
-
-If you allocate chunks with @code{malloc}, the chunk size should be a
-power of 2. The default chunk size, 4096, was chosen because it is long
-enough to satisfy many typical requests on the obstack yet short enough
-not to waste too much memory in the portion of the last chunk not yet used.
-
-@comment obstack.h
-@comment GNU
-@deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-This returns the chunk size of the given obstack.
-@end deftypefn
-
-Since this macro expands to an lvalue, you can specify a new chunk size by
-assigning it a new value. Doing so does not affect the chunks already
-allocated, but will change the size of chunks allocated for that particular
-obstack in the future. It is unlikely to be useful to make the chunk size
-smaller, but making it larger might improve efficiency if you are
-allocating many objects whose size is comparable to the chunk size. Here
-is how to do so cleanly:
-
-@smallexample
-if (obstack_chunk_size (obstack_ptr) < @var{new-chunk-size})
- obstack_chunk_size (obstack_ptr) = @var{new-chunk-size};
-@end smallexample
-
-@node Summary of Obstacks
-@subsubsection Summary of Obstack Functions
-
-Here is a summary of all the functions associated with obstacks. Each
-takes the address of an obstack (@code{struct obstack *}) as its first
-argument.
-
-@table @code
-@item void obstack_init (struct obstack *@var{obstack-ptr})
-Initialize use of an obstack. @xref{Creating Obstacks}.
-
-@item void *obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
-Allocate an object of @var{size} uninitialized bytes.
-@xref{Allocation in an Obstack}.
-
-@item void *obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
-Allocate an object of @var{size} bytes, with contents copied from
-@var{address}. @xref{Allocation in an Obstack}.
-
-@item void *obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
-Allocate an object of @var{size}+1 bytes, with @var{size} of them copied
-from @var{address}, followed by a null character at the end.
-@xref{Allocation in an Obstack}.
-
-@item void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
-Free @var{object} (and everything allocated in the specified obstack
-more recently than @var{object}). @xref{Freeing Obstack Objects}.
-
-@item void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
-Add @var{size} uninitialized bytes to a growing object.
-@xref{Growing Objects}.
-
-@item void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
-Add @var{size} bytes, copied from @var{address}, to a growing object.
-@xref{Growing Objects}.
-
-@item void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
-Add @var{size} bytes, copied from @var{address}, to a growing object,
-and then add another byte containing a null character. @xref{Growing
-Objects}.
-
-@item void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{data-char})
-Add one byte containing @var{data-char} to a growing object.
-@xref{Growing Objects}.
-
-@item void *obstack_finish (struct obstack *@var{obstack-ptr})
-Finalize the object that is growing and return its permanent address.
-@xref{Growing Objects}.
-
-@item int obstack_object_size (struct obstack *@var{obstack-ptr})
-Get the current size of the currently growing object. @xref{Growing
-Objects}.
-
-@item void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
-Add @var{size} uninitialized bytes to a growing object without checking
-that there is enough room. @xref{Extra Fast Growing}.
-
-@item void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{data-char})
-Add one byte containing @var{data-char} to a growing object without
-checking that there is enough room. @xref{Extra Fast Growing}.
-
-@item int obstack_room (struct obstack *@var{obstack-ptr})
-Get the amount of room now available for growing the current object.
-@xref{Extra Fast Growing}.
-
-@item int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
-The mask used for aligning the beginning of an object. This is an
-lvalue. @xref{Obstacks Data Alignment}.
-
-@item int obstack_chunk_size (struct obstack *@var{obstack-ptr})
-The size for allocating chunks. This is an lvalue. @xref{Obstack Chunks}.
-
-@item void *obstack_base (struct obstack *@var{obstack-ptr})
-Tentative starting address of the currently growing object.
-@xref{Status of an Obstack}.
-
-@item void *obstack_next_free (struct obstack *@var{obstack-ptr})
-Address just after the end of the currently growing object.
-@xref{Status of an Obstack}.
-@end table
-
-@node Variable Size Automatic
-@subsection Automatic Storage with Variable Size
-@cindex automatic freeing
-@cindex @code{alloca} function
-@cindex automatic storage with variable size
-
-The function @code{alloca} supports a kind of half-dynamic allocation in
-which blocks are allocated dynamically but freed automatically.
-
-Allocating a block with @code{alloca} is an explicit action; you can
-allocate as many blocks as you wish, and compute the size at run time. But
-all the blocks are freed when you exit the function that @code{alloca} was
-called from, just as if they were automatic variables declared in that
-function. There is no way to free the space explicitly.
-
-The prototype for @code{alloca} is in @file{stdlib.h}. This function is
-a BSD extension.
-@pindex stdlib.h
-
-@comment stdlib.h
-@comment GNU, BSD
-@deftypefun {void *} alloca (size_t @var{size})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-The return value of @code{alloca} is the address of a block of @var{size}
-bytes of memory, allocated in the stack frame of the calling function.
-@end deftypefun
-
-Do not use @code{alloca} inside the arguments of a function call---you
-will get unpredictable results, because the stack space for the
-@code{alloca} would appear on the stack in the middle of the space for
-the function arguments. An example of what to avoid is @code{foo (x,
-alloca (4), y)}.
-@c This might get fixed in future versions of GCC, but that won't make
-@c it safe with compilers generally.
-
-@menu
-* Alloca Example:: Example of using @code{alloca}.
-* Advantages of Alloca:: Reasons to use @code{alloca}.
-* Disadvantages of Alloca:: Reasons to avoid @code{alloca}.
-* GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative
- method of allocating dynamically and
- freeing automatically.
-@end menu
-
-@node Alloca Example
-@subsubsection @code{alloca} Example
-
-As an example of the use of @code{alloca}, here is a function that opens
-a file name made from concatenating two argument strings, and returns a
-file descriptor or minus one signifying failure:
-
-@smallexample
-int
-open2 (char *str1, char *str2, int flags, int mode)
-@{
- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
- stpcpy (stpcpy (name, str1), str2);
- return open (name, flags, mode);
-@}
-@end smallexample
-
-@noindent
-Here is how you would get the same results with @code{malloc} and
-@code{free}:
-
-@smallexample
-int
-open2 (char *str1, char *str2, int flags, int mode)
-@{
- char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1);
- int desc;
- if (name == 0)
- fatal ("virtual memory exceeded");
- stpcpy (stpcpy (name, str1), str2);
- desc = open (name, flags, mode);
- free (name);
- return desc;
-@}
-@end smallexample
-
-As you can see, it is simpler with @code{alloca}. But @code{alloca} has
-other, more important advantages, and some disadvantages.
-
-@node Advantages of Alloca
-@subsubsection Advantages of @code{alloca}
-
-Here are the reasons why @code{alloca} may be preferable to @code{malloc}:
-
-@itemize @bullet
-@item
-Using @code{alloca} wastes very little space and is very fast. (It is
-open-coded by the GNU C compiler.)
-
-@item
-Since @code{alloca} does not have separate pools for different sizes of
-blocks, space used for any size block can be reused for any other size.
-@code{alloca} does not cause memory fragmentation.
-
-@item
-@cindex longjmp
-Nonlocal exits done with @code{longjmp} (@pxref{Non-Local Exits})
-automatically free the space allocated with @code{alloca} when they exit
-through the function that called @code{alloca}. This is the most
-important reason to use @code{alloca}.
-
-To illustrate this, suppose you have a function
-@code{open_or_report_error} which returns a descriptor, like
-@code{open}, if it succeeds, but does not return to its caller if it
-fails. If the file cannot be opened, it prints an error message and
-jumps out to the command level of your program using @code{longjmp}.
-Let's change @code{open2} (@pxref{Alloca Example}) to use this
-subroutine:@refill
-
-@smallexample
-int
-open2 (char *str1, char *str2, int flags, int mode)
-@{
- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
- stpcpy (stpcpy (name, str1), str2);
- return open_or_report_error (name, flags, mode);
-@}
-@end smallexample
-
-@noindent
-Because of the way @code{alloca} works, the memory it allocates is
-freed even when an error occurs, with no special effort required.
-
-By contrast, the previous definition of @code{open2} (which uses
-@code{malloc} and @code{free}) would develop a memory leak if it were
-changed in this way. Even if you are willing to make more changes to
-fix it, there is no easy way to do so.
-@end itemize
-
-@node Disadvantages of Alloca
-@subsubsection Disadvantages of @code{alloca}
-
-@cindex @code{alloca} disadvantages
-@cindex disadvantages of @code{alloca}
-These are the disadvantages of @code{alloca} in comparison with
-@code{malloc}:
-
-@itemize @bullet
-@item
-If you try to allocate more memory than the machine can provide, you
-don't get a clean error message. Instead you get a fatal signal like
-the one you would get from an infinite recursion; probably a
-segmentation violation (@pxref{Program Error Signals}).
-
-@item
-Some @nongnusystems{} fail to support @code{alloca}, so it is less
-portable. However, a slower emulation of @code{alloca} written in C
-is available for use on systems with this deficiency.
-@end itemize
-
-@node GNU C Variable-Size Arrays
-@subsubsection GNU C Variable-Size Arrays
-@cindex variable-sized arrays
-
-In GNU C, you can replace most uses of @code{alloca} with an array of
-variable size. Here is how @code{open2} would look then:
-
-@smallexample
-int open2 (char *str1, char *str2, int flags, int mode)
-@{
- char name[strlen (str1) + strlen (str2) + 1];
- stpcpy (stpcpy (name, str1), str2);
- return open (name, flags, mode);
-@}
-@end smallexample
-
-But @code{alloca} is not always equivalent to a variable-sized array, for
-several reasons:
-
-@itemize @bullet
-@item
-A variable size array's space is freed at the end of the scope of the
-name of the array. The space allocated with @code{alloca}
-remains until the end of the function.
-
-@item
-It is possible to use @code{alloca} within a loop, allocating an
-additional block on each iteration. This is impossible with
-variable-sized arrays.
-@end itemize
-
-@strong{NB:} If you mix use of @code{alloca} and variable-sized arrays
-within one function, exiting a scope in which a variable-sized array was
-declared frees all blocks allocated with @code{alloca} during the
-execution of that scope.
-
-
-@node Resizing the Data Segment
-@section Resizing the Data Segment
-
-The symbols in this section are declared in @file{unistd.h}.
-
-You will not normally use the functions in this section, because the
-functions described in @ref{Memory Allocation} are easier to use. Those
-are interfaces to a @glibcadj{} memory allocator that uses the
-functions below itself. The functions below are simple interfaces to
-system calls.
-
-@comment unistd.h
-@comment BSD
-@deftypefun int brk (void *@var{addr})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-@code{brk} sets the high end of the calling process' data segment to
-@var{addr}.
-
-The address of the end of a segment is defined to be the address of the
-last byte in the segment plus 1.
-
-The function has no effect if @var{addr} is lower than the low end of
-the data segment. (This is considered success, by the way.)
-
-The function fails if it would cause the data segment to overlap another
-segment or exceed the process' data storage limit (@pxref{Limits on
-Resources}).
-
-The function is named for a common historical case where data storage
-and the stack are in the same segment. Data storage allocation grows
-upward from the bottom of the segment while the stack grows downward
-toward it from the top of the segment and the curtain between them is
-called the @dfn{break}.
-
-The return value is zero on success. On failure, the return value is
-@code{-1} and @code{errno} is set accordingly. The following @code{errno}
-values are specific to this function:
-
-@table @code
-@item ENOMEM
-The request would cause the data segment to overlap another segment or
-exceed the process' data storage limit.
-@end table
-
-@c The Brk system call in Linux (as opposed to the GNU C Library function)
-@c is considerably different. It always returns the new end of the data
-@c segment, whether it succeeds or fails. The GNU C library Brk determines
-@c it's a failure if and only if the system call returns an address less
-@c than the address requested.
-
-@end deftypefun
-
-
-@comment unistd.h
-@comment BSD
-@deftypefun void *sbrk (ptrdiff_t @var{delta})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-This function is the same as @code{brk} except that you specify the new
-end of the data segment as an offset @var{delta} from the current end
-and on success the return value is the address of the resulting end of
-the data segment instead of zero.
-
-This means you can use @samp{sbrk(0)} to find out what the current end
-of the data segment is.
-
-@end deftypefun
-
-
-
-@node Locking Pages
-@section Locking Pages
-@cindex locking pages
-@cindex memory lock
-@cindex paging
-
-You can tell the system to associate a particular virtual memory page
-with a real page frame and keep it that way --- i.e., cause the page to
-be paged in if it isn't already and mark it so it will never be paged
-out and consequently will never cause a page fault. This is called
-@dfn{locking} a page.
-
-The functions in this chapter lock and unlock the calling process'
-pages.
-
-@menu
-* Why Lock Pages:: Reasons to read this section.
-* Locked Memory Details:: Everything you need to know locked
- memory
-* Page Lock Functions:: Here's how to do it.
-@end menu
-
-@node Why Lock Pages
-@subsection Why Lock Pages
-
-Because page faults cause paged out pages to be paged in transparently,
-a process rarely needs to be concerned about locking pages. However,
-there are two reasons people sometimes are:
-
-@itemize @bullet
-
-@item
-Speed. A page fault is transparent only insofar as the process is not
-sensitive to how long it takes to do a simple memory access. Time-critical
-processes, especially realtime processes, may not be able to wait or
-may not be able to tolerate variance in execution speed.
-@cindex realtime processing
-@cindex speed of execution
-
-A process that needs to lock pages for this reason probably also needs
-priority among other processes for use of the CPU. @xref{Priority}.
-
-In some cases, the programmer knows better than the system's demand
-paging allocator which pages should remain in real memory to optimize
-system performance. In this case, locking pages can help.
-
-@item
-Privacy. If you keep secrets in virtual memory and that virtual memory
-gets paged out, that increases the chance that the secrets will get out.
-If a password gets written out to disk swap space, for example, it might
-still be there long after virtual and real memory have been wiped clean.
-
-@end itemize
-
-Be aware that when you lock a page, that's one fewer page frame that can
-be used to back other virtual memory (by the same or other processes),
-which can mean more page faults, which means the system runs more
-slowly. In fact, if you lock enough memory, some programs may not be
-able to run at all for lack of real memory.
-
-@node Locked Memory Details
-@subsection Locked Memory Details
-
-A memory lock is associated with a virtual page, not a real frame. The
-paging rule is: If a frame backs at least one locked page, don't page it
-out.
-
-Memory locks do not stack. I.e., you can't lock a particular page twice
-so that it has to be unlocked twice before it is truly unlocked. It is
-either locked or it isn't.
-
-A memory lock persists until the process that owns the memory explicitly
-unlocks it. (But process termination and exec cause the virtual memory
-to cease to exist, which you might say means it isn't locked any more).
-
-Memory locks are not inherited by child processes. (But note that on a
-modern Unix system, immediately after a fork, the parent's and the
-child's virtual address space are backed by the same real page frames,
-so the child enjoys the parent's locks). @xref{Creating a Process}.
-
-Because of its ability to impact other processes, only the superuser can
-lock a page. Any process can unlock its own page.
-
-The system sets limits on the amount of memory a process can have locked
-and the amount of real memory it can have dedicated to it. @xref{Limits
-on Resources}.
-
-In Linux, locked pages aren't as locked as you might think.
-Two virtual pages that are not shared memory can nonetheless be backed
-by the same real frame. The kernel does this in the name of efficiency
-when it knows both virtual pages contain identical data, and does it
-even if one or both of the virtual pages are locked.
-
-But when a process modifies one of those pages, the kernel must get it a
-separate frame and fill it with the page's data. This is known as a
-@dfn{copy-on-write page fault}. It takes a small amount of time and in
-a pathological case, getting that frame may require I/O.
-@cindex copy-on-write page fault
-@cindex page fault, copy-on-write
-
-To make sure this doesn't happen to your program, don't just lock the
-pages. Write to them as well, unless you know you won't write to them
-ever. And to make sure you have pre-allocated frames for your stack,
-enter a scope that declares a C automatic variable larger than the
-maximum stack size you will need, set it to something, then return from
-its scope.
-
-@node Page Lock Functions
-@subsection Functions To Lock And Unlock Pages
-
-The symbols in this section are declared in @file{sys/mman.h}. These
-functions are defined by POSIX.1b, but their availability depends on
-your kernel. If your kernel doesn't allow these functions, they exist
-but always fail. They @emph{are} available with a Linux kernel.
-
-@strong{Portability Note:} POSIX.1b requires that when the @code{mlock}
-and @code{munlock} functions are available, the file @file{unistd.h}
-define the macro @code{_POSIX_MEMLOCK_RANGE} and the file
-@code{limits.h} define the macro @code{PAGESIZE} to be the size of a
-memory page in bytes. It requires that when the @code{mlockall} and
-@code{munlockall} functions are available, the @file{unistd.h} file
-define the macro @code{_POSIX_MEMLOCK}. @Theglibc{} conforms to
-this requirement.
-
-@comment sys/mman.h
-@comment POSIX.1b
-@deftypefun int mlock (const void *@var{addr}, size_t @var{len})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-@code{mlock} locks a range of the calling process' virtual pages.
-
-The range of memory starts at address @var{addr} and is @var{len} bytes
-long. Actually, since you must lock whole pages, it is the range of
-pages that include any part of the specified range.
-
-When the function returns successfully, each of those pages is backed by
-(connected to) a real frame (is resident) and is marked to stay that
-way. This means the function may cause page-ins and have to wait for
-them.
-
-When the function fails, it does not affect the lock status of any
-pages.
-
-The return value is zero if the function succeeds. Otherwise, it is
-@code{-1} and @code{errno} is set accordingly. @code{errno} values
-specific to this function are:
-
-@table @code
-@item ENOMEM
-@itemize @bullet
-@item
-At least some of the specified address range does not exist in the
-calling process' virtual address space.
-@item
-The locking would cause the process to exceed its locked page limit.
-@end itemize
-
-@item EPERM
-The calling process is not superuser.
-
-@item EINVAL
-@var{len} is not positive.
-
-@item ENOSYS
-The kernel does not provide @code{mlock} capability.
-
-@end table
-
-You can lock @emph{all} a process' memory with @code{mlockall}. You
-unlock memory with @code{munlock} or @code{munlockall}.
-
-To avoid all page faults in a C program, you have to use
-@code{mlockall}, because some of the memory a program uses is hidden
-from the C code, e.g. the stack and automatic variables, and you
-wouldn't know what address to tell @code{mlock}.
-
-@end deftypefun
-
-@comment sys/mman.h
-@comment POSIX.1b
-@deftypefun int munlock (const void *@var{addr}, size_t @var{len})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-@code{munlock} unlocks a range of the calling process' virtual pages.
-
-@code{munlock} is the inverse of @code{mlock} and functions completely
-analogously to @code{mlock}, except that there is no @code{EPERM}
-failure.
-
-@end deftypefun
-
-@comment sys/mman.h
-@comment POSIX.1b
-@deftypefun int mlockall (int @var{flags})
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-@code{mlockall} locks all the pages in a process' virtual memory address
-space, and/or any that are added to it in the future. This includes the
-pages of the code, data and stack segment, as well as shared libraries,
-user space kernel data, shared memory, and memory mapped files.
-
-@var{flags} is a string of single bit flags represented by the following
-macros. They tell @code{mlockall} which of its functions you want. All
-other bits must be zero.
-
-@vtable @code
-
-@item MCL_CURRENT
-Lock all pages which currently exist in the calling process' virtual
-address space.
-
-@item MCL_FUTURE
-Set a mode such that any pages added to the process' virtual address
-space in the future will be locked from birth. This mode does not
-affect future address spaces owned by the same process so exec, which
-replaces a process' address space, wipes out @code{MCL_FUTURE}.
-@xref{Executing a File}.
-
-@end vtable
-
-When the function returns successfully, and you specified
-@code{MCL_CURRENT}, all of the process' pages are backed by (connected
-to) real frames (they are resident) and are marked to stay that way.
-This means the function may cause page-ins and have to wait for them.
-
-When the process is in @code{MCL_FUTURE} mode because it successfully
-executed this function and specified @code{MCL_CURRENT}, any system call
-by the process that requires space be added to its virtual address space
-fails with @code{errno} = @code{ENOMEM} if locking the additional space
-would cause the process to exceed its locked page limit. In the case
-that the address space addition that can't be accommodated is stack
-expansion, the stack expansion fails and the kernel sends a
-@code{SIGSEGV} signal to the process.
-
-When the function fails, it does not affect the lock status of any pages
-or the future locking mode.
-
-The return value is zero if the function succeeds. Otherwise, it is
-@code{-1} and @code{errno} is set accordingly. @code{errno} values
-specific to this function are:
-
-@table @code
-@item ENOMEM
-@itemize @bullet
-@item
-At least some of the specified address range does not exist in the
-calling process' virtual address space.
-@item
-The locking would cause the process to exceed its locked page limit.
-@end itemize
-
-@item EPERM
-The calling process is not superuser.
-
-@item EINVAL
-Undefined bits in @var{flags} are not zero.
-
-@item ENOSYS
-The kernel does not provide @code{mlockall} capability.
-
-@end table
-
-You can lock just specific pages with @code{mlock}. You unlock pages
-with @code{munlockall} and @code{munlock}.
-
-@end deftypefun
-
-
-@comment sys/mman.h
-@comment POSIX.1b
-@deftypefun int munlockall (void)
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-@code{munlockall} unlocks every page in the calling process' virtual
-address space and turns off @code{MCL_FUTURE} future locking mode.
-
-The return value is zero if the function succeeds. Otherwise, it is
-@code{-1} and @code{errno} is set accordingly. The only way this
-function can fail is for generic reasons that all functions and system
-calls can fail, so there are no specific @code{errno} values.
-
-@end deftypefun
-
-
-
-
-@ignore
-@c This was never actually implemented. -zw
-@node Relocating Allocator
-@section Relocating Allocator
-
-@cindex relocating memory allocator
-Any system of dynamic memory allocation has overhead: the amount of
-space it uses is more than the amount the program asks for. The
-@dfn{relocating memory allocator} achieves very low overhead by moving
-blocks in memory as necessary, on its own initiative.
-
-@c @menu
-@c * Relocator Concepts:: How to understand relocating allocation.
-@c * Using Relocator:: Functions for relocating allocation.
-@c @end menu
-
-@node Relocator Concepts
-@subsection Concepts of Relocating Allocation
-
-@ifinfo
-The @dfn{relocating memory allocator} achieves very low overhead by
-moving blocks in memory as necessary, on its own initiative.
-@end ifinfo
-
-When you allocate a block with @code{malloc}, the address of the block
-never changes unless you use @code{realloc} to change its size. Thus,
-you can safely store the address in various places, temporarily or
-permanently, as you like. This is not safe when you use the relocating
-memory allocator, because any and all relocatable blocks can move
-whenever you allocate memory in any fashion. Even calling @code{malloc}
-or @code{realloc} can move the relocatable blocks.
-
-@cindex handle
-For each relocatable block, you must make a @dfn{handle}---a pointer
-object in memory, designated to store the address of that block. The
-relocating allocator knows where each block's handle is, and updates the
-address stored there whenever it moves the block, so that the handle
-always points to the block. Each time you access the contents of the
-block, you should fetch its address anew from the handle.
-
-To call any of the relocating allocator functions from a signal handler
-is almost certainly incorrect, because the signal could happen at any
-time and relocate all the blocks. The only way to make this safe is to
-block the signal around any access to the contents of any relocatable
-block---not a convenient mode of operation. @xref{Nonreentrancy}.
-
-@node Using Relocator
-@subsection Allocating and Freeing Relocatable Blocks
-
-@pindex malloc.h
-In the descriptions below, @var{handleptr} designates the address of the
-handle. All the functions are declared in @file{malloc.h}; all are GNU
-extensions.
-
-@comment malloc.h
-@comment GNU
-@c @deftypefun {void *} r_alloc (void **@var{handleptr}, size_t @var{size})
-This function allocates a relocatable block of size @var{size}. It
-stores the block's address in @code{*@var{handleptr}} and returns
-a non-null pointer to indicate success.
-
-If @code{r_alloc} can't get the space needed, it stores a null pointer
-in @code{*@var{handleptr}}, and returns a null pointer.
-@end deftypefun
-
-@comment malloc.h
-@comment GNU
-@c @deftypefun void r_alloc_free (void **@var{handleptr})
-This function is the way to free a relocatable block. It frees the
-block that @code{*@var{handleptr}} points to, and stores a null pointer
-in @code{*@var{handleptr}} to show it doesn't point to an allocated
-block any more.
-@end deftypefun
-
-@comment malloc.h
-@comment GNU
-@c @deftypefun {void *} r_re_alloc (void **@var{handleptr}, size_t @var{size})
-The function @code{r_re_alloc} adjusts the size of the block that
-@code{*@var{handleptr}} points to, making it @var{size} bytes long. It
-stores the address of the resized block in @code{*@var{handleptr}} and
-returns a non-null pointer to indicate success.
-
-If enough memory is not available, this function returns a null pointer
-and does not modify @code{*@var{handleptr}}.
-@end deftypefun
-@end ignore
-
-
-
-
-@ignore
-@comment No longer available...
-
-@comment @node Memory Warnings
-@comment @section Memory Usage Warnings
-@comment @cindex memory usage warnings
-@comment @cindex warnings of memory almost full
-
-@pindex malloc.c
-You can ask for warnings as the program approaches running out of memory
-space, by calling @code{memory_warnings}. This tells @code{malloc} to
-check memory usage every time it asks for more memory from the operating
-system. This is a GNU extension declared in @file{malloc.h}.
-
-@comment malloc.h
-@comment GNU
-@comment @deftypefun void memory_warnings (void *@var{start}, void (*@var{warn-func}) (const char *))
-Call this function to request warnings for nearing exhaustion of virtual
-memory.
-
-The argument @var{start} says where data space begins, in memory. The
-allocator compares this against the last address used and against the
-limit of data space, to determine the fraction of available memory in
-use. If you supply zero for @var{start}, then a default value is used
-which is right in most circumstances.
-
-For @var{warn-func}, supply a function that @code{malloc} can call to
-warn you. It is called with a string (a warning message) as argument.
-Normally it ought to display the string for the user to read.
-@end deftypefun
-
-The warnings come when memory becomes 75% full, when it becomes 85%
-full, and when it becomes 95% full. Above 95% you get another warning
-each time memory usage increases.
-
-@end ignore