| @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} |
| * Memory Protection:: Controlling access to memory regions. |
| * 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 |
| |
| @deftypefun {void *} malloc (size_t @var{size}) |
| @standards{ISO, malloc.h} |
| @standards{ISO, stdlib.h} |
| @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 |
| |
| @deftypefun void free (void *@var{ptr}) |
| @standards{ISO, malloc.h} |
| @standards{ISO, stdlib.h} |
| @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 |
| |
| @deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize}) |
| @standards{ISO, malloc.h} |
| @standards{ISO, stdlib.h} |
| @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 |
| |
| @deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size}) |
| @standards{BSD, malloc.h} |
| @standards{BSD, stdlib.h} |
| @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 |
| |
| @deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize}) |
| @standards{ISO, malloc.h} |
| @standards{ISO, stdlib.h} |
| @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}. |
| |
| @deftypefun {void *} aligned_alloc (size_t @var{alignment}, size_t @var{size}) |
| @standards{???, stdlib.h} |
| @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 |
| |
| @deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size}) |
| @standards{BSD, malloc.h} |
| @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 |
| |
| @deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size}) |
| @standards{POSIX, stdlib.h} |
| @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 |
| |
| @deftypefun {void *} valloc (size_t @var{size}) |
| @standards{BSD, malloc.h} |
| @standards{BSD, stdlib.h} |
| @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: |
| |
| @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 |
| |
| @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status})) |
| @standards{GNU, mcheck.h} |
| @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 to a |
| non-zero value, 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. |
| |
| Any detected heap corruption results in immediate termination of the |
| process. |
| |
| 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 |
| |
| @defvar __malloc_hook |
| @standards{GNU, malloc.h} |
| 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 |
| |
| @defvar __realloc_hook |
| @standards{GNU, malloc.h} |
| 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 |
| |
| @defvar __free_hook |
| @standards{GNU, malloc.h} |
| 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 |
| |
| @defvar __memalign_hook |
| @standards{GNU, malloc.h} |
| 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 |
| |
| @deftp {Data Type} {struct mallinfo} |
| @standards{GNU, malloc.h} |
| 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 |
| |
| @deftypefun {struct mallinfo} mallinfo (void) |
| @standards{SVID, malloc.h} |
| @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 |
| |
| @deftypefun void mtrace (void) |
| @standards{GNU, mcheck.h} |
| @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 |
| |
| @deftypefun void muntrace (void) |
| @standards{GNU, mcheck.h} |
| @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 |
| |
| @deftp {Data Type} {struct obstack} |
| @standards{GNU, obstack.h} |
| 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}. |
| |
| @deftypefun int obstack_init (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @defvar obstack_alloc_failed_handler |
| @standards{GNU, obstack.h} |
| 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}. |
| |
| @deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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: |
| |
| @deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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. |
| |
| @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object}) |
| @standards{GNU, obstack.h} |
| @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. |
| |
| @deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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: |
| |
| @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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: |
| |
| @deftypefun int obstack_room (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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: |
| |
| @deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size}) |
| @standards{GNU, obstack.h} |
| @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. |
| |
| @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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: |
| |
| @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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. |
| |
| @deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr}) |
| @standards{GNU, obstack.h} |
| @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 |
| |
| @deftypefun {void *} alloca (size_t @var{size}) |
| @standards{GNU, stdlib.h} |
| @standards{BSD, stdlib.h} |
| @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. |
| |
| @deftypefun int brk (void *@var{addr}) |
| @standards{BSD, unistd.h} |
| @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 |
| |
| |
| @deftypefun void *sbrk (ptrdiff_t @var{delta}) |
| @standards{BSD, unistd.h} |
| @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 Memory Protection |
| @section Memory Protection |
| @cindex memory protection |
| @cindex page protection |
| @cindex protection flags |
| |
| When a page is mapped using @code{mmap}, page protection flags can be |
| specified using the protection flags argument. @xref{Memory-mapped |
| I/O}. |
| |
| The following flags are available: |
| |
| @vtable @code |
| @item PROT_WRITE |
| @standards{POSIX, sys/mman.h} |
| The memory can be written to. |
| |
| @item PROT_READ |
| @standards{POSIX, sys/mman.h} |
| The memory can be read. On some architectures, this flag implies that |
| the memory can be executed as well (as if @code{PROT_EXEC} had been |
| specified at the same time). |
| |
| @item PROT_EXEC |
| @standards{POSIX, sys/mman.h} |
| The memory can be used to store instructions which can then be executed. |
| On most architectures, this flag implies that the memory can be read (as |
| if @code{PROT_READ} had been specified). |
| |
| @item PROT_NONE |
| @standards{POSIX, sys/mman.h} |
| This flag must be specified on its own. |
| |
| The memory is reserved, but cannot be read, written, or executed. If |
| this flag is specified in a call to @code{mmap}, a virtual memory area |
| will be set aside for future use in the process, and @code{mmap} calls |
| without the @code{MAP_FIXED} flag will not use it for subsequent |
| allocations. For anonymous mappings, the kernel will not reserve any |
| physical memory for the allocation at the time the mapping is created. |
| @end vtable |
| |
| The operating system may keep track of these flags separately even if |
| the underlying hardware treats them the same for the purposes of access |
| checking (as happens with @code{PROT_READ} and @code{PROT_EXEC} on some |
| platforms). On GNU systems, @code{PROT_EXEC} always implies |
| @code{PROT_READ}, so that users can view the machine code which is |
| executing on their system. |
| |
| Inappropriate access will cause a segfault (@pxref{Program Error |
| Signals}). |
| |
| After allocation, protection flags can be changed using the |
| @code{mprotect} function. |
| |
| @deftypefun int mprotect (void *@var{address}, size_t @var{length}, int @var{protection}) |
| @standards{POSIX, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| |
| A successful call to the @code{mprotect} function changes the protection |
| flags of at least @var{length} bytes of memory, starting at |
| @var{address}. |
| |
| @var{address} must be aligned to the page size for the mapping. The |
| system page size can be obtained by calling @code{sysconf} with the |
| @code{_SC_PAGESIZE} parameter (@pxref{Sysconf Definition}). The system |
| page size is the granularity in which the page protection of anonymous |
| memory mappings and most file mappings can be changed. Memory which is |
| mapped from special files or devices may have larger page granularity |
| than the system page size and may require larger alignment. |
| |
| @var{length} is the number of bytes whose protection flags must be |
| changed. It is automatically rounded up to the next multiple of the |
| system page size. |
| |
| @var{protection} is a combination of the @code{PROT_*} flags described |
| above. |
| |
| The @code{mprotect} function returns @math{0} on success and @math{-1} |
| on failure. |
| |
| The following @code{errno} error conditions are defined for this |
| function: |
| |
| @table @code |
| @item ENOMEM |
| The system was not able to allocate resources to fulfill the request. |
| This can happen if there is not enough physical memory in the system for |
| the allocation of backing storage. The error can also occur if the new |
| protection flags would cause the memory region to be split from its |
| neighbors, and the process limit for the number of such distinct memory |
| regions would be exceeded. |
| |
| @item EINVAL |
| @var{address} is not properly aligned to a page boundary for the |
| mapping, or @var{length} (after rounding up to the system page size) is |
| not a multiple of the applicable page size for the mapping, or the |
| combination of flags in @var{protection} is not valid. |
| |
| @item EACCES |
| The file for a file-based mapping was not opened with open flags which |
| are compatible with @var{protection}. |
| |
| @item EPERM |
| The system security policy does not allow a mapping with the specified |
| flags. For example, mappings which are both @code{PROT_EXEC} and |
| @code{PROT_WRITE} at the same time might not be allowed. |
| @end table |
| @end deftypefun |
| |
| If the @code{mprotect} function is used to make a region of memory |
| inaccessible by specifying the @code{PROT_NONE} protection flag and |
| access is later restored, the memory retains its previous contents. |
| |
| On some systems, it may not be possible to specify additional flags |
| which were not present when the mapping was first created. For example, |
| an attempt to make a region of memory executable could fail if the |
| initial protection flags were @samp{PROT_READ | PROT_WRITE}. |
| |
| In general, the @code{mprotect} function can be used to change any |
| process memory, no matter how it was allocated. However, portable use |
| of the function requires that it is only used with memory regions |
| returned by @code{mmap} or @code{mmap64}. |
| |
| @subsection Memory Protection Keys |
| |
| @cindex memory protection key |
| @cindex protection key |
| @cindex MPK |
| On some systems, further restrictions can be added to specific pages |
| using @dfn{memory protection keys}. These restrictions work as follows: |
| |
| @itemize @bullet |
| @item |
| All memory pages are associated with a protection key. The default |
| protection key does not cause any additional protections to be applied |
| during memory accesses. New keys can be allocated with the |
| @code{pkey_alloc} function, and applied to pages using |
| @code{pkey_mprotect}. |
| |
| @item |
| Each thread has a set of separate access right restriction for each |
| protection key. These access rights can be manipulated using the |
| @code{pkey_set} and @code{pkey_get} functions. |
| |
| @item |
| During a memory access, the system obtains the protection key for the |
| accessed page and uses that to determine the applicable access rights, |
| as configured for the current thread. If the access is restricted, a |
| segmentation fault is the result ((@pxref{Program Error Signals}). |
| These checks happen in addition to the @code{PROT_}* protection flags |
| set by @code{mprotect} or @code{pkey_mprotect}. |
| @end itemize |
| |
| New threads and subprocesses inherit the access rights of the current |
| thread. If a protection key is allocated subsequently, existing threads |
| (except the current) will use an unspecified system default for the |
| access rights associated with newly allocated keys. |
| |
| Upon entering a signal handler, the system resets the access rights of |
| the current thread so that pages with the default key can be accessed, |
| but the access rights for other protection keys are unspecified. |
| |
| Applications are expected to allocate a key once using |
| @code{pkey_alloc}, and apply the key to memory regions which need |
| special protection with @code{pkey_mprotect}: |
| |
| @smallexample |
| int key = pkey_alloc (0, PKEY_DISABLE_ACCESS); |
| if (key < 0) |
| /* Perform error checking, including fallback for lack of support. */ |
| ...; |
| |
| /* Apply the key to a special memory region used to store critical |
| data. */ |
| if (pkey_mprotect (region, region_length, |
| PROT_READ | PROT_WRITE, key) < 0) |
| ...; /* Perform error checking (generally fatal). */ |
| @end smallexample |
| |
| If the key allocation fails due to lack of support for memory protection |
| keys, the @code{pkey_mprotect} call can usually be skipped. In this |
| case, the region will not be protected by default. It is also possible |
| to call @code{pkey_mprotect} with a key value of @math{-1}, in which |
| case it will behave in the same way as @code{mprotect}. |
| |
| After key allocation assignment to memory pages, @code{pkey_set} can be |
| used to temporarily acquire access to the memory region and relinquish |
| it again: |
| |
| @smallexample |
| if (key >= 0 && pkey_set (key, 0) < 0) |
| ...; /* Perform error checking (generally fatal). */ |
| /* At this point, the current thread has read-write access to the |
| memory region. */ |
| ... |
| /* Revoke access again. */ |
| if (key >= 0 && pkey_set (key, PKEY_DISABLE_ACCESS) < 0) |
| ...; /* Perform error checking (generally fatal). */ |
| @end smallexample |
| |
| In this example, a negative key value indicates that no key had been |
| allocated, which means that the system lacks support for memory |
| protection keys and it is not necessary to change the the access rights |
| of the current thread (because it always has access). |
| |
| Compared to using @code{mprotect} to change the page protection flags, |
| this approach has two advantages: It is thread-safe in the sense that |
| the access rights are only changed for the current thread, so another |
| thread which changes its own access rights concurrently to gain access |
| to the mapping will not suddenly see its access rights revoked. And |
| @code{pkey_set} typically does not involve a call into the kernel and a |
| context switch, so it is more efficient. |
| |
| @deftypefun int pkey_alloc (unsigned int @var{flags}, unsigned int @var{restrictions}) |
| @standards{Linux, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} |
| Allocate a new protection key. The @var{flags} argument is reserved and |
| must be zero. The @var{restrictions} argument specifies access rights |
| which are applied to the current thread (as if with @code{pkey_set} |
| below). Access rights of other threads are not changed. |
| |
| The function returns the new protection key, a non-negative number, or |
| @math{-1} on error. |
| |
| The following @code{errno} error conditions are defined for this |
| function: |
| |
| @table @code |
| @item ENOSYS |
| The system does not implement memory protection keys. |
| |
| @item EINVAL |
| The @var{flags} argument is not zero. |
| |
| The @var{restrictions} argument is invalid. |
| |
| The system does not implement memory protection keys or runs in a mode |
| in which memory protection keys are disabled. |
| |
| @item ENOSPC |
| All available protection keys already have been allocated. |
| @end table |
| @end deftypefun |
| |
| @deftypefun int pkey_free (int @var{key}) |
| @standards{Linux, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| Deallocate the protection key, so that it can be reused by |
| @code{pkey_alloc}. |
| |
| Calling this function does not change the access rights of the freed |
| protection key. The calling thread and other threads may retain access |
| to it, even if it is subsequently allocated again. For this reason, it |
| is not recommended to call the @code{pkey_free} function. |
| |
| @table @code |
| @item ENOSYS |
| The system does not implement memory protection keys. |
| |
| @item EINVAL |
| The @var{key} argument is not a valid protection key. |
| @end table |
| @end deftypefun |
| |
| @deftypefun int pkey_mprotect (void *@var{address}, size_t @var{length}, int @var{protection}, int @var{key}) |
| @standards{Linux, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| Similar to @code{mprotect}, but also set the memory protection key for |
| the memory region to @code{key}. |
| |
| Some systems use memory protection keys to emulate certain combinations |
| of @var{protection} flags. Under such circumstances, specifying an |
| explicit protection key may behave as if additional flags have been |
| specified in @var{protection}, even though this does not happen with the |
| default protection key. For example, some systems can support |
| @code{PROT_EXEC}-only mappings only with a default protection key, and |
| memory with a key which was allocated using @code{pkey_alloc} will still |
| be readable if @code{PROT_EXEC} is specified without @code{PROT_READ}. |
| |
| If @var{key} is @math{-1}, the default protection key is applied to the |
| mapping, just as if @code{mprotect} had been called. |
| |
| The @code{pkey_mprotect} function returns @math{0} on success and |
| @math{-1} on failure. The same @code{errno} error conditions as for |
| @code{mprotect} are defined for this function, with the following |
| addition: |
| |
| @table @code |
| @item EINVAL |
| The @var{key} argument is not @math{-1} or a valid memory protection |
| key allocated using @code{pkey_alloc}. |
| |
| @item ENOSYS |
| The system does not implement memory protection keys, and @var{key} is |
| not @math{-1}. |
| @end table |
| @end deftypefun |
| |
| @deftypefun int pkey_set (int @var{key}, unsigned int @var{rights}) |
| @standards{Linux, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| Change the access rights of the current thread for memory pages with the |
| protection key @var{key} to @var{rights}. If @var{rights} is zero, no |
| additional access restrictions on top of the page protection flags are |
| applied. Otherwise, @var{rights} is a combination of the following |
| flags: |
| |
| @vtable @code |
| @item PKEY_DISABLE_WRITE |
| @standards{Linux, sys/mman.h} |
| Subsequent attempts to write to memory with the specified protection |
| key will fault. |
| |
| @item PKEY_DISABLE_ACCESS |
| @standards{Linux, sys/mman.h} |
| Subsequent attempts to write to or read from memory with the specified |
| protection key will fault. |
| @end vtable |
| |
| Operations not specified as flags are not restricted. In particular, |
| this means that the memory region will remain executable if it was |
| mapped with the @code{PROT_EXEC} protection flag and |
| @code{PKEY_DISABLE_ACCESS} has been specified. |
| |
| Calling the @code{pkey_set} function with a protection key which was not |
| allocated by @code{pkey_alloc} results in undefined behavior. This |
| means that calling this function on systems which do not support memory |
| protection keys is undefined. |
| |
| The @code{pkey_set} function returns @math{0} on success and @math{-1} |
| on failure. |
| |
| The following @code{errno} error conditions are defined for this |
| function: |
| |
| @table @code |
| @item EINVAL |
| The system does not support the access rights restrictions expressed in |
| the @var{rights} argument. |
| @end table |
| @end deftypefun |
| |
| @deftypefun int pkey_get (int @var{key}) |
| @standards{Linux, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| Return the access rights of the current thread for memory pages with |
| protection key @var{key}. The return value is zero or a combination of |
| the @code{PKEY_DISABLE_}* flags; see the @code{pkey_set} function. |
| |
| Calling the @code{pkey_get} function with a protection key which was not |
| allocated by @code{pkey_alloc} results in undefined behavior. This |
| means that calling this function on systems which do not support memory |
| protection keys is undefined. |
| @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. |
| |
| @deftypefun int mlock (const void *@var{addr}, size_t @var{len}) |
| @standards{POSIX.1b, sys/mman.h} |
| @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 |
| @end deftypefun |
| |
| @deftypefun int mlock2 (const void *@var{addr}, size_t @var{len}, unsigned int @var{flags}) |
| @standards{Linux, sys/mman.h} |
| @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| |
| This function is similar to @code{mlock}. If @var{flags} is zero, a |
| call to @code{mlock2} behaves exactly as the equivalent call to @code{mlock}. |
| |
| The @var{flags} argument must be a combination of zero or more of the |
| following flags: |
| |
| @vtable @code |
| @item MLOCK_ONFAULT |
| @standards{Linux, sys/mman.h} |
| Only those pages in the specified address range which are already in |
| memory are locked immediately. Additional pages in the range are |
| automatically locked in case of a page fault and allocation of memory. |
| @end vtable |
| |
| Like @code{mlock}, @code{mlock2} returns zero on success and @code{-1} |
| on failure, setting @code{errno} accordingly. Additional @code{errno} |
| values defined for @code{mlock2} are: |
| |
| @table @code |
| @item EINVAL |
| The specified (non-zero) @var{flags} argument is not supported by this |
| system. |
| @end table |
| @end deftypefun |
| |
| 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}. |
| |
| @deftypefun int munlock (const void *@var{addr}, size_t @var{len}) |
| @standards{POSIX.1b, sys/mman.h} |
| @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 |
| |
| @deftypefun int mlockall (int @var{flags}) |
| @standards{POSIX.1b, sys/mman.h} |
| @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 |
| |
| |
| @deftypefun int munlockall (void) |
| @standards{POSIX.1b, sys/mman.h} |
| @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 |