Mtrace

Last updated

mtrace is the memory debugger included in the GNU C Library.

Contents

Use

Note that mtrace tool works only with single threaded applications. One thread could temporarily remove the hook while another thread could malloc memory at the sametime leading to missed allocations in a multithreaded application!

The function mtrace installs handlers for malloc, realloc and free; the function muntrace disables these handlers. Their prototypes, defined in the header file mcheck.h, are

void mtrace(void);
void muntrace(void);

The handlers log all memory allocations and frees to a file defined by the environment variable MALLOC_TRACE (if the variable is unset, describes an invalid filename, or describes a filename the user does not have permissions to, the handlers are not installed).

A perl script called mtrace, not to be confused with the function of the same name, is also distributed with the GNU C Library; the script parses through the output file and reports all allocations that were not freed.

Usage example

Bad source code

The following is an example of bad source code. The problem with the program is that it allocates memory, but doesn't free the memory before exiting.

#include<stdlib.h>intmain(void){int*a;a=malloc(sizeof(int));/* allocate memory and assign it to the pointer */return0;/* we exited the program without freeing memory *//* we should have released the allocated memory with the statement “free(a)” */}

MTrace usage

  1. Set the environment variable MALLOC_TRACE to the pathname of the desired output file. Setting environment variables is slightly different in each shell. In Bourne Shell-compatible shells, like Bash, the command is as follows:
    $ MALLOC_TRACE=/home/YourUserName/path/to/program/MallocTraceOutputFile.txt $ exportMALLOC_TRACE 
  2. Include mcheck.h in the source code. This is done, for example, by adding the following line to the top of a C or C++ file, as shown below:
    #include<mcheck.h>
  3. Call the function mtrace() before you start allocating memory. It is usually easiest to call mtrace() at the very beginning of the main() function:
    mtrace();
    To delineate the end of the code that should be traced, call the function muntrace(). This is usually done at the end of the main() function:
    muntrace();
  4. Compile and run the program as usual. Note that you need to compile with the -g option to get useful output. In GCC on Linux, this can be done using the following commands for a C program:
    $ gccyourProgram.c-g $ ./a.out 
  5. Memory leak information will be reported in the file specified by the MALLOC_TRACE environment variable. The difficulty is, this file will be in a computer-readable format. Most Linux machines come with a console command called mtrace, that converts the computer readable format into human-readable text as shown below. If you do not have access to this console command, there is a Perl script, of the same name, that can be downloaded to accomplish the same task. The mtrace syntax is as follows:
    $ mtrace<exec_file_name><malloc_trace_filename> 
    For example:
    $ mtracea.outMallocTraceOutputFile.txt 
  6. mtrace can be used with parallel computing but one process at a time, using a condition on the rank like:
    if(my_rank==0)mtrace();

MTrace output

If the mtrace command reports “No Memory Leaks”, then all memory that was allocated in the last execution of that program was also released, which is the way it should be. If, on the other hand, mtrace gives output such as that below, it means the programmer still has some work to do.

Memory not freed: -----------------    Address     Size     Caller 0x08049910      0x4  at /home/sureshsathiah/tips/leak.c:9 

Good source code

The following is an example of good source code. It releases memory after it is allocated, and it uses mtrace to notify the programmer if there are memory leaks.

#include<stdlib.h>#include<mcheck.h>intmain(void){mtrace();/* Starts the recording of memory allocations and releases */int*a=NULL;a=malloc(sizeof(int));/* allocate memory and assign it to the pointer */if(a==NULL){return1;/* error */}free(a);/* we free the memory we allocated so we don't have leaks */muntrace();return0;/* exit */}

See also

Related Research Articles

<span class="mw-page-title-main">AWK</span> Programming language

AWK is a domain-specific language designed for text processing and typically used as a data extraction and reporting tool. Like sed and grep, it is a filter, and is a standard feature of most Unix-like operating systems.

C is a general-purpose computer programming language. It was created in the 1970s by Dennis Ritchie, and remains very widely used and influential. By design, C's features cleanly reflect the capabilities of the targeted CPUs. It has found lasting use in operating systems, device drivers, and protocol stacks, but its use in application software has been decreasing. C is commonly used on computer architectures that range from the largest supercomputers to the smallest microcontrollers and embedded systems.

<span class="mw-page-title-main">GNU Debugger</span> Source-level debugger

The GNU Debugger (GDB) is a portable debugger that runs on many Unix-like systems and works for many programming languages, including Ada, Assembly, C, C++, D, Fortran, Go, Objective-C, OpenCL C, Modula-2, Pascal, Rust, and partially others.

In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in a way that memory which is no longer needed is not released. A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code. A memory leak has symptoms similar to a number of other problems and generally can only be diagnosed by a programmer with access to the program's source code.

