Locating Memory Access Errors With Sun Memory Error Discovery Tool

   
By Darryl Gove, September 2007  

The Sun Memory Error Discovery Tool detects and reports common memory access errors such as accessing uninitialized memory, writing past the end of an array, or accessing memory after it has been freed.

Contents

Introduction

Memory access errors are one of the hardest types of error to detect. The reason for this is that the symptoms of the error occur arbitrarily far from the point where the error occurred. The Sun Memory Error Discovery Tool (the Discovery tool) is designed to detect and report common memory access errors such as accessing uninitialized memory, writing past the end of an array, or accessing memory after it has been freed. The initial release of the tool supports only single-threaded applications.

The Discovery tool is included as part of the Oracle Solaris Studio 12.2 release.

Using the Discovery Tool

The target application needs to be compiled with Sun Studio 12 together with the -xbinopt=prepare compiler flag, an optimization level of at least -xO1 and the -g compiler option to get better debugging information from the tool. The following example code has an error where the array element a[1] is read without having first been initialized.

#include <stdlib.h>
#include <stdio.h>

void main()
{
  int * a=malloc(100*sizeof(int));
  a[1]++;
  free(a);
}

The steps necessary to compile, instrument, and run the code are shown in the following example.

$ cc -g -O -xbinopt=prepare -o mem mem.c
$ discover mem
$ mem

At the end of the run, the instrumented application reports any memory errors that were encountered during the run. Each reported error can have multiple sections. The first section always describes where the error occurred, as shown in the following example.

ERROR (UMR): accessing uninitialized data 
             from address 0x5000c (4 bytes) at:
        main() + 0x54 [/tmp/mem:0x30054]
          <mem.c:7>:
                 4:    void main()
                 5:    {
                 6:      int * a=malloc(100*sizeof(int));
                 7:=>    a[1]++;
                 8:      free(a);
                 9:    }

There might be other sections that report where the memory was allocated, and if necessary, where the memory was freed. It is also possible to generate the output as an HTML report by setting the environment variable DISCOVER_HTML to 1.

The following code shows an example of reading memory beyond the end of an allocated array. Another error message is reported for the same line because it is both a read and a write of the 101st element of the array.

ERROR (ABR): reading memory beyond array bounds 
             at address 0x50198 (4 bytes) at:
        main() + 0x54 [/tmp/mem:0x30054]
          <mem.c:7>:
                 4:    void main()
                 5:    {
                 6:      int * a=malloc(100*sizeof(int));
                 7:=>    a[100]++;
                 8:      free(a);
                 9:    }

Concluding Remarks

Although memory access errors can be hard to locate, the Sun Memory Error Discovery Tool should make the process of locating these errors significantly easier, leading to a shorter development time and a more robust final product. More information, including links to installation instructions, the man page, and a detailed user's guide, is available online.

Author

Darryl Gove is a senior staff engineer in Compiler Performance Engineering at Sun Microsystems, and now Oracle, analyzing and optimizing the performance of applications on current and future UltraSPARC systems. Darryl has an M.Sc. and Ph.D. in Operational Research from the University of Southampton in the U.K. Before joining Sun, Darryl held various software architecture and development roles in the U.K. Read Darryl's blog.