In computing, a segmentation fault or access violation is a fault, or failure condition, raised by hardware with memory protection, notifying an operating system (OS) the software has attempted to access a restricted area of memory. On standard x86 computers, this is a form of general protection fault. The operating system kernel will, in response, usually perform some corrective action, generally passing the fault on to the offending process by sending the process a signal. Processes can in some cases install a custom signal handler, allowing them to recover on their own, but otherwise the OS default signal handler is used, generally causing abnormal termination of the process, and sometimes a core dump.

GNU Bison, commonly known as Bison, is a parser generator that is part of the GNU Project. Bison reads a specification in the BNF notation, warns about any parsing ambiguities, and generates a parser that reads sequences of tokens and decides whether the sequence conforms to the syntax specified by the grammar.

C dynamic memory allocation refers to performing manual memory management for dynamic memory allocation in the C programming language via a group of functions in the C standard library, namely malloc, realloc, calloc, aligned_alloc and free.

<span class="mw-page-title-main">Pointer (computer programming)</span> Object which stores memory addresses in a computer program

In computer science, a pointer is an object in many programming languages that stores a memory address. This can be that of another value located in computer memory, or in some cases, that of memory-mapped computer hardware. A pointer references a location in memory, and obtaining the value stored at that location is known as dereferencing the pointer. As an analogy, a page number in a book's index could be considered a pointer to the corresponding page; dereferencing such a pointer would be done by flipping to the page with the given page number and reading the text found on that page. The actual format and content of a pointer variable is dependent on the underlying computer architecture.

<span class="mw-page-title-main">Dangling pointer</span> Pointer that does not point to a valid object

Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object of the appropriate type. These are special cases of memory safety violations. More generally, dangling references and wild references are references that do not resolve to a valid destination.

In computing, a data segment is a portion of an object file or the corresponding address space of a program that contains initialized static variables, that is, global variables and static local variables. The size of this segment is determined by the size of the values in the program's source code, and does not change at run time.

<span class="mw-page-title-main">Stack-based memory allocation</span> Form of computer memory allocation

Stacks in computing architectures are regions of memory where data is added or removed in a last-in-first-out (LIFO) manner.

<span class="mw-page-title-main">Jagged array</span>

In computer science, a jagged array, also known as a ragged array or irregular array is an array of arrays of which the member arrays can be of different lengths, producing rows of jagged edges when visualized as output. In contrast, two-dimensional arrays are always rectangular so jagged arrays should not be confused with multidimensional arrays, but the former is often used to emulate the latter.

The Boehm–Demers–Weiser garbage collector, often simply known as Boehm GC, is a conservative garbage collector for C and C++ developed by Hans Boehm, Alan Demers, and Mark Weiser.

In the C++ programming language, new and delete are a pair of language constructs that perform dynamic memory allocation, object construction and object destruction.

sizeof is a unary operator in the programming languages C and C++. It generates the storage size of an expression or a data type, measured in the number of char-sized units. Consequently, the construct sizeof (char) is guaranteed to be 1. The actual number of bits of type char is specified by the preprocessor macro CHAR_BIT, defined in the standard include file limits.h. On most modern computing platforms this is eight bits. The result of sizeof has an unsigned integer type that is usually denoted by size_t.

The C and C++ programming languages are closely related but have many significant differences. C++ began as a fork of an early, pre-standardized C, and was designed to be mostly source-and-link compatible with C compilers of the time. Due to this, development tools for the two languages are often integrated into a single product, with the programmer able to specify C or C++ as their source language.

In computer programming, a variable-length array (VLA), also called variable-sized or runtime-sized, is an array data structure whose length is determined at run time . In C, the VLA is said to have a variably modified type that depends on a value.

Secure coding is the practice of developing computer software in such a way that guards against the accidental introduction of security vulnerabilities. Defects, bugs and logic flaws are consistently the primary cause of commonly exploited software vulnerabilities. Through the analysis of thousands of reported vulnerabilities, security professionals have discovered that most vulnerabilities stem from a relatively small number of common software programming errors. By identifying the insecure coding practices that lead to these errors and educating developers on secure alternatives, organizations can take proactive steps to help significantly reduce or eliminate vulnerabilities in software before deployment.

In C++ computer programming, allocators are a component of the C++ Standard Library. The standard library provides several data structures, such as list and set, commonly referred to as containers. A common trait among these containers is their ability to change size during the execution of the program. To achieve this, some form of dynamic memory allocation is usually required. Allocators handle all the requests for allocation and deallocation of memory for a given container. The C++ Standard Library provides general-purpose allocators that are used by default, however, custom allocators may also be supplied by the programmer.

<span class="mw-page-title-main">Zig (programming language)</span> A general-purpose programming language, and toolchain to build Zig/C/C++ code

Zig is an imperative, general-purpose, statically typed, compiled system programming language designed by Andrew Kelley. It is intended to be a successor to the C programming language, with the goals of being even smaller and simpler to program in while also offering modern features, new optimizations and a variety of safety mechanisms while not as demanding of runtime safety as seen in other languages. It is distinct from languages like Go, Rust and Carbon, which have similar goals but also target the C++ space.