debugging memory problems with memoryscape

DEBUGGING
MEMORY PROBLEMS
WITH
MEMORYSCAPE™
Version 3.6
ROGUE WAVE SOFTWARE
/ 5500 FLATIRON PARKWAY, SUITE 200
/
BOULDER, CO 80301, USA
/
WWW.ROGUEWAVE.COM
Copyright © 2010-2014 by Rogue Wave Software, Inc. All rights reserved.
Copyright © 2007-2009 by TotalView Technologies, LLC
Copyright © 1998–2007 by Etnus LLC. All rights reserved.
Copyright © 1996–1998 by Dolphin Interconnect Solutions, Inc.
Copyright © 1993–1996 by BBN Systems and Technologies, a division of
BBN Corporation.
No part of this publication may be reproduced, stored in a retrieval system,
or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise without the prior written permission of
Rogue Wave Software, Inc. ("Rogue Wave").
Use, duplication, or disclosure by the Government is subject to restrictions
as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and
Computer Software clause at DFARS 252.227-7013.
Rogue Wave has prepared this manual for the exclusive use of its customers, personnel, and licensees. The information in this manual is subject to
change without notice, and should not be construed as a commitment by
Rogue Wave. Rogue Wave assumes no responsibility for any errors that
appear in this document.
TotalView and TotalView Technologies are registered trademarks of Rogue
Wave Software, Inc. TVD is a trademark of Rogue Wave.
Rogue Wave uses a modified version of the Microline widget library. Under
the terms of its license, you are entitled to use these modifications. The
source code is available at:
http://www.roguewave.com/support/knowledge-base.aspx.
All other brand names are the trademarks of their respective holders.
ROGUEWAVE.COM
ii
Contents
Locating Memory Problems 1
Checking for Problems 2
Programs and Memory 3
Behind the Scenes 6
Your Program’s Data 7
The Data Section 7
The Stack 7
The Heap 10
Finding Heap Allocation Problems 10
Finding Heap Deallocation Problems 10
realloc() Problems 11
Finding Memory Leaks 11
Starting MemoryScape 13
Using MemoryScape Options 14
Preloading MemoryScape 14
Understanding How Your Program is Using Memory 15
Finding free() and realloc() Problems 17
Event and Error Notification 17
Types of Problems 19
Freeing Stack Memory 19
Freeing bss Data 19
Freeing Data Section Memory 19
Freeing Memory That Is Already Freed 19
Tracking realloc() Problems 20
Freeing the Wrong Address 20
Finding Memory Leaks 21
ROGUEWAVE.COM
Fixing Dangling Pointer Problems 23
Dangling Pointers 24
Batch Scripting and Using the CLI 26
Batch Scripting Using tvscript 26
Using the -dheap Command 26
dheap Example 27
dheap 27
Notification When free Problems Occur 40
Showing Backtrace Information: dheap -backtrace: 41
Guarding Memory Blocks: dheap -guards 41
Memory Reuse: dheap -hoard 42
Writing Heap Information: dheap -export 43
Filtering Heap Information: dheap -filter 43
Checking for Dangling Pointers: dheap -is_dangling: 44
Detecting Leaks: dheap -leaks 44
Block Painting: dheap -paint 45
Red Zones Bounds Checking: dheap -red_zones 45
Deallocation Notification: dheap -tag_alloc 48
TVHEAP_ARGS 49
Examining Memory 51
Block Properties 52
Memory Contents Tab 54
Additional Memory Block Information 55
Filtering 56
Using Guard Blocks 56
Using Red Zones 57
Using Guard Blocks and Red Zones 58
i
Block Painting 58
Hoarding 59
Example 1: Finding a Multithreading Problem 59
Example 2: Finding Dangling Pointer References 59
Debugging with TotalView 60
Memory Tasks 63
Getting Started 64
Starting MemoryScape 64
Adding Programs and Files to MemoryScape 66
Attaching to Programs and Adding Core Files 67
Stopping Before Finishing Execution 68
Exporting Memory Data 68
MemoryScape Information 68
Where to Go Next 69
Adding Parallel Programs 70
Where to Go Next 71
Setting MemoryScape Options 72
Basic Options 72
Advanced Options 74
Halt execution at process exit (standalone MemoryScape only) 75
Halt execution on memory event or error 75
Guard allocated memory 77
Use Red Zones to find memory access violations 77
Restricting Red Zones 78
Customizing Red Zones 78
Paint memory 79
Hoard deallocated memory 79
Where to Go Next 80
Controlling Program Execution 81
Controlling Program Execution from the Home | Summary
Screen 83
Controlling Program Execution from the Manage Processes
Screen 83
Controlling Program Execution from a Context Menu 83
Where to Go Next 83
Seeing Memory Usage 84
Information Types 84
ROGUEWAVE.COM
Process and Library Reports 85
Chart Report 85
Where to Go Next 87
Using Runtime Events 88
Error Notifications 88
Deallocation and Reuse Notifications 90
Where to Go Next 91
Graphically Viewing the Heap 92
Window Sections 92
Block Information 93
Bottom Tabbed Areas 94
Where to Go Next 94
Obtaining Detailed Heap Information 95
Heap Status Source Report 96
Heap Status Source Backtrace Report 98
Where to Go Next 98
Seeing Leaks 99
Filtering Reports 100
Adding, Deleting, Enabling and Disabling Filters 100
Adding and Editing Filters 101
Where to Go Next 103
Viewing Corrupted Memory 104
Examining Corrupted Memory Blocks 104
Viewing Memory Contents 106
Saving and Restoring Memory State Information 107
Procedures for Exporting and Adding Memory Data 107
Using Saved State Information 107
Where to Go Next 108
Comparing Memory 109
Overview 109
Obtaining a Comparison 109
Memory Comparison Report 110
Where to Go Next 111
Saving Memory Information as HTML 112
Saving Report Information 113
Hoarding Deallocated Memory 114
Painting Memory 115
ii
Remote Access 117
Using Remote Display 117
Creating Programs for
Memory Debugging 119
Compiling Programs 120
Linking with the dbfork Library 121
dbfork on IBM AIX on RS/6000 Systems 121
Linking C++ Programs with dbfork 121
dbfork and Linux or Mac OS X 122
dbfork and SunOS 5 SPARC 122
Ways to Start MemoryScape 123
Attaching to Programs 124
Setting Up MPI Debugging Sessions 125
Debugging MPI Programs 125
Debugging MPICH Applications 126
Starting MemoryScape on an MPICH Job 126
Attaching to an MPICH Job 127
Using MPICH P4 procgroup Files 127
Starting MPI Issues 127
Debugging IBM MPI Parallel Environment (PE) Applications 128
Using Switch-Based Communications 128
Performing a Remote Login 128
Starting MemoryScape on a PE Program 129
Attaching to a PE Job 129
Debugging LAM/MPI Applications 129
Debugging QSW RMS Applications 129
ROGUEWAVE.COM
Starting MemoryScape on an RMS Job 130
Attaching to an RMS Job 130
Debugging Sun MPI Applications 130
Attaching to a Sun MPI Job 130
Linking Your Application with
the Agent 131
Using env to Insert the Agent 134
Installing tvheap_mr.a on AIX 135
LIBPATH and Linking 135
Using MemoryScape in Selected Environments 136
MPICH 136
IBM PE 136
RMS MPI 137
MemoryScape Scripting 139
display_specifiers Command-Line Option 139
event_action Command-Line Option 141
Other Command Line Options 143
memscript Example 143
MemoryScape Command-Line Options 145
Invoking MemoryScape 145
Syntax 145
Options 146
Index 149
iii
ROGUEWAVE.COM
iv
Chapter 1
Locating Memory Problems
It’s frequently stated that 60% or 70% of all programming errors are memory related. So, while these numbers could be wrong, let’s assume that
they are right. While algorithmic errors often show themselves easily, memory errors are far more subtle. You can reproduce an algorithmic error with
a predefined set of steps. In contrast, memory errors are seldom reproducible in this way. Worse, the problems they cause happen randomly, and may
not occur every time a program is run.
Why are there so many memory errors? There are many answers. The primary reason is that programs are complicated, and the way in which memory should be managed isn’t clear. Is a library function allocating its own
memory, or should the program allocate it? Once it is allocated, does your
program manage the memory or does the library? Something creates a
pointer to something, then the memory is freed without any knowledge
that something else is pointing to it. Or, and this is the most prevalent reason, a wide separation exists between lines of code, or the time when old
code and new code was written. And, of course, there’s always insufficient
and inaccurate documentation.
In addition, some apparent problems might be irrelevant. If the program
does not free the memory allocated for a small array, it doesn’t mean
much. Or, it can be more efficient not to free the memory since the operat-
ROGUEWAVE.COM
ing system will free it for you when the program ends. On the other hand, if
the program continually allocates memory without freeing it, it will eventually crash because there is no more memory available.
Locating Memory Problems
1
Locate
Checking for Problems
MemoryScape can help you locate many of your program’s memory
problems. For example, you can:
Stop execution when free(), realloc(), and other heap API
problems or actions occur
For example, if your program tries to free memory that it either can’t
or shouldn’t free, MemoryScape can stop execution. This lets you
quickly identify the statement causing the problem. For more information, see “Finding free() and realloc() Problems” on page 17.
Or, after identifying a memory block, you can tell MemoryScape to
stop execution when your program either deallocates or reallocates
it. For more information, see “Deallocation and Reuse Notifications”
on page 90.
List leaks
MemoryScape can display reports of your program’s leaks—leaks are
memory blocks that are allocated and are no longer referenced; that
is, the program no longer can access the memory block, which means
that memory is not available for any other use.
When your program allocates a memory block, MemoryScape creates
and records a backtrace for the block—a backtrace is a list of stack
frames. At a later time when you ask MemoryScape to display leak
information, MemoryScape also displays this backtrace. This means
that you’ll instantly know where your program allocated the memory
block. For more information, see “Finding Memory Leaks” on
page 21.
ROGUEWAVE.COM
memory written beyond the bounds of an allocation
MemoryScape can allocate memory immediately before and after the
blocks your program allocates. When MemoryScape adds these
blocks—called guard blocks—it also initializes them to a bit pattern. If
this bit pattern changes, MemoryScape sees the change when your
program deallocates the block, and stops execution.
MemoryScape can also check all guard blocks at any time during program execution. For more information, see “Using Guard Blocks” on
page 56.
Another option is to use Red Zones, additional pages of memory allocated before or after your block. MemoryScape can apply Red Zones
to your allocated blocks. If MemoryScape detects read or write
access in the Red Zone outside the bounds of your allocated block,
it halts program execution and notifies you of the underrun or overrun. For more information see “Using Red Zones” on page 57.
Paint allocated and deallocated blocks
When your program’s memory manager allocates or deallocates
memory, MemoryScape can write a bit pattern into it. Writing this bit
pattern is called painting.
If your program tries to dereference a pointer through painted memory, it may crash. Fortunately, MemoryScape will trap the action
before your program dumps core, allowing you to see where the
problem occurs. For more information, see “Block Painting” on
page 58.
Hold on to deallocated memory
When you are trying to identify memory problems, holding on to
memory after your program releases it can sometimes help locate
problems by forcing a memory error to occur at a later time. Holding
onto freed memory is called hoarding. For more information, see
“Hoarding” on page 59.
Locating Memory Problems
2
Programs and Memory
When you run a program, your operating system loads the program into
memory and defines an address space in which the program can operate.
For example, if your program is executing in a 32-bit computer, the
address space is approximately 4 gigabytes.
Figure 1: Mapping Program Pages



available
This discussion is generally relevant to most computer architectures.
For information specific to your system, check your vendor documentation.
An operating system does not actually allocate the memory in this
address space. Instead, operating systems memory map this space, which
means that the operating system relates the theoretical address space
your program could use with what it actually will be using. Typically, operating systems divide memory into pages. When a program begins executing, the operating system creates a map that correlates the executing
program with the pages that contain the program’s information. Figure 1
shows regions of a program where arrows point to the memory pages
that contain different portions of your program.
Figure 1 also shows a stack containing three stack frames, each mapped
to its own page.
Stack
library
library
library
available

Heap

Program
Similarly, the heap shows two allocations, each mapped to its own page.
(This figure vastly simplifies actual memory mapping, since a page can
have many stack frames and many heap allocations.)
ROGUEWAVE.COM
Locating Memory Problems
3
The program did not emerge fully formed into this state. It had to be
compiled, linked, and loaded. Figure 2 shows a program whose source
code resides in four files.
Figure 2: Compiling Programs
source
file
source
file
source
file
source
file
compile
object
file
object
file
object
file
library
file
object
file
library
file
link
Load File
data section
symbol table
section
machine code
(text) section
header section
ROGUEWAVE.COM
Running these files through a compiler creates object files. A linker then
merges these object files and any external libraries needed into a load
file. This load file is the executable program stored on your computer’s
file system.
When the linker creates the load file, it combines the information contained in each of the object files into one unit. Combining them is relatively straightforward. The load file at the bottom of Figure 2 also details
this file’s contents, as this file contains a number of sections and additional information. For example:
Data section—contains static variables and variables initialized
outside of a function. Here is a small sample program that shows
these initializations:
int my_var1 = 10;
void main ()
{
static int my_var2 = 1;
int my_var3;
my_var3 = my_var1 + my_var2;
printf(“here’s what I’ve got: %i\n”, my_var3);
}
The data section contains the my_var1 and my_var2 variables. In
contrast, the memory for the my_var3 variable is dynamically and
automatically allocated and deallocated within the stack by your program’s runtime system.
Symbol table section—contains addresses (usually offsets) to the
locations of routines and variables.
Machine code section—contains an intermediate binary representation of your program. (It is intermediate because the linker has not yet
resolved the addresses.)
Header section—contains information about the size and location
of information in all other sections of the object file.
When the linker creates the load file from the object and library files, it
interweaves these sections into one file. The linking operation creates
something that your operating system can load into memory. Figure 3
shows this process.
Locating Memory Problems
4
Figure 4: Memory Usage Chart Report
Figure 3: Linking a Program
Data
Section
Symbol Table
Section
Machine Code
(text) Section
Header
Section
Data
Section
Data
Section
Symbol Table
Section
Symbol Table
Section
Machine Code
(text) Section
Machine Code
(text) Section
Header
Section
Header
Section
Data
Section
While there are other memory usage reports, the Chart Report provides a
concise summary of how your program is using memory.
For information, see Task 5: “Seeing Memory Usage” on page 84.
Symbol Table
Section
Machine Code
(text) Section
Header
Section
MemoryScape can provide information about these sections and the
amount of memory your program is using. To obtain this information, use
the Memory Reports | Memory Usage and select Chart report, Figure 4.
ROGUEWAVE.COM
Locating Memory Problems
5
If
Behind the Scenes
MemoryScape intercepts calls made by your program to heap library
functions that allocate and deallocate memory by using the malloc() and
free() functions and related functions such as calloc() and realloc(). The
technique it uses is called interposition. MemoryScape’s interposition
technology uses an agent routine to intercept calls to functions in this
library. This agent routine is sometimes called the Heap Interposition
Agent (HIA).
You can use MemoryScape with any allocation and deallocation library
that uses such functions as malloc() and free(). Typically, this library is
called the malloc library. For example, the C++ new operator is almost
always built on top of the malloc() function. If it is, MemoryScape can
track it. Similarly, if your Fortran implementation use malloc() and free()
functions to manage memory, MemoryScape can track Fortran heap
memory use.
You can interpose the agent in two ways:
You can tell MemoryScape to preload the agent. Preloading means that
the loader places an object before the object listed in the application’s
loader table.
When a routine references a symbol in another routine, the linker
searches for that symbol’s definition. Because the agent’s routine is
the first object in the table, your program invokes the agent’s routine
instead of the routine that was initially linked in.
On Linux and Sun, MemoryScape sets an environment variable that
contains the pathname of the agent’s shared library. For more information, see “Using env to Insert the Agent” on page 134.
ROGUEWAVE.COM
MemoryScape cannot preload the agent, you will need to explicitly
link it into your program. For details, see Chapter 4, “Creating Programs for Memory Debugging,” on page 119.
If your program attaches to an already running program, you must
explicitly link this other program with the agent.
After the agent intercepts a call, it calls the original function. This means
that you can use MemoryScape with most memory allocators. Figure 5
shows how the agent interacts with your program and the heap library.
Figure 5: Interposition
MemoryScape obtains
backtrace
ptr = malloc(...);
interceptor
malloc()
recorder
returned
value
program
agent
heap
manager
interceptor and recorder
place information
in agent tables
Because MemoryScape uses interposition, memory debugging can be
considered non-invasive. That is, MemoryScape doesn’t rewrite or augment your program’s code, and you don’t have to do anything in your
program. Because the agent lives in the user space, it will add a small
amount of overhead to the program’s behavior, but it should not be significant.
Locating Memory Problems
6
Your Program’s Data
Your program’s data resides in the following places:
The Data Section
The Stack
The Heap
The stack differs from the data section in that your program implicitly
manages its space. What’s in it one minute might not be there a minute
later. Your program’s runtime environment allocates memory for stack
frames as your program calls routines and deallocates these frames when
execution exits from the routine.
A stack frame contains control information, data storage, and space for
passed-in arguments (parameters) and the returned value (and much
more). Figure 6 shows three ways in which a compiler can arrange stack
frame information.
Figure 6: Placing Parameters
The Data Section
Your program uses the data section for storing static and global variables.
Memory in this section is permanently allocated, and the operating system sets its size when it loads your program. Variables in this section
exist for the entire time that your program executes.
Errors can occur if your program tries to manage this section’s memory.
For example, you cannot free memory allocated to variables in the data
section. In general, data section errors are usually related to not understanding that the program cannot manage data section memory.
The Stack
Memory in the stack section is dynamically managed by your program or
operating system’s memory manager. Consequently, your program cannot allocate memory in the stack or deallocate memory in it.
“Deallocates” means that your program tells a memory manager
that it is no longer using this memory. The next time your program
calls a routine, the new stack frame overwrites the memory previously used by other routines. In almost all cases, deallocated memory, whether on the stack or the heap, just hangs around in its predeallocation state until it gets reassigned.
ROGUEWAVE.COM
Local data
Local data
Local data
Control
information
Control
information
Control
information
Parameters
Returned
value
Returned
value
Returned
value
Parameters
Parameters
Local data
Local data
Local data
Control
information
Control
information
Control
information
Parameters
Returned
value
Returned
value
Returned
value
Parameters
In this figure, the left and center stack frames have different positions for
the parameters and returned value. The stack frame on the right is a little
more complicated. In this version, the parameters reside in a stack memory area that doesn’t belong to either stack frame.
Locating Memory Problems
7
If a stack frame contains local (sometimes called automatic) variables,
where is this memory placed? If the routine has blocks in which memory
is allocated, where on the stack is this memory for these additional variables placed? Although there are many variations, Figure 7 shows two of
the more common ways to allocate memory.
Figure 8: Four Stack Frames
Stack frame 1
Stack frame 2
Figure 7: Local Data in a Stack Frame
Block data
Local data
Local data
State
information
State
information
Parameters
Returned
value
Returned
value
Parameters
The blocks on the left show a data block allocated within a stack frame
on a system that ignores your routine’s block structure. The compiler figures how much memory your routine needs, and then allocates enough
memory for all of a routine’s automatic variables. These kinds of systems
minimize the time necessary to allocate memory. Other systems dynamically allocate the memory required within a routine as the block is
entered, and then deallocate it as execution leaves the block. (The blocks
on the right show this.) These systems minimize a routine’s size.
As your program executes routines, routines call other routines, placing
additional routines on the stack. Figure 8 shows four stack frames. The
shaded areas represents local data.
Stack frame 3
Stack frame 4
What happens when a program passes a pointer to memory in a stack
frame to lower frames? Figure 9 shows a program passing a pointer to
memory in stack frame 1 down to lower stack frames.
Figure 9: Passing Pointers
Stack frame 1
Stack frame 2
Stack frame 3
Stack frame 4
In this figure, the arrows on the left represent an address contained
within a pointer, an address that is passed down the stack. The lines and
arrow on the right indicate the place to which the pointer is pointing. A
pointer to memory in frame 1 is passed to frame 2, which passes the
pointer to frame 3, and then to frame 4. In all frames, the pointer points
ROGUEWAVE.COM
Locating Memory Problems
8
to a memory location in frame 1. Stated in another way, the pointers in
frames 2, 3, and 4 point to memory in another stack frame. This is the
most efficient way for your program to pass data from one routine to
another since your program passes the pointer instead of the actual
data. Using the pointer, the program can both access and alter the information that the pointer is pointing to.
Sometimes you read that data can be passed “by-value” (which
means copying it) or “by-reference” (which means passing a
pointer). This really isn’t true. Something is always copied. “Pass
by reference” means that instead of copying the data, the program
copies a pointer to the data.
Because the program’s runtime system owns stack memory, you cannot
free it. Instead, your program’s runtime system frees it when it pops a
frame from the stack.
One of the reasons for memory problems is that it may not be clear
which component owns a variable’s memory. For example, Figure 10
shows a routine in frame 1 that has allocated memory in the heap, and
which passes a pointer to that memory to other stack frames.
Heap memory
Stack frame 2
Figure 11: Allocating a Block from a Stack Frame
Stack frame 1
Stack frame 2
Figure 10: Allocating a Memory Block
Stack frame 1
If the routine executing in frame 4 frees this memory, all pointers to that
memory are dangling; that is, they point to deallocated memory. If the
program’s memory manager reallocates this heap memory block, the
data accessible by all the pointers is both invalid and wrong. Note that if
the memory manager doesn’t immediately reuse the block, the data
accessed through the pointers is still correct.
The timing of the reallocation and reuse of a block by another allocation
request means there is no guarantee that the data is correct when the
program accesses the block, and there is never a pattern to when the
block’s data changes. Consequently, the problem occurs only intermittently, which makes it nearly impossible to locate. Worse, development
systems usually are not as memory stressed as production systems, so
the problem may occur only in the production environment.
Another common problem occurs when you allocate memory and assign
its location to an automatic variable, shown in Figure 11.
Stack frame 3
Stack frame 4
Heap memory
Stack frame 3
If frame 4 returns control to frame 3 without deallocating the heap memory it created, this memory is no longer accessible, and your program can
no longer use this memory block. It has leaked this memory block.
Stack frame 4
ROGUEWAVE.COM
Locating Memory Problems
9
If you have trouble remembering the difference between a leak and a
dangling pointer, the following figure may help. In both cases, your
program allocates heap memory, and the address of this memory
block is assigned to a pointer. A leak occurs when the pointer gets
deleted, leaving a block with no reference. In contrast, a dangling
pointer occurs when the memory block is deallocated, leaving a
pointer that points to deallocated memory. Both are shown in
Figure 12.
Figure 12: Leaks and Dangling Pointers
ptr
ptr
normal allocation
ptr
leaked memory
dangling pointer
MemoryScape can tell you about all of your program’s leaks. For information on detecting leaks, see “Finding Memory Leaks” on page 21.
The Heap
The heap is an area of memory that your program uses when it wants to
dynamically allocate space for data. While using the heap gives you a
considerable amount of flexibility, your program must manage this
resource. That is, the program must explicitly allocate and deallocate this
space. In contrast, the program does not allocate or deallocate memory
in other areas.
ROGUEWAVE.COM
Because allocations and deallocations are intimately linked with your
program’s algorithms and, in some cases, the way the program uses this
memory is implicit rather than explicit, problems associated with the
heap are the hardest to find.
Finding Heap Allocation Problems
Memory allocation problems are seldom due to allocation requests.
Because an operating system’s virtual memory space is large, allocation
requests usually succeed. Problems most often occur if you are either
using too much memory or leaking it. Although problems are rare, you
should always check the value returned from calls to allocation functions
such as malloc(), calloc(), and realloc(). Similarly, you should always check
whether the C++ new operator returns a null pointer. (Newer C++ compilers throw a bad_alloc exception.) If your compiler supports the
new_handler operator, you can throw your own exception.
Finding Heap Deallocation Problems
MemoryScape can let you know when your program encounters a problem in deallocating memory. Some of the problems it can identify are:
free() not allocated: An application calls the free() function by using an address that is not in a block allocated in the heap.
realloc() not allocated: An application calls the realloc() function
by using an address that is not in a block allocated in the heap.
Address not at start of block: A free() or realloc() function receives
a heap address that is not at the start of a previously allocated
block.
If a library routine uses the program’s memory manager (that is, it is using
the heap API) and a problem occurs, MemoryScape still locates the problem. For example, the strdup() string library function calls the malloc()
function to create memory for a duplicated string. Since the strdup()
function is calling the malloc() function, MemoryScape can track this
memory.
Locating Memory Problems
10
MemoryScape can stop execution just before your program misuses a
heap API operation. This lets you see what the problem is before it actually occurs. (For a reminder, see “Behind the Scenes” on page 6.)
Figure 13: realloc() Problem
before calling realloc()
When Memory Scape is used with TotalView, execution stops before
your program’s heap manager deallocates memory, you can use the
Thread > Set PC command to set the PC to a line after the free()
request. This means that you can continue debugging past a problem that might cause your program to crash. In this case, the problem is solved while in the debugger. You still need to fix the problem.
ptr 1
ptr 2
after calling realloc()
realloc() Problems
The realloc() function can either extend a current memory block, or create a new block and free the old. When it creates a new block, it can create problems. Although you can check to see which action occurred, you
need to code realloc() usage defensively so that problems do not occur.
Specifically, you must change every pointer pointing to the memory block
that was reallocated so that it points to the new one. Also, if the pointer
doesn’t point to the beginning of the block, you need to take some corrective action.
In Figure 13, two pointers are pointing to a block. After the realloc() function executes, ptr1 points to the new block. However, ptr2 still points to
the original block, a block that a program deallocated and returned to
the heap manager.
ptr 2
ptr 1
If you use block painting, MemoryScape can initialize the first block with
a bit pattern. If your program is able to display the contents of this block
to you, you’ll be able to see what kind of problem occurred.
Finding Memory Leaks
A memory “leak” is a block of memory that a program allocates that is no
longer referenced. (Technically, there’s no such thing as a memory leak.
Memory doesn’t leak and can’t leak.) For example, when your program
allocates memory, it assigns the block’s location to a pointer. A leak can
occur if one of the following occurs:
You
The
ROGUEWAVE.COM
assign a different value to that pointer.
pointer was a local variable and execution exited from the block.
Locating Memory Problems
11
If your program leaks a lot of memory, it can run out of memory. Even if it
doesn’t run out of memory, your program’s memory footprint becomes
larger. This increases the amount of paging that occurs as your program
executes. Increased paging makes your program run slower.
Here are some of the circumstances in which memory leaks occur:
Orphaned ownership—Your program creates memory but does
not preserve the address so that it can deallocate it at a later time.
The following example makes this (extremely) obvious:
char *str;
for( i = 1; i <= 10; i++ )
{
str = (char *)malloc(10*i);
}
free( str );
In the loop, your program allocates a block of memory and assigns
its address to str. However, each loop iteration overwrites the address
of the previously created block. Because the address of the previously allocated block is lost, its memory can never be made available
to your program.
Concealed allocation—Creating a memory block is separate from
using it.
Because all programs rely on libraries in some fashion, you must
understand what responsibilities you have for allocating and managing memory. As an example, contrast the strcpy() and strdup() functions. Both do the same thing—they copy a string. However, the
strdup() function uses the malloc() function to create the memory it
needs, while the strcpy() function uses a buffer that your program creates.
ROGUEWAVE.COM
In many cases, your program receives a handle from a library. This
handle identifies a memory block that a library allocated. When you
pass the handle back to the library, it knows which memory block
contains the data you want to use or manipulate. There may be a
considerable amount of memory associated with the handle, and
deleting the handle without telling the library to deallocate the memory associated with the handle leaks memory.
Changes in custody—The routine creating a memory block is not
the routine that frees it. (This is related to concealed allocation.)
For example, routine 2 asks routine 1 to create a memory block. At a
later time, routine 2 passes a reference to this memory to routine 3.
Which of these blocks is responsible for freeing the block?
This type of problem is more difficult than other types of problems in
that it is not clear when your program no longer needs the data. The
only thing that seems to work consistently is reference counting. In
other words, when routine 2 gets a memory block, it increments a
counter. When it passes a pointer to routine 3, routine 3 also increments the counter. When routine 2 stops executing, it decrements
the counter. If it is zero, the executing routine frees the memory. If it
isn’t zero, another routine frees it at another time.
Underwritten destructors—When a C++ object creates memory, it
must have a destructor that frees it. No exceptions. This doesn’t
mean that a block of memory cannot be allocated and used as a
general buffer. It just means that when an object is destroyed, it
needs to completely clean up after itself; that is, the program’s destructor must completely clean up its allocated memory.
For more information, see “Finding free() and realloc() Problems” on
page 17.
Locating Memory Problems
12
Starting MemoryScape
On most architectures, there is not much you need to do to prepare your
program for memory debugging. In most cases, just compile your program using the -g command-line option. In some cases, you may need to
link your program with the MemoryScape agent. (See Chapter 4, “Creating Programs for Memory Debugging,” on page 119 for more information.)
Here is how you start MemoryScape:
1 Start MemoryScape from a shell window. On a Macintosh, depending
upon how it was installed, you can start it using the MemoryScape
program icon.
2 If you didn’t specify a program name on the command line, select Add
new program, Figure 14.
3 If you need to, select your memory debugging options. In most cases,
the defaults are fine. In some cases, you may want to select Low,
Medium, High, or Extreme. If you need finer control, select the
Advanced Options button, Figure 15. For more information, see Task
3: “Setting MemoryScape Options” on page 72.
Figure 15: Memory Debugging Options
Figure 14: Add Programs to Your MemoryScape Session
4 After setting options, MemoryScape displays a screen that lets you
start program execution, Figure 16.
ROGUEWAVE.COM
Locating Memory Problems
13
Halt
Figure 16: Program Created Screen
Whenever your program is stopped—which happens when you halt the
program, when a memory problem occurs, or just before the program
exits—MemoryScape can create a report that describes leaks or one that
shows or describes currently allocated memory blocks.
Using MemoryScape Options
Before your program begins execution, you can set other options by
selecting controls in the Memory Debugging Options screen show in
Figure 15. (Some of these options can be set at other times.) Here’s a
summary of these options:
ROGUEWAVE.COM
execution at process exit—Stops execution before your program
exits. This lets you analyze the memory information that MemoryScape has collected. If the program does finish executing, MemoryScape discards this memory information, and you can no longer
view its reports.
Halt execution on memory event or error— Stops execution and notifies you if a heap event such as a deallocation or a problem occurs.
This is called event notification. (See “Event and Error Notification” on
page 17 for more information.) By default, this is set to On.
Guard allocated memory—Surrounds allocations with a small
amount of additional memory. By default, it uses 8 bytes of memory.
It also writes a pattern into this memory. These additional memory
blocks are called guard blocks. If your program overwrites these
blocks, you can tell that a problem occurred either by asking for a
report or by an event notification when your program deallocates a
guarded block.
Use Red Zones to find memory access violations—Adds a Red Zone
to your allocated blocks. The Red Zone is an additional page of
memory located either before or after your block. If MemoryScape
detects access in the Red Zone that is outside the bounds of your
allocated block, it halts execution of your program and notifies you
of the underrun or overrun. For more information see “Using Red
Zones” on page 57.
Paint memory—Paints allocated and deallocated memory and the
pattern that MemoryScape uses when it paints this memory. For
more information, see “Finding free() and realloc() Problems” on
page 17 and Task 3: “Setting MemoryScape Options” on page 72.
Hoard deallocated memory—Retains deallocated memory blocks,
how much memory to use for these blocks, and the number of
blocks to retain. For more information, see Task 3: “Setting MemoryScape Options” on page 72.
Preloading MemoryScape
MemoryScape must be able to preload your program with its agent. In
many cases, it does this automatically. However, MemoryScape cannot
preload the agent for applications that run on IBM RS/6000 platforms.
Locating Memory Problems
14
For more information, see “Creating Programs for Memory Debugging” on
page 119.
Use the Export Memory Data command on the left side of many screens
when you want to save memory data, Figure 17.
Figure 17: Memory Reports Commands
Understanding How Your Program is
Using Memory
MemoryScape can help you understand how your program is using memory in these ways:
Its Memory Usage reports show how much memory your program’s
processes are using. (See Task 5: “Seeing Memory Usage” on
page 84.)
Its compare feature displays the differences between your program’s
current memory state and saved memory data or the differences between two sets of saved memory data. (See Task 13: “Comparing
Memory” on page 109.)
Its heap status reports tell you how much memory your program allocated and where it was allocated. (See Task 8: “Obtaining Detailed
Heap Information” on page 95.)
You can examine imported memory state information in the same way as
the memory for a live process. For example, you can look for leaks,
graphically display the heap, and so on.
ROGUEWAVE.COM
At a later time, you can import this data back into MemoryScape using
the Add memory debugging file command, which is on the Home | Add
Program screen.
MemoryScape treats this imported information in nearly the same way as
the information it has accumulated for a live process. After selecting
Memory Reports | Memory Comparisons, MemoryScape displays a screen
containing all processes and imported files,Figure 18.
Locating Memory Problems
15
)
Figure 18: Select Processes and Files
Figure 19: Memory Comparison Report
After you select two processes, MemoryScape can display the differences
between this information, Figure 19.
ROGUEWAVE.COM
Locating Memory Problems
16
Finding free() and realloc() Problems
Figure 20: Memory Error Notification Dialog Box
MemoryScape detects problems that occur when you allocate, reallocate, and free heap memory.
This memory is usually allocated by the malloc(), calloc(), and realloc()
functions, and deallocated by the free() and realloc() functions. In C++,
MemoryScape tracks the new and delete operators. If your Fortran programs and libraries use the heap API, MemoryScape tracks their dynamic
memory use. Some Fortran systems use the heap API for assumedshape, automatic, and allocatable arrays. See your system’s man pages
and other documentation for more information.
Event and Error Notification
When one of these errors occurs, MemoryScape places event indicators
by the process and at the top of the window, Figure 21.
Figure 21: Event Indicators
There are a number of events that can cause MemoryScape to stop your
program’s execution, and you can control which of these will actually halt
execution by selecting the Advanced button in the Halt execution area of
the Memory Debugging Options screen, Figure 20.
When you click on one of these indicators, MemoryScape displays the
Manage Processes | Process Events screen, Figure 22.
ROGUEWAVE.COM
Locating Memory Problems
17
Figure 22: Process Event Screen
This screen contains the following kinds of information:
The bold information reports the type of error or event that occurred.
The Event Location tab contains the function backtrace if the error or
event is related to a block allocated on the heap. This is the backtrace that exists when the event occurred. Depending upon the kind
of problem, you may also want to examine the information in the
next two tabs.
ROGUEWAVE.COM
Block Details tab displays this information in a manner similar to
that shown in a graphical heap display.
MemoryScape retains information about the backtrace that existed
when your program allocated and deallocated the memory block.
Select which to display using either the Allocation Location or
Deallocation Location tab.
The
Locating Memory Problems
18
If a memory error occurred, the deallocation backtrace is often the
same as the backtrace shown in the Event Location tab. If the memory
error occurs after your program deallocated this memory, the backtraces are different.
free(addr);
return 0;
}
Freeing Data Section Memory
Types of Problems
This section presents some trivial programs that illustrate some of the
free() and realloc() problems that MemoryScape detects. The errors
shown in these programs are obvious. Errors in your program are, of
course, more subtle.
Freeing Stack Memory
The following program allocates stack memory for the stack_addr variable. Because the memory was allocated on the stack, the program cannot deallocate it.
int main (int argc, char *argv[])
{
void *stack_addr = &stack_addr;
/* Error: freeing a stack address */
free(stack_addr);
return 0;
}
Freeing bss Data
The bss section contains uninitialized data. That is, variables in this section have a name and a size but they do not have a value. Specifically,
these variables are your program’s uninitialized static and global variables. Because they exist in a data section, your program cannot free
their memory.
The following program tries to free a variable in this section:
If your program initializes static and global variables, it places them in
your executable’s data section. Your program cannot free this memory.
The following program tries to free a variable in this section:
static int data_var = 9;
int main (int argc, char *argv[])
{
void *addr = (void *) (&data_var);
/* Error: adress in data section */
free(addr);
return 0;
}
Freeing Memory That Is Already Freed
The following program allocates some memory, and then releases it
twice. On some operating systems, your program will raise a SEGV on the
second free request.
int main ()
{
void *s;
/* Get some memory */
s = malloc(sizeof(int)*200);
/* Now release the memory */
free(s);
/* Error: Release it again */
free(s);
return 0;
}
static int bss_var;
int main (int argc, char *argv[])
{
void *addr = (void *) (&bss_var);
/* Error: address in bss section */
ROGUEWAVE.COM
Locating Memory Problems
19
Tracking realloc() Problems
Reallocate
The following program passes a misaligned address to the realloc() function.
Reallocate
int main (int argc, char *argv[])
{
char *s, *bad_s, *realloc_s;
/* Get some memory */
s = malloc(sizeof(int)*64);
/* Reallocate memory using a misaligned address */
bad_s = s + 8;
realloc_s = realloc(bad_s, sizeof(int)*256));
return 0;
}
In a similar fashion, MemoryScape detects realloc() problems caused by
passing addresses to memory sections whose memory your program
cannot free. For example, MemoryScape detects problems if you try to
do any of the following:
ROGUEWAVE.COM
stack memory.
memory in the data section.
Reallocate memory in the bss section.
Freeing the Wrong Address
MemoryScape can detect when a program tries to free a block that does
not correspond to the start of a block allocated using the malloc() function. The following program illustrates this problem:
int main (int argc, char *argv[])
{
char *s, *misaligned_s;
/* Get some memory */
s = malloc(sizeof(int)*64));
/* Release memory using a misaligned address */
misaligned_s = s + 8;
free(misaligned_s);
free(s);
return 0;
}
Locating Memory Problems
20
Finding Memory Leaks
MemoryScape can locate your program’s memory leaks and display
information about them. Here’s what you can do:
1 Run the program and then halt it when you want to look at memory
problems. You should allow your program to run for a while before
stopping execution to give it enough time to create leaks.
2 Select Memory Reports | Leak Detection, Figure 23.
3 Select a report. For example, you might select Source Report.
The top portion shows all of your program’s files. The second column
in this list shows the number of bytes that are leaked from code in
those files. You may want to click on the Bytes header so that MemoryScape displays which files have the greatest number of leaks.
Figure 23: Leak Detection Source Report
ROGUEWAVE.COM
Locating Memory Problems
21
4 After you select a leak in the top part of the window, the bottom of
the window shows a backtrace of the place where your program allocated the memory. After you select a stack frame in the Backtrace
pane, MemoryScape displays the statement where the block was created.
The backtrace that MemoryScape displays is the backtrace that existed
when your program made the heap allocation request. It is not the current backtrace.
Many users like to generate a report that contains all leaks for the entire
program. If you are running with TotalView, you can set a breakpoint on
your program’s Exit statement. Otherwise, MemoryScape will automati-
ROGUEWAVE.COM
cally stop your program during your program’s exit. After your program
stops executing, generate a Leak Detection Report. You may want to write
this report to disk.
MemoryScape uses a conservative approach to finding memory leaks,
searching roots from the stack, registers, and data sections of the process for references into the heap. Although leaks will not be falsely
reported, some leaks may be missed. If you are within a method that has
leaks, you may need to step out of the method for the leak to be
reported. Leak detection may be sensitive to the compiler used to build
the program.
Locating Memory Problems
22
Block
Fixing Dangling Pointer Problems
You must be using MemoryScape with TotalView to be able to find
dangling pointers.
Fixing dangling pointer problems is usually more difficult than fixing other
memory problems. First of all, you become aware of them only when you
realize that the information your program is manipulating isn’t what it is
supposed to be. Even more troubling, these problems can be intermittent, happening only when your program’s heap manager reuses a memory block. For example, if nothing else is running on your computer, your
program may never reuse the block. If there are a large number of jobs
running, it could reuse a deallocated block quickly.
After you identify that you have a dangling pointer problem, you have
two problems to solve. The first is to determine where your program
freed the memory block. The second is to determine where it should free
this memory. MemoryScape tools that can help you are:
ROGUEWAVE.COM
painting, in which MemoryScape writes a bit pattern into allocated and deallocated memory blocks.
Hoarding, in which MemoryScape holds onto a memory block when
the heap manager receives a request to free it. This is most often
used to get beyond where a problem occurs. By allowing the program to continue executing with correct data, you sometimes have a
better chance to find the problem. For example, if you also paint the
block, it becomes easy to tell what the problem is. In addition, your
program might crash. (Crashing while you are in TotalView is a good
thing, because it will show the crash point, and you will immediately
know where the problem is.)
Watchpoints, in which TotalView stops execution when a new value
is written into a memory block. If MemoryScape is painting deallocated blocks, you immediately know where your program freed the
block.
Block tagging, in which TotalView stops execution when your program deallocates or reallocates memory.
You enable painting and hoarding in the Memory Debugging Options Page,
Figure 24.
Locating Memory Problems
23
Figure 24: Memory Debugging Options
You can turn painting and hoarding on and off. In addition, you can tell
MemoryScape what bit patterns to use when it paints memory. For more
information, see “Block Painting” on page 58.
main(int argc, char **argv)
{
int *addr = 0; /* Pointer to start of block. */
int *misaddr = 0; /* Pointer to interior of block. */
Dangling Pointers
If you enable memory debugging, TotalView displays information in the
Variable Window about the variable’s memory status; that is, whether the
memory is allocated or deallocated. The following small program allocates a memory block, sets a pointer to the middle of the block, and then
deallocates the block:
ROGUEWAVE.COM
addr = (int *) malloc (10 * sizeof(int));
misaddr = addr + 5;
/* Point to block interior */
/* Deallocate the block. addr and */
/* misaddr are now dangling. */
free (addr);
}
Locating Memory Problems
24
Figure 25 shows two Variable Windows. Execution was stopped before
your program executed the free() function. Both windows contain a memory indicator saying that blocks are allocated.
Figure 26: Dangling Description in a Variable Window
Figure 25: Allocated Descriptions in a Variable Window
After your program executes the free() function, the messages change,
Figure 26.
ROGUEWAVE.COM
Locating Memory Problems
25
Using the -dheap Command
Batch Scripting and Using the CLI
You must be using MemoryScape with TotalView to have access to
the CLI.
Batch Scripting Using tvscript
TotalView and MemoryScape can run unattended if you use the tvscript
shell command. This is called batch debugging because like all batch programs, you do not need to use them interactively. In addition, you can
invoke tvscript using cron to schedule debugging at off-hours, so reports
will be ready when you want them.
The commands that tvscript executes can be entered in two ways. The
first is to just use command-line options. The second—and recommended—is to creat a file containing commands that tvscript executes. A
file can contain Tcl callback functions to be called when an event occurs
within your program. These callback functions can also include CLI commands.
Here is an example of how tvscript is invoked using command-line
options on an MPI program:
tvscript -mpi "Open MPI" -tasks 4 \
-create_actionpoint "hello.c#14=>show_backtrace" \
~/Tests/hello-mpi/hello
Some of the events that tvscript can act on are memory events. For
example, if a double_free event occurs, you can create a Tcl callback
function that tells you more about what the event. This callback function
can include CLI commands.
The dheap command tracks memory problems from within the CLI. The
dheap command supports the same functionality as that within the GUI,
with some additional options. Here are actions common to both interfaces:
see the status of MemoryScape, use the dheap command with no
arguments.
To display information about the heap, use dheap -info. You can
show information for the entire heap or limit what TotalView displays
to just a part of it.
To enable and disable MemoryScape, use dheap -enable and dheap
-disable.
To start and stop error notification, use dheap -notify and dheap nonotify.
To filter the information displayed, use dheap -filter.
To check for leaks, use dheap -leaks.
To paint memory with a bit pattern, use dheap -paint.
To hoard memory, use dheap -hoard.
To export view information, use dheap -export.
To detect bounds and use-after-free errors, use dheap -red_zones.
To compare memory states, either against a baseline or against a
saved state or between two saved states, use dheap -compare.
To
Some dheap options are not available in the GUI.
"Batch Debugging Using tvscript" in the TotalView Reference Guide explains
how to use the tvscript command.
ROGUEWAVE.COM
Locating Memory Problems
26
dheap Example
The following example shows typical CLI information returned after MemoryScape locates an error:
d1.<> dheap
process:
Enable
Notify
Available
1
(18993):
yes
yes
yes
1.1
realloc: Address does not match any allocated
block.: 0xbfffd87c
d1.<> dheap -info -backtrace
process
1
(18993):
0x8049e88 -0x8049e98
0x10 [
16]
flags: 0x0 (none)
:
realloc PC=0x400217e5 [/.../malloc_wrappers_dlopen.c]
:
argz_append
PC=0x401ae025 [/lib/i686/libc.so.6]
:
__newlocale
PC=0x4014b3c7 [/lib/i686/libc.so.6]
:
...
.../malloc_wrappers_dlopen.c]
:
main
PC=0x080487c4 [../realloc_prob.c]
:
__libc_start_main PC=0x40140647 [/lib/i686/libc.so.6]
:
_start
PC=0x08048621 [/.../realloc_prob]
0x8049f18 -0x8049f3a
0x22 [
34]
flags: 0x0 (none)
:
realloc PC=0x400217e5 [/.../malloc_wrappers_dlopen.c]
:
main
PC=0x0804883e [../realloc_prob.c]
:
__libc_start_main PC=0x40140647 [/lib/i686/libc.so.6]
:
_start
PC=0x08048621 [/.../realloc_prob]
The information displayed in this example is explained in more detail
later in this chapter.
dheap
The command dheap controls heap debugging
Shows MemoryScape state
dheap [ -status ]
Applies a saved configuration file
ROGUEWAVE.COM
dheap -apply_config { default | filename }
Shows information about a backtrace
dheap -backtrace [ subcommands ]
Compares memory states
dheap -compare subcommands [ optional_subcommands ]
[ process | filename [ process | filename ] ]
Enables or disables MemoryScape
dheap { -enable | -disable }
Enables or disables event notification
dheap -event_filter [ subcommands ]
Writes memory information
dheap -export [ subcommands ]
Specifies which filters MemoryScape uses
dheap -filter [ subcommands ]
Writes guard blocks (memory before and after an allocation)
dheap -guard [ subcommands ]
Enables or disables the retaining (hoarding) of freed memory blocks
dheap -hoard [ subcommands ]
Displays MemoryScape information
dheap -info [ subcommands ]
Indicates whether an address is in a deallocated block
dheap -is_dangling address
Locates memory leaks
dheap -leaks [ -[no]check_interior ]
Enables or disables MemoryScape event notification
dheap -[no]notify
Paints memory with a distinct pattern
dheap -paint [ subcommands ]
Enables or disables the ability to catch bounds errors and use-after-free
errors retaining freed memory blocks
dheap -red_zones [ subcommands ]
Enables or disables allocation and reallocation notification
dheap -tag_alloc subcommand [ start_address [ end_address ] ]
Displays MemoryScape version number
dheap -version
Locating Memory Problems
27
Arguments:
[ -status ]
Displays the current state of MemoryScape. This
tells you if a process is capable of having its heap
operations traced, and if TotalView will notify you if a
notifiable heap event occurs. If TotalView stops a
thread because one of these events occur, it displays
information about this event.
-set_depth depth
-reset_depth
Set or reset the depth. The depth is the
maximum number of PCs that MemoryScape includes when it creates a backtrace. (The backtrace is created when
your program allocates or reallocates a
memory block.) The depth value starts after the trim value. That is, the number of
excluded frames does not include the
trimmed frames.
If you do not use other options to the dheap command, you can omit this option.
-enable/-disable
The option -enable tells TotalView to use the MemoryScape agent to record heap events the next time
you start the program. The -disable option tells TotalView not to use the agent the next time you start
your program.
If necessary, you must preload the agent (see Chapter 4, “Creating Programs for Memory Debugging,”
on page 119 for information) before using this option.
When you use the -reset_depth option,
TotalView either restores its default setting or the setting you set using the
TVHEAP_ARGS environment variable.
-set_trim trim
-reset_trim
Sets or resets the trim. The trim describes
the number of PCs from the top of the
stack that MemoryScape ignores when it
creates a backtrace. As the backtrace includes procedure calls from within MemoryScape, setting a trim value removes
them from the backtrace. The default is
to exclude MemoryScape procedures.
Similarly, your program might call the
heap manager from within library code. If
you do not want to see call frames showing a library, you can exclude them.
-apply_config { default | filename }
Applies configuration settings in a file to MemoryScape. If you type default, MemoryScape looks first
in the current directory and then in your .totalview/
hia/ directory for a file named default.hiarc. Otherwise, it uses the name of the file entered here. If you
do not specify an extension, MemoryScape assumes
that the extension is .hiarc. That is, while you can
specify a file named foo.foobar, you cannot specify
a file foo as MemoryScape would then assume that
the file is actually named foo.hiarc.
-backtrace [ subcommands ]
Shows the current settings for the backtraces associated with a memory allocation. This information includes the depth and the trim (described later in this
section).
[ -status ]
Displays backtrace information. If you do not use
other backtrace options, you can omit this option.
ROGUEWAVE.COM
When you use the -reset_trim option, TotalView either restores its default setting
or the setting you set using the
TVHEAP_ARGS environment variable.
-display backtrace_id
Displays the stack frames associated with
the backtrace identified by backtrace_id.
Locating Memory Problems
28
-compare required_subcommands [ optional_subcommands ]
[ process | filename [ process | filename ] ]
required_subcommands
-data { alloc | dealloc | hoard | leaks }
Names the data to be written into the exported compare file, as follows:
alloc: writes heap allocations
hoard: writes deallocations currently held
in the hoard
leaks: writes leaked heap allocatons
-output { directory | filename }
Names the location for writing memory
information. If the name ends with a
slash (/), MemoryScape writes information into a directory; the filenames it uses
are the MemoryScape defaults.
optional_subcommands
-reverse_diff
Changes the order in which MemoryScape makes its comparison. That is,
MemoryScape normally compares the
first named file to the second. This tells
MemoryScape to compare the second to
the first.
-format { html | txt }
Specifies the format to use when it writes
information to disk. If you do not use this
command, MemoryScape writes the information as HTML.
[ process | filename [ process | filename ]
Specifies if the comparison uses a process or a memory debugging export
(.mdbg) file. Your choices are:
No arguments: compare the two processes in the current focus.
ROGUEWAVE.COM
One argument: compare the process in
the current focus with the process/
filename you specify.
Two arguments: compare the two processes/filenames named as arguments.
-event_filter subcommands
The subcommands to this option let you control
which agent events cause MemoryScape to stop
program execution.
[ -status ]
Tells TotalView to display the current
event filter settings. If you do not use
other event filter options, you can omit
this option.
-set { on | off }
Enables or disables event filtering. If you
disable event filtering, MemoryScape displays all events. If you enable event filtering, then you can control which events
MemoryScape displays.
-reset
Resets the event filter to MemoryScape’s
default value. You can create your own
default in a configuration file or by specifying an environment variable setting.
-[no]notify event-list
Enables or disables one or more events.
The event names you can use are:
addr_not_at_start
alloc_not_in_heap
alloc_null
alloc_returned_bad_alignment
bad_alignment_argument
dealloc_notification
double_alloc
free_not_allocated
realloc_not_allocated
realloc_notification
Locating Memory Problems
29
-reset_notify event-list
Resets the event filter to MemoryScape’s
default value for the filters named in the
list. The names you can use are the same
as those you use in the -notify option.
-export required_subcmds [ optional_subcmds ]
Writes information to a file.
required_subcmds
When exporting data, you must use the data and -output options with dheap export:
-data { alloc | alloc_leaks | dealloc | hoard | leaks | raw }
Specifies the data being written, as follows:
alloc: Shows all heap allocations.
alloc_leaks: Shows all heap allocations
and perfrom leak detection. This differs
from the alloc argument in that TotalView
annotates leaked allocations.
dealloc: Shows deallocation data.
hoard: Shows deallocations currently
held in the hoard.
leaks: Shows leaked heap allocations.
raw: Exports all heap informtion for the
process using .mdbg format. This for-
mat’s only purpose is to be imported
back into MemoryScape.
-output filename
Names the file to which TotalView writes
memory information.
optional_subcmds
-[no]check_interior
If you omit the no prefix, tells MemoryScape that a memory block should not
be considered as leaked if a pointer is
pointing anywhere within the block. TotalView ignores this option unless you
also use the -data leaks option.
-format { html| text }
Specifies the format used to write a file. If
you omit this option, MemoryScape
writes an HTML-formatted document.
If you select text, the result is as expected: a text file containing the view’s
information.
There are some limitations and things
you need to know if you select html. The
only supported browser is Firefox, running versions 1.0 or greater. In addition,
you must have JavaScript turned on.
(While information displays correctly in
other browsers such as Internet Explorer
6.0 and Safari, isolated problems can occur.) This file can be quite large and can
take a while to load.
When MemoryScape writes a file, it also
creates a subdirectory with a related
name containing additional information.
For example, if the output file name is
foo.html, MemoryScape creates a subdirectory named foo_files.
If you need to move the output file, you
must also move the related subdirectory
to the same directory.
You can optionally use any of the following options with dheap -export:
ROGUEWAVE.COM
Locating Memory Problems
30
-relative_to_baseline
Using a filter name simply defines where
to locate filter information; you still need
to enable filtering. For example, here is
how you would enable filtering and enable the use of a filter named MyFilter:
If used, MemoryScape limits the information it writes to those created since the
last time you created a baseline. If you
also use the raw data format, MemoryScape ignores this option.
-set_show_backtraces { on | off }
When set to on, TotalView includes backtrace information within the data being
written. As on is the default, you only
need to use this option with the off argument.
-set_show_code { on | off }
When set to on, TotalView includes the
source code for the place where the
memory was allocated with the data being written. As on is the default, you only
need to use this option with the off argument.
-view backtrace
Tells MemoryScape to export a backtrace view instead of a source view. If you
also use the raw data format, MemoryScape ignores this option.
-filter subcommands
Use the -filter options to enable, disable, and show
information about filtering.
-enable [ filter-name-list | all ]
Enables filtering of dheap commands. If
you do not use an argument with this option, this option is equivalent to selecting
Enable Filtering in the MemoryScape Window.
ROGUEWAVE.COM
dheap -filter -enable MyFilter
dheap -filter -enable
If you did not enter the second command, no filtering occurs.
The all argument tells MemoryScape to
enable all of your filters.
-disable [ filter-name-list | all ]
Disables filtering or disables an individual
filter. The way that you use this command
is similar to dheap -filter -enable.
-list [ [-full ] filter-name-list ]
Displays a filter description and its enabled state. If you do not use a filter-name
argument, the CLI displays all defined filters and their enabled states.
If you include the full argument, the information includes all of the filter’s criteria.
-guard subcommands [ start_address [ end_address ] ]
Use the -guard options to enable, disable, set characteristics, and show information about guard
blocks.
[ -status ]
Displays guard settings. If you do not use other
guard options, you can omit the -status option when
you want to see status information.
-check
Checks the guards to see if they have been violated.
If it finds a violated guard, MemoryScape displays information.
-reset
Resets the guards to MemoryScape’s default value.
You can create your own default in a configuration
file or by specifying an environment variable setting.
Locating Memory Problems
31
-reset_max_size
-reset_post_pattern
-reset_pre_pattern
-reset_post_size
-reset_pre_size
Removes all changes you made and restores guard
settings to what they were when you first invoked
MemoryScape.
The default pre-allocation pattern is 0x77777777
and the default post-allocation pattern is
0x99999999.
start_address
If you only only a start_address, MemoryScape either tags or removes the tag
from the block that contains this address. The action it performs depends on
the subcommand you use.
-set { on | off }
Enables or disables the writing of guards.
If you disable this feature after it is enabled, MemoryScape does not remove
existing guard blocks.
end_address
If you also specify an end_address, MemoryScape either tags all blocks beginning
with the block containing the start_address and ending with the block containing the end_address or removes the tag.
The action it performs depends on the
subcommand you use. If end_address is 0
(zero) or you do not type an end_address,
MemoryScape tags or removes the tag
from all addresses beginning with
start_address to the end of the heap.
-set_max_size size
-set_post_size size
-set_pre_size size
Specify a size in bytes. You can set the
sizes of the pre- and post- guards independently. The actual size of a guard can
differ from these settings if MemoryScape needs to adjust the size to meet
alignment and allocation unit size constraints. In addition, you can set the maximum guard size. If the guard size will be
greater than this maximum, MemoryScape does not create a guard.
-hoard [ subcommands ]
Tells MemoryScape not to surrender allocated
blocks back to your program’s heap manager. If you
do not type a subcommand, MemoryScape displays
information about the hoarded blocks. For more information, see “Memory Reuse: dheap -hoard” on
page 42.
The default sizes are 8 bytes.
Setting the maximum size to zero (0) indicates that MemoryScape does not limit
guard sizes. Zero is the default value.
-set_post_pattern pattern
-set_pre_pattern pattern
Defines the pattern MemoryScape uses when it
writes guard blocks.
ROGUEWAVE.COM
[ -status ]
Displays hoard settings. Information displayed indicates if hoarding is enabled, if deallocated blocks are
added to the hoard (or only those that are tagged),
the maximum size of the hoard, and the hoard’s current size.
If you do not use other hoarding options, you can
omit the -status option when you want to see status
information.
Locating Memory Problems
32
-display [ start_address [ end_address ] ]
-info [ subcommand ] [ start_address [ end_address ] ]
Displays information about the heap or regions of
the heap within a range of addresses. If you do not
use the address arguments, the CLI displays information about all heap allocations.
Displays the contents of the hoard. You
can restrict the display by specifying
start_address and end_address. If you omit
end_address or use a value of 0, MemoryScape displays all contents beginning at
start_address and going to the end of the
hoard.
The CLI displays hoarded blocks in the
order in which your program deallocated
them.
-set { on | off }
Enables and disables hoarding.
-reset
Resets MemoryScape settings for hoarding back to their initial value.
-set_all_deallocs { on | off }
Tells MemoryScape whether to hoard
deallocated blocks.
-reset_all_deallocs
Resets MemoryScape settings for hoarding of deallocated blocks to its initial
value.
-set_max_kb num_kb
The information that MemoryScape displays includes the start address, a block’s length, and other
information such as flags or attributes.
-show_backtrace
Displays backtrace information. This list
can be very long.
-show_backtrace_id
Adds backtrace IDs to the information it
displays.
-show_guard_settings
Adds information about guards settings
to the information it displays.
-[no]show_allocater_id
-[no]show_owner_id
The HIA detects when an attempt is
made to release a block using a Mac xx86 malloc zone that is different from the
one which allocated it.
Allocators are the low-level functions
that allocated and deallocate memory.
Sets the maximum size of the hoarded information.
-set_max_blocks num_blocks
Sets the maximum number of hoarded
blocks.
-reset_max_kb
-reset_max_blocks
Resets a hoarding size value back to its
default.
ROGUEWAVE.COM
An owner can be thought of as an instance of a heap manager interface.
start_address
If you just type a start_address, the CLI reports on all allocations beginning at and
following this address. If you also type an
end_address, the CLI limits the display to
those allocations between the start_address and the end_address.
Locating Memory Problems
33
Using the -nonotify option tells TotalView not to
stop execution. Even if you type the -nonotify option, TotalView tracks heap events.
end_address
If you also specify an end_address, the CLI
reports on all allocations between
start_address and end_address. If you type 0,
it’s the same as omitting this argument;
that is, MemoryScape displays information from the start_address to the end of
the address space.
-is_dangling address
Indicates if an address that was once allocated and not yet recycled by the heap
manager is now deallocated.
-leaks
Locates all memory blocks that your program allocated and which are no longer
referenced. That is, using this command
tells MemoryScape to locate all dangling
memory. For more information, see “Detecting Leaks: dheap -leaks” on page 44.
-paint [ subcommands ]
Enables and disables block painting and shows status information. (For more information on block
painting, see “Block Painting: dheap -paint” on
page 45.)
[ -status ]
If you do not use a subcommand to the -paint option, MemoryScape shows the block painting status
information.
-set_alloc {on | off }
-set_dealloc { on | off }
-set_zalloc { on | off }
The on options enable block painting.
They tell MemoryScape to paint a block
when your program’s heap manager allocates, deallocates, or uses a memory
function that sets memory blocks to
zero.
-nocheck_interior
-check_interior
Unless set to -nocheck_interior, MemoryScape considers a memory block as being referenced if the interior portion of
the block is referenced. If you do not set
this option, the default is -check_interior.
You can only paint zero-allocated blocks
if you are also painting regular allocations.
By default, MemoryScape checks to see if
the starting location of an allocated
memory block is referenced.
-[no]notify
Using the -notify option tells TotalView to stop your
program’s execution when MemoryScape detects a
notifiable event, and then print a message (or display a dialog box if you are also using the GUI) that
explains what just occurred. MemoryScape can notify you when heap memory errors occur or when
your program deallocates or reallocates tagged
blocks.
ROGUEWAVE.COM
Shows the current paint settings. These are either
the values you set using other painting options or
their default values.
The off options disable block painting.
-reset_alloc
-reset_dealloc
-reset_zalloc
Resets MemoryScape settings for block painting to
their initial values or to values typed in a startup file.
Locating Memory Problems
34
-set_alloc_pattern pattern
-set_dealloc_pattern pattern
Sets the pattern that MemoryScape uses
the next time it paints a block of memory.
The maximum width of pattern can differ
between operating systems. However,
your pattern can be shorter.
-reset_alloc_pattern
-reset_dealloc_pattern
Resets the patterns used when MemoryScape paints memory to the default values.
-red_zones [subcommands]
Enables or disables the ability to catch
bounds errors and use-after-free errors
retaining freed memory blocks.
Sum
of the space used for fences for allocated blocks.
space used for allocated blocks.
The same set of statistics are also shown for deallocated blocks. In addition, the space used for each
category is shown as a percentage of the overall
space used for Red Zones.
Overall
-info [start_addr [end_addr]]
Displays the Red Zone entries for allocations (and
deallocations) lying in the optionally specified range.
If no range is specified, the entries for the entire address space are displayed.
-set {on | off | reset }
Enables or disables Red Zones. -reset allows the HIA
to determine its setting using the usual rules.
-set_mode {overrun | underrun | unfenced | manual}
Sets the HIA in one of several Red Zone
modes. When a new allocation is requested, the HIA will override the actual
settings for some of the individual controls, and instead use values that correspond to that mode. The settings that
are affected are: pre-fence, post-fence,
and end-positioning. The other settings,
like use-after-free, exit value , and alignment, take their values from the actual
settings of those controls.
Please note that the abbreviation -rz can be used
for -red_zones in the CLI.
-status[-all]
Shows the current HIA Red Zones settings. By default, dheap -red_zones displays only those settings
that can vary in the current mode, so that, for example, in overrun mode the settings for fences and end
positioning are not shown. The dheap -red_zones status -all command causes all settings to be shown,
including those that are overridden for the current
mode.
-stats [start_addr [end_addr]]
Displays statistics relating to the HIA’s
Red Zones allocator for the optionally
specified address range. If no range is
specified, the following statistics are
shown for the entire address space:
Number
of allocated blocks.
Sum of the space requests received by the Red Zones allocator for
allocated blocks.
ROGUEWAVE.COM
The modes are:
dheap
-red_zones -set_mode overrun
The settings used are those that allow overruns to be detected.
These are: no for pre-fence, yes for post-fence, and yes for end-positioned.
dheap
-red_zones -set_mode underrun
The settings used are those that allow underruns to be detected.
These are: yes for pre-fence, no for post-fence, and no for end-positioned.
Locating Memory Problems
35
dheap
-red_zones -set_mode unfenced
The settings used are those that allow use_after_frees to be detected. These are: no for pre-fence, no for post-fence. End-positioned is determined from the control's setting.
dheap
-red_zones -set_mode manual
All settings are determined from their actual values.
-set_pre_fence {on | off }
Enables or disables the pre-fence control. However, the setting is ignored unless the mode is manual.
-set_pre_fence {on | off }
Enables or disables the post-fence control. However, the setting is ignored unless the mode is manual.
-set_use_after_free {on | off }
Enables or disables the use_after_free
control. If enabled, any subequent allocations will be tagged such that the allocation and its fences are retained when
the block is deallocated. Access to the
block is disabled when it is deallocated
to allow attempts to access the block to
be detected.
-set_alignment integer
Regulates the alignment of the start address of a block issued by the Red Zones
allocator. An alignment of zero indicates
that the default alignment for the platform should be used. An alignment of
two ensures that any address returned by
the Red Zones allocator is a multiple of
two. In this case, if the length of the
block is odd, the end of the block will not
line up with the end of the page contain-
ROGUEWAVE.COM
ing the allocation. An alignment of one is
necessary for the end of the block to always correspond to the end of the page.
-set_fence_size integer
Adjusts the fence size used by Red
Zones. A fence size of zero indicates that
the default fence size of one page should
be used. If necessary, the fence size is
rounded up to the next multiple of the
page size. In most cases it should not be
necessary to adjust this control. One instance where it may be useful, however,
is where it is suspected that a bounds error is a consequence of a badly coded
loop, and the stride of the loop is large.
In such a case, a larger fence may be
helpful.
-set_end_aligned {on | off }
Controls whether the allocation is positioned at the end or the start of the containing page. The control in the HIA is
always updated, though the actual value
is ignored in overrun and underrun
modes.
-set_exit_value integer
Adjusts the exit value used if the HIA terminates the target following detection of
a Red Zones error. Generally, the application fails if it is allowed to continue after
a Red Zone error has been detected. In
order to allow some control over the application's exit code, the HIA will call exit
when an error is detected. The value it
passes to exit as a termination code can
be controlled, so that if the application is
run from scripts, the cause for the termination can be determined.
Locating Memory Problems
36
-size_ranges [ subcommands ]
Enables the user to restrict the use of
Red Zones to allocations of particular
sizes. With size ranges are enabled, the
Red Zones allocator will be used if the
size of the request lies in one of the defined ranges. A value is deemed to lie in
a range if start <= size <= end.
To make typing a bit easier, -size_ranges
can be abbreviated to -sr.
motivation here is to allow TotalView to
keep a state that would otherwise be lost
if the target is detached, and then reattached to later.
The second attribute is the “active” attribute. This indicates if the size range is
active, and therefore whether it is used
by the HIA when determining whether the
Red Zones allocator should be used.
-set { on | off }
A range having an end of 0 is interpreted
as having no upper limit. Thus if the end
is 0, the size matches the range if it is at
least as large as the start.
Enables and disables size ranges. If size
ranges are disabled, but Red Zones are
enabled, the Red Zones allocator will be
used for all allocations.
This feature allows the HIA to enable Red
Zones for specific allocation sizes. The
Red Zones allocator will be used if the
size of the request lies in any one of
these ranges. The HIA does not check to
see that ranges do not overlap or are
otherwise consistent.
-reset
The determination of whether the Red
Zones allocator should be used is made
at the time of the original allocation.
Thus, once an allocator has taken ownership of a block, that allocator will be used
for the remainder of the block's life. In
particular, all realloc operations will handled by the same allocator, irrespective
of the size range settings at the time of
reallocation.
There are two attributes associated with
each range. The first is the “in_use” attribute. This is ignored by the HIA, and is
provided for the benefit of TotalView. The
ROGUEWAVE.COM
Unsets the TotalView setting for the enable/disable control.
-status |-all id_range|
Shows the current settings of the size
ranges. The absence of an id_range is
equivalent to an id_range of “0:0”. By default, only “in_use” size ranges are displayed. To display all known ranges,
specify -all. id_range must be in one of
the following formats:
x:y
:y
x:
x
= ids from x to y
= ids from 1 to y
= id of x and higher
= id is x
-set_range id size_range
Set a size range identified by id to a particular size range. size_range must be in
one of the following formats:
Locating Memory Problems
37
x:y
:y
x:
x
conjunction with hoarding. To reenable
memory reuse, use the nohoard_on_dealloc subcommand. See
“Memory Reuse: dheap -hoard” on
page 42 for more information.
= allocations from x to y
= allocations from 1 to y
= allocations of x and higher
= allocations of x
-reset_range id_range
If you use this option, the memory
tracker only hoards tagged blocks. In
contrast, if you use the dheap -hoard set_all_deallocs on command, MemoryScape hoards all deallocated blocks.
Resets an id or range of ids. id_range
must be in a format defined above.
-set_in_use { on | off} id_range
Adjusts the “in_use” attribute of all the
size ranges whose ids lie within id_range.
-set_active { on | off} id_range
-[no]notify_dealloc
-[no]notify_realloc
Enable or disable notification when your
program deallocates or reallocates a
memory block.
Adjusts the “active” attribute of all the
size ranges whose ids lie within id_range.
-reset_mode
-reset_pre_fence
-reset_post_fence
-reset_use_after_free
-reset_alignment
-reset_fence_size
-reset_exit_value
-reset_end_aligned
start_address
If you only type a start_address, MemoryScape either tags or removes the tag
from the block that contains this address. The action it performs depends on
the subcommand you use.
end_address
Unsets the TotalView settings for the
above controls.
-tag_alloc subcommand [ start_address [ end_address ] ]
Marks a block so that it can notify you when your
program deallocates or reallocates a memory block.
(For more information, see “Deallocation Notification: dheap -tag_alloc” on page 48.)
When tagging memory, if you do not specify address
arguments, MemoryScape either tags all allocated
blocks or removes the tag from all tagged blocks.
-[no]hoard_on_dealloc
Does not release tagged memory back to
your program’s heap manager for reuse
when it is deallocated—this is used in
ROGUEWAVE.COM
If you also specify an end_address, MemoryScape either tags all blocks beginning
with the block containing the start_address and ending with the block containing the end_address or removes the tag.
The action it performs depends on the
subcommand you use. If end_address is 0
(zero) or you do not type an end_address,
MemoryScape tags or removes the tag
from all addresses beginning with
start_address to the end of the heap.
-verbosity [ subcommands ]
The subcommands to this option let you control
how much information MemoryScape displays as it
executes.
Locating Memory Problems
38
[ -status ]
Displays the current verbosity setting. If
you do not use other verbosity options,
you can omit this option.
-reset
Restores the verbosity setting to its default.
-set verbosity
Controls how much output MemoryScape writes to its output file. By default,
this is file descriptor 1. Higher verbosity
values tell MemoryScape to write more
information. Setting verbosity to zero (0)
suppresses output.
For more information, see
“TVHEAP_ARGS” on page 49.
-version
Displays the MemoryScape version number.
Description:
The dheap command controls MemoryScape. MemoryScape can:
Tell TotalView to use the MemoryScape agent to track memory errors.
Stop execution when a free() error occurs, and display information
you need to analyze the error. For more information, see “Notification When free Problems Occur” on page 40.
Hoard freed memory so that it is not released to the heap manager.
For more information, see “Memory Reuse: dheap -hoard” on
page 42.
Write heap information to a file. For more information, see “Writing
Heap Information: dheap -export” on page 43.
Remove unwanted information from displays. For more information,
see “Filtering Heap Information: dheap -filter” on page 43.
Use guard blocks. After MemoryScape writes guard blocks, you can
ask it to tell you if blocks are violated. For more information, see
“Guarding Memory Blocks: dheap -guards” on page 41.
Detect leaked memory by analyzing if a memory block is reachable.
For more information, see “Detecting Leaks: dheap -leaks” on
page 44.
ROGUEWAVE.COM
Compare
memory states. You can compare the current state against
a saved state or compare two saved states.
Paint memory with a bit pattern when your program allocate and
deallocates it. For more information, see “Block Painting: dheap paint” on page 45.
Use Red Zones to detect bounds and use-after-free errors. For more
information, see “Red Zones Bounds Checking: dheap -red_zones”
on page 45.
Notify you when your program deallocates or reallocates a memory
block. For more information, see “Deallocation Notification: dheap tag_alloc” on page 48.
The first step when debugging memory problems is to type the dheap
-enable command. This command activates MemoryScape. You must do
this before your program begins executing. If you try to do this after execution starts, TotalView tells you that it will enable MemoryScape when
you restart your program. For example:
d1.<> n
64 >
int
num_reds
= 15;
d1.<> dheap -enable
process 1 (30100): This will only take effect on restart
You can tell MemoryScape to stop execution if:
free() problem exists by using the dheap -notify command.
block is deallocated by using the dheap -tag_alloc -notify_dealloc
command.
A block is reallocated by using the dheap -tag_alloc -notify_realloc
command.
A
A
If you enable notification, TotalView stops the process when it detects
one of these events. MemoryScape is always monitoring heap events,
even if you turned notification off. That is, disabling notification means
that TotalView does not stop a program when events occur. In addition, it
does not tell you that the event occurred.
While you can separately enable and disable notification in any group,
process, or thread, you probably want to activate notification only on the
control group’s master process. Because this is the only process that
TotalView creates, it is the only process where TotalView can control
MemoryScape’s environment variable. For example, slave processes are
Locating Memory Problems
39
normally created by an MPI starter process or as a result of using the
fork() and exec() functions. In these cases, TotalView simply attaches to
them. For more information, see Chapter 4, “Creating Programs for Memory Debugging,” on page 119.
If you do not use a dheap subcommand, the CLI displays memory status
information. You use the -status option only when you want the CLI to
display status information in addition to doing something else.
The information that the dheap command displays can contain a flag
containing additional information about the memory location. The following table describes these flags:
Flag Value
Meaning
0x0001
Operation in progress
0x0002
notify_dealloc: you will be notified if the block is deallocated
0x0004
notify_realloc: you will be notified if the block is reallocated
0x0008
paint_on_dealloc: MemoryScape will paint the block when it is
deallocated
0x0010
dont_free_on_dealloc: MemoryScape will not free the tagged
block when it is deallocated
0x0020
hoarded: MemoryScape is hoarding the block
While some dheap options obtain information on specific memory conditions, you can use the following options throughout your session:
dheap or dheap -status: Displays MemoryScape state information.
For example:
a1.<> dheap -status
process:
1
(18868):
2
(18947):
3
(18953):
4
(18956):
dheap
(18947):
(18953):
(18956):
1.001
1.001
1.001
dheap
-backtrace: Displays information about how much of the
backtrace MemoryScape displays. For example:
a1.<> dheap -backtrace
process:
1
(18868):
2
(18947):
3
(18953):
4
(18956):
Depth
32
32
32
32
Trim
5
5
5
5
Using arguments to this command, you can change both the depth
and the trim values. Changing the depth value changes the number of
stack frames that MemoryScape displays in a backtrace display.
Changing the trim value eliminates the topmost stack frames.
dheap -info: Displays information about currently allocated memory
blocks. For example:
d1.<> dheap -info
process
1
(5320):
0x8049790 -flags: 0x0 (none)
0x80497a0 -flags: 0x0 (none)
0x80497b8 -flags: 0x0 (none)
0x80497e0 -flags: 0x0 (none)
0x804979a
0xa [
10]
0x80497b4
0x14 [
20]
0x80497d6
0x1e [
30]
0x8049808
0x28 [
40]
Notification When free Problems Occur
Enable
yes
n/a
n/a
n/a
Notify
yes
yes
yes
yes
Available
yes
yes
yes
yes
-version: Displays version information. You receive informa-
tion for each process as processes can be compiled with different
versions of MemoryScape. For example:
a1.<> dheap -version
process:
1
(18868):
2
3
4
Version
1.001
ROGUEWAVE.COM
If you type dheap -enable -notify and then run your program, MemoryScape notifies you if a problem occurs when your program tries to free
memory.
When execution stops, you can type dheap (with no arguments), to display information about what happened. You can also use the dheap -info
and dheap -info -backtrace commands to display additional information.
The information displayed by these commands lets you locate the statement in your program that caused the problem. For example:
d1.<> dheap
Locating Memory Problems
40
1
1.1
process:
Enable
Notify
Available
(18993):
yes
yes
yes
realloc: Address does not match any allocated block.:
0xbfffd87c
For each allocated region, the CLI displays the start and end address, and
the length of the region in decimal and hexadecimal formats. For example:
d1.<> dheap
process:
Enable
Notify
Available
1
(30420):
yes
yes
yes
1.1 free: Address is not the start of any allocated block.:
free: existing allocated block:
free: start=0x08049b00 length=(17 [0x11])
free: flags: 0x0 (none)
free:
malloc
PC=0x40021739 [/.../malloc_wrappers_dlopen.c]
free:
main
PC=0x0804871b [../free_prob.c]
free:
__libc_start_main PC=0x40140647 [/lib/i686/
libc.so.6]
free:
_start
PC=0x080485e1 [/.../free_prob]
free:
address passed to heap manager: 0x08049b08
dheap
-backtrace -set_depth value
Limits the number of stack frames to the value that you type as an
argument. The depth value starts after the trim value. That is, the number of excluded frames does not include the frames that were
trimmed.
Guarding Memory Blocks: dheap -guards
When your program allocates a memory block, MemoryScape can surround this block with additional memory. It will also initialize this memory
to a bit pattern. When MemoryScape checks these blocks, it can tell if
your program overwrote the blocks.
Checks can be made in the following ways:
Use the dheap -guard -check command while the process is stopped.
MemoryScape will respond by writing information about all overwritten guard blocks.
Use the dheap -notify command. If you’ve turned on notification,
MemoryScape checks guard blocks when your program deallocates
a memory block. If that memory block’s guards were altered, the CLI
stops program execution and MemoryScape writes information.
MemoryScape can also tell you when your program deallocates or reallocates tagged blocks. For more information, see “Deallocation Notification: dheap -tag_alloc” on page 48.
Showing Backtrace Information: dheap -backtrace:
The backtrace associated with a memory allocation can contain many
stack frames that are part of the heap library, MemoryScape’s library, and
other related functions and libraries. You are not usually interested in this
information, since these stack frames aren’t part of your program. Using
the -backtrace option lets you manage this information, as follows:
dheap
-backtrace -set_trim value
Removes—that is, trims—this number of stack frames from the top
of the backtrace. This lets you hide the stack frames that you’re not
interested in as they come from libraries.
ROGUEWAVE.COM
You should set the TotalView VERBOSE setting to WARNING. Setting it lower than this suppresses this output. Setting it higher tends
to bury the information in debugger runtime information.
Use the dheap -guard -set command to turn this feature on or off. To see
guard block status, use the dheap -guard command without an argument. For example:
d1.<> dheap -guard
process:
1 (13071):
Enabled
yes
Max
0
Size
Pre
8
Post
Pre
8 0x77777777
Pattern
Post
0x99999999
If you are using the dheap -info command, you can include guard block
information in the output by typing dheap -info -show_guard_settings.
Locating Memory Problems
41
Memory Reuse: dheap -hoard
In some cases, you may not want your system’s heap manager to immediately reuse memory. You would do this, for example, when you are trying to find problems that occur when more than one process or thread is
allocating the same memory block. Hoarding allows you to temporarily
delay the block’s release to the heap manager. When the hoard has
reached its capacity in either size or number of blocks, MemoryScape
releases previously hoarded blocks back to your program’s heap manager.
The order in which MemoryScape releases blocks is the order in which it
hoards them. That is, the first blocks hoarded are the first blocks
released—this is a first-in, first-out (FIFO) queue.
Hoarding is a two-step process, as follows:
1 Use the dheap -enable command to tell MemoryScape to track heap
allocations.
2 Use the dheap -hoard -set on command to tell MemoryScape not to
release deallocated blocks back to the heap manager. (The dheap hoard -set off command tells MemoryScape to no longer hoard memory.) After you turn hoarding on, use the dheap -hoard
-set_all_deallocs on command to tell MemoryScape to start hoarding
blocks.
At any time, you can obtain the hoard’s status by typing the dheap hoard command. For example:
d1.<> dheap -hoard
process: Enabled
1 (10883):
yes
All
Max
Max
deallocs
size blocks
Size
yes 16 (kb)
32 15 (kb)
Blocks
9
The Enabled column contains either yes or no, which indicates whether
hoarding is enabled. The All deallocs column indicates if hoarding is
occuring. The next columns show the maximum size in kilobytes and
number of blocks to which the hoard can grow. The last two columns
show the current size of the hoard, again, in kilobytes and the number of
blocks.
ROGUEWAVE.COM
As your program executes, MemoryScape adds the deallocated region to
a FIFO buffer. Depending on your program’s use of the heap, the hoard
could become quite large. You can control the hoard’s size by setting the
maximum amount of memory in kilobytes that MemoryScape can hoard
and the maximum number of hoarded blocks.
dheap -hoard -set_max_kb num_kb
Sets the maximum size in kilobytes to which the
hoard is allowed to grow. The default value on many
operating systems is 32KB.
dheap -hoard -set_max_blocks num_blocks
Sets the maximum number of blocks that the hoard
can contain.
You can tell which blocks are in the hoard by typing the dheap -hoard
-display command. For example:
d1.<> dheap -hoard -display
process
1
(10883):
0x804cdb0 -flags: 0x32 (hoarded)
0x804d3b8 -flags: 0x32 (hoarded)
0x804dac0 -flags: 0x32 (hoarded)
0x804fce8 -flags: 0x32 (hoarded)
0x804fef0 -flags: 0x32 (hoarded)
0x804d3b0
0x600 [
1536]
0x804dab8
0x700 [
1792]
0x804e2c0
0x800 [
2048]
0x804fee8
0x200 [
512]
0x80502f0
0x400 [
1024]
You can enable autoshrinking when hoarding by entering dheap -hoard autoshrink -set on. This allows the hoard to contract automatically when
memory is short. When an allocation request fails because of a shortage
of memory and autoshrinking is enabled, the HIA will eject a block from
the hoard and automatically retry the request. This will continue until
either the allocation succeeds, or the hoard is completely exhausted. In
the latter case, the normal 'allocation operation returned null' event is
raised.
Locating Memory Problems
42
One other feature is associated with autoshrinking: a notification threshold size, given in kb. If, during the course of autoshrinking, the size of the
hoard in kb crosses from above to below the threshold size defined by
-autoshrink -set_threshold_kb num_kb, a new event is raised. This is to
alert the user that space is running out. The event will be particularly
useful when the size of the hoard is unlimited (which means that blocks
released by the application are not returned to the heap manager), and
therefore the size of the hoard really does reflect how much space is left.
One concern regarding the threshold event is that it could be reported
many times if the size of the hoard fluctuates, crossing and recrossing
the threshold. To reduce the noise, a count is associated with the
threshold. The count is decremented each time the event is raised. This
continues until the count reaches zero, after which the count is no longer
decremented, and the event is not raised. Notification can be reactivated by re-priming the counter using the -set_threshold_trigger option.
The default value for the number of times the event is triggered is 1. The
trigger is independent of any event filtering that may be active.
The -autoshrink -reset, -autoshrink -reset_threshold_kb, and -autoshrink reset_threshold_trigger options unset the TotalView settings for these
controls. The HIA will determine its settings using the values in either the
TVHEAP_ARGS environment variable, the HIA configuration file, or its
default values.
Writing Heap Information: dheap -export
You may want to write the information that MemoryScape collects about
your program to disk so that you can examine it at a later time. Or, you
may want to save information from different sessions so that you can
compare changes that you’ve made.
You can save MemoryScape information by using the dheap -export command. This command has two sets of options: one contain options you
must specify, the other contains options that are optional. In all cases,
you must use the:
-output option to name the file to which MemoryScape writes information.
ROGUEWAVE.COM
-data
option to name which data MemoryScape includes.
For example:
dheap -export -output heap.txt -data leaks
You can also add -set_show_code and -set_show_backtraces. These
options are most often used to restrict the amount of information that
MemoryScape displays. You can also use the -check_interior option to tell
MemoryScape that if a pointer is pointing into a block instead of at the
block’s beginning, then the block shouldn’t be considered as being
leaked.
Filtering Heap Information: dheap -filter
Depending upon the way in which your program manages memory, MemoryScape might be managing a lot of information. You can filter this information down to focus on things that are important to you at the moment
by using filters. These filters can only be created using the GUI. However,
after you create a filter using the GUI, you can apply it from within the CLI
by using the dheap -filter commands.
Here is an excerpt from a CLI interaction:
d1.<> dheap -filter -list
Filtering of heap reports is 'disabled'
Individual filters are set as follows:
Disabled
MyFilter
Function contains
d1.<> dheap -filter -enable MyFilter
d1.<> dheap -filter -enable
d1.<> dheap -filter -list
Filtering of heap reports is 'enabled'
Individual filters are set as follows:
Enabled
MyFilter
Function contains
strdup
strdup
d1.<>
Notice that TotalView automatically knew about your filters. That is, it
always reads your filter file. However, TotalView ignores the file until you
both enable the file and enable filtering. That is, while the following two
commands look about the same, they are different:
Locating Memory Problems
43
dheap -filter -enable MyFilter
dheap -filter -enable
The first command tells MemoryScape that it could use the information
contained within the MyFilter filter. However, MemoryScape only uses it
after you enter the second command.
Checking for Dangling Pointers: dheap -is_dangling:
This example is contrived. When creating this example, the variables were
examined for their address and their addresses were used as arguments.
In a realistic program, you’d find the memory block referenced by a
pointer and then use that value. In this case, because it is so simple,
using the CLI dprint command gives you the information you need. For
example:
The dheap -is_dangling command lets you determine if a pointer is still
pointing into a deallocated memory block.
d1.<> dprint addr
addr = 0x080496d0 (Dangling) -> 0x00000000 (0)
d1.<> dprint misaddr
misaddr = 0x080496e4 (Dangling Interior) -> 0x00000000 (0)
You can also use the dheap -is_dangling command to determine if an
address refers to a block that was once allocated but has not yet been
recycled. That is, this command lets you know if a pointer is pointing into
deallocated memory.
If a pointer is pointing into memory that is deallocated, and this memory
is being hoarded, the CLI also lets you know that you are looking at
hoarded memory.
Here’s a small program that illustrates a dangling pointer:
Detecting Leaks: dheap -leaks
main(int argc, char **argv)
{
int *addr = 0;
/* Pointer to start of block.
*/
int *misaddr = 0;
/* Pointer to interior of block. */
The dheap -leaks command locates memory blocks that your program
allocated and are no longer refe enced. It then displays a report that
describes these blocks; for example:
addr = (int *) malloc (10 * sizeof(int));
/* Point to interior of the block. */
misaddr = addr + 5;
/* addr and misaddr now dangling.
free (addr);
printf ("addr=%lx, misaddr=%lx\n",
(long) addr, (long) misaddr);
*/
}
If you set a breakpoint on the printf() statement and probe the addresses
of addr and misaddr, the CLI displays the following:
d1.<> dheap -is_dangling 0x80496d0
process:
0x80496d0
1
(19405):
dangling
d1.<> dheap -is_dangling 0x80496e4
process:
0x80496e4
1
(19405): dangling interior
ROGUEWAVE.COM
d1.<> dheap -leaks
process 1
(32188): total count 9, total bytes 450
* leak 1 -- total count 9 (100.00%), total bytes 450 (100%)
-- smallest / largest / average leak: 10 / 90 / 50
: malloc
PC=0x40021739 [/.../malloc_wrappers_dlopn.c]
: main
PC=0x0804851e [/.../local_leak.cxx]
: __libc_start_main PC=0x40055647 [/lib/i686/libc.so.6]
: _start
PC=0x080483f1 [/.../local_leak]
If you use the -check_interior option, MemoryScape considers a block as
being referenced if a pointer exists to memory inside the block.
In addition to providing backtrace information, the CLI:
Consolidates leaks made by one program statement into one leak
report. For example, leak 1 has nine instances.
Reports the amount of memory consumed for a group of leaks. It
also tells you what percentage of leaked memory this one group of
memory is using.
Indicates the smallest and largest leak size, as well as telling you
what the average leak size is for a group.
Locating Memory Problems
44
You might want to paint a memory block when it is deallocated so that
you can recognize that the data pointed to is out-of-date. Tagging the
block so that you can be notified when it is deallocated is another way to
locate the source of problems.
Notice that all of the values in the red_balls structure in this example
aren’t set to 0xall0ca7f. This is because the amount of memory used by
elements of the variable use more bits than the 0xall0ca7f bit pattern.
The following two CLI statements show the result of printing the x variable, and then casting it into an array of two integers:
When your program allocates or deallocates a block, MemoryScape can
paint the block with a bit pattern. This makes it easy to identify uninitialized blocks, or blocks pointed to by dangling pointers.
d1.<> dprint (red_balls)->x
(red_balls)->x = -2.05181867705792e-149
d1.<> dprint {*(int[2]*)&(red_balls)->x}
*(int[2]*)&(red_balls)->x = {
[0] = 0xa110ca7f (-1592735105)
[1] = 0xa110ca7f (-1592735105)
Here are the commands that enable block painting:
(Diving in the GUI is much easier.)
Block Painting: dheap -paint
dheap
-paint -set_alloc on
dheap -paint -set_dealloc on
dheap -paint -set_zalloc on
Use the dheap -paint command to check the kind of painting that occurs
and what the current painting pattern is. For example:
You can tell MemoryScape to use a different pattern by using the following two commands:
dheap -paint -set_alloc_pattern pattern
dheap -paint -set_dealloc_pattern pattern
d1.<> dheap -paint
1
Alloc
process: Alloc Dealloc AllocZero
pattern
(1012):
yes
yes
no 0xa110ca7f
Dealloc
pattern
0xdea110cf
Some heap allocation routines such as calloc() return memory initialized
to zero. Using the -set_zalloc_on command allows you to separately
enable the painting of the memory blocks altered by these kinds of routines. If you do enable painting for routines that set memory to zero,
MemoryScape uses the same pattern that it uses for a normal allocation.
Here’s an example of painted memory:
d1.<> dprint *(red_balls)
*(red_balls) = {
value = 0xa110ca7f (-1592735105)
x = -2.05181867705792e-149
y = -2.05181867705792e-149
spare = 0xa110ca7f (-1592735105)
colour = 0xa110ca7f -> <Bad address: 0xa110ca7f>
}
The 0xall0ca7f allocation pattern resembles the word “allocate”. Similarly,
the 0xdea110cf deallocation pattern resembles “deallocate”.
ROGUEWAVE.COM
Red Zones Bounds Checking: dheap -red_zones
The Red Zones feature helps catch bounds errors and use-after-free
errors. The basic idea is that each allocation is placed in its own page.
An allocation is positioned so that if an overrun, that is, an access
beyond the end of the allocation, is to be detected, the end of the allocation corresponds to the end of the page.
The page following that in which the allocation lies is also allocated,
though access to this page is disabled. This page is termed the fence.
Should the application attempt to access a location beyond the end of
the allocation, that is, in the fence, the operating system sends the target
a segment violation signal. This is caught by a signal handler installed by
the HIA. The HIA examines the address that caused the violation. If it it
lies in the fence, then the HIA raises an overrun bounds error using the
normal event mechanism.
If, however, the address does not lie in any region that the HIA "owns,"
the HIA attempts to replicate what would have happened if the HIA’s signal handler were not in place. If the application had installed a signal
handler, then this handler is called. Otherwise, the HIA attempts to perLocating Memory Problems
45
form the default action for the signal. It should be clear from this that
the HIA needs to interpose the signal’s API to ensure that it always
remains the installed handler as far as the operating system is concerned. At the same time, it needs to present the application with what
it expects.
Underruns, or errors where the application attempts to read before the
start of an allocation, are handled in a similar way. Here, though, the
allocation is positioned so that its start lies at the start of the page, and
the fence is positioned to precede the allocation.
One complication that arises concerns overrun detection. The architecture or definition of the allocation routines may require that certain
addresses conform to alignment constraints. As a consequence, there
may be a conflict between ensuring that the allocation’s start address
has the correct alignment, and ensuring that the allocation ends at the
end of the page.
Use-after-free errors can also be detected. In this case, when the block is
deallocated, the pages are not returned to the operating system.
Instead, the HIA changes the state of the allocation’s table entry to indicate that it is in the deallocated state, and then disables access to the
page in which the allocation lies. This time, should the application
attempt to access the block after it has been deallocated, a signal will be
raised. Again, the HIA examines the faulting address to see what it
knows about the address, and then either raises an appropriate event for
TotalView, or forwards the signal on.
A key feature distinguishing TotalView Red Zones is that they can be
engaged and disengaged at will during the course of the target's execution. The settings can be adjusted so that new allocations have different
properties from existing allocations. Since Red Zones can be turned on
or off, some of the application's requests can be satisfied by the Red
Zones allocator, and others by the standard heap manager. The HIA
keeps track of which allocator is responsible for, or owns, each block.
The dheap -red_zones [-status [-all]] option displays the current HIA Red
Zone settings. By default, dheap -red_zones displays only those settings
that can vary in the current mode, so that, for example, in overrun mode,
the settings for fences and end positioning are not shown. The dheap
-red_zones -status -all command will cause all settings to be shown,
including those that are overridden for the current mode.
ROGUEWAVE.COM
Please note that the abbreviation -rz can be used in the CLI for red_zones.
The dheap -red_zones -stats [<start_addr [<end addr]] option shows statistics relating to the HIA’s Red Zones allocator for the optionally specified address range. If no range is specified the statistics are shown for
the entire address space. These are:
number of allocated blocks
sum of the space requests received by the Red Zones allocator for
allocated blocks
sum of the space used for fences for allocated blocks
overall space used for allocated blocks
The same set of statistics are also shown for deallocated blocks. In addition, the space used for each category is also shown as a percentage of
the overall space used for Red Zones.
dheap -red_zones -info [<start_addr [<end addr]] shows the Red Zones
entries for allocations (and deallocations) lying in the optionally specified
range. If no range is specified the entries are shown for the entire
address space.
Red Zones is enabled using dheap -red_zones -set on, and disabled with
dheap -red_zones -set off. dheap -red_zones -reset allows the HIA to
determine its setting using the usual rules.
dheap -red_zones -set_mode sets the HIA in one of several Red Zone
modes. When a new allocation is requested, the HIA will override the
actual settings for some of the individual controls, and instead use values
that correspond to that mode. The settings that are affected are: prefence, post-fence, and end-positioning. The other settings, like use-afterfree, exit value, and alignment, take their values from the actual settings
of those controls.
The Red Zone modes are:
dheap
-red_zones -set_mode overrun
The settings used are those that allow overruns to be detected.
These are: no for pre-fence, yes for post-fence, and yes for end
positioned.
dheap
-red_zones -set_mode underrun
The settings used are those that allow underruns to be detected.
These are: yes for pre-fence, no for post-fence, and no for end
positioned.
Locating Memory Problems
46
dheap -red_zones -set_mode unfenced
The settings used are those that allow use_after_frees to be detected. These are: no for pre-fence, no for post-fence. End
positioned is determined from the control's setting.
dheap
-red_zones -set_mode manual
All settings are determined from their actual values.
Use the dheap -red_zones -set_pre_fence (on | off) | -reset_pre_fence
commands to adjust the pre-fence control. However, the setting is
ignored unless the mode is manual.
Use the the dheap -red_zones -set_post_fence (on | off) | -reset_post_fence
commands to adjust the post-fence control. However, the setting is
ignored unless the mode is manual.
To enable the use-after-free control, enter dheap -red_zones -set_use_after_free on. To disable the control enter “off ”. If enabled, any subsequent allocations will be tagged such that the allocation and its fences
are retained when the block is deallocated. Access to the block is disabled when it is deallocated to allow attempts to access the block to be
detected.
The alignment control dheap -red_zones -set_alignment <integer> regulates the alignment of the start address of a block issued by the Red
Zones allocator. An alignment of zero indicates that the default alignment for the platform should be used. An alignment of two ensures that
any address returned by the Red Zones allocator is a multiple of two. In
this case, if the length of the block is odd, then the end of the block will
not line up with the end of the page containing the allocation. An alignment of one would be necessary for the end of the block to always correspond to the end of the page.
Adjusting the fence size is done through the dheap -red_zones set_fence-_size <integer> command. A fence size of zero indicates that
the default fence size of one page should be used. If necessary, the fence
size is rounded up to the next multiple of the page size. In most cases it
should not be necessary to adjust this control. One instance where it
may be useful, however, is where it is suspected that a bounds error is a
consequence of a badly coded loop, and the stride of the loop is large.
In such a case, a larger fence may be helpful.
ROGUEWAVE.COM
dheap -red_zones -set_end_aligned (on | off) controls whether the alloca-
tion is positioned at the end of the containing page or at its start. The
control in the HIA is always updated, though the actual value is ignored
in overrun and underrun modes.
Use dheap -red_zones -set_exit_value <integer> to adjust the exit value
used if the HIA terminates the target following detection of a Red Zone
error. Generally, the application would fail if it is allowed to continue
after a Red Zone error has been detected. In order to allow some control
over the application’s exit code, the HIA will call exit when an error is
detected. The value it passes to exit as a termination code can be controlled, so that if the application is run from scripts the cause for the termination can be determined.
The dheap -red_zones -size_ranges ... option for Red Zones allows the
user to restrict the use of Red Zones to allocations of specified sizes. If
Red Zones are engaged and size ranges are enabled, the Red Zones allocator will be used if the size of the request lies in one of the defined size
ranges. A value is deemed to lie in a range if start <= size <= end.
To make typing a bit easier, -size_ranges can be abbreviated to -sr.
A range having an end of 0 is interpreted as having no upper limit. Thus if
the end is 0, the size matches the range if it is at least as large as the
start.
The HIA supports a number of size ranges. This allows particular ranges
of sizes to be included or excluded. The Red Zones allocator is used if
the size of the request lies in any one of these ranges. The HIA does not
check to see that ranges don't overlap or are otherwise consistent.
The determination of whether the Red Zones allocator should be used is
made at the time of the original allocation. Thus, once an allocator has
taken ownership of a block, that allocator is used for the remainder of
the block's life. In particular, all realloc operations are handled by the
same allocator, irrespective of the size range settings at the time of reallocation.
There are two attributes associated with each range. The first is the
“in_use” attribute. This is ignored by the HIA, and is provided for the
benefit of TotalView. The motivation here is to allow TotalView to keep
the state that would otherwise be lost if the target is detached, and then
reattached to later.
Locating Memory Problems
47
The second attribute is the “active” attribute. This indicates if the size
range is active, and therefore whether it is used by the HIA when determining whether the Red Zones allocator should be used.
The TotalView cli command dheap -red_zones -size_ranges -set on
enables size ranges, and dheap -red_zones -size_ranges -set off disables
size ranges. If size ranges are disabled, but Red Zones are enabled, the
Red Zones allocator will be used for all allocations.
dheap -red_zones -size_ranges -reset unsets the TotalView setting for the
enable/disable control.
The dheap -red_zones -size_ranges -status [-all <id_range> command
shows the current settings of the size ranges. The absence of an
<id_range> is equivalent to an id_range of “0:0”. By default, only
“in_use” size ranges are displayed. To display all known ranges, specify all. <id_range> must be in one of the following formats:
The following Red Zones command options unset the TotalView settings
for these controls:
dheap -red_zones -reset_mode
dheap -red_zones -reset_pre_fence
dheap -red_zones -reset_post_fence
dheap -red_zones -reset_use_after_free
dheap -red_zones -reset_alignment
dheap -red_zones -reset_fence_size
dheap -red_zones -reset_exit_value
dheap -red_zones -reset_end_aligned
When the above commands are entered, the HIA will determine its settings using the values in the TVHEAP_ARGS environment variable, the HIA
configuration file, or its default values.
x:y = id's from x to y
Deallocation Notification: dheap -tag_alloc
:y = id's from 1 to y
x: = id of x and higher
x = id is x
To set a size range identified by <id> to a particular size range the dheap
-red_zones -size_ranges -set_range <id> <size_range> command is
used. <size_range> must be in one of the following formats:
x:y = allocations from x to y
:y = allocations from 1 to y
x: = allocations of x and higher
x = allocations of x
To reset an id or range of ids use dheap -red_zones -size_ranges reset_range <id_range>. <id_range> must be in a format defined
above.
The dheap -red_zones -size_ranges -set_in_use (on | off) <id_range>
option adjusts the “in_use” attribute of all the size ranges whose ids lie
within <id_range>. dheap -red_zones -size_ranges -set_active (on | off)
<id_range> adjusts the “active” attribute of all the size ranges whose ids
lie within <id_range>.
ROGUEWAVE.COM
You can tell MemoryScape to tag information within MemoryScape’s
tables and to notify you when your program either frees a block or passes
it to realloc() by using the following two commands:
dheap
dheap
-tag_alloc -notify_dealloc
-tag_alloc -notify_realloc
Tagging is done within MemoryScape’s agent. It tells MemoryScape to
watch those memory blocks. Arguments to these commands tell MemoryScape which blocks to tag. If you do not type address arguments,
TotalView notifies you when your program frees or reallocates an allocated block. The following example shows how to tag a block and how to
see that a block is tagged:
d1.<> dheap -tag_alloc -notify_dealloc 0x8049a48
process
1
(19387): 1 record(s) update
d1.<> dheap -info
process
1
(19387):
0x8049a48 -0x8049b48
0x100 [
flags: 0x2 (notify_dealloc)
0x8049b50 -0x8049d50
0x200 [
flags: 0x0 (none)
0x8049d58 -0x804a058
0x300 [
256]
512]
768]
Locating Memory Problems
48
flags: 0x0 (none)
Using the -notify_dealloc subcommand tells MemoryScape to let you
know when a memory block is freed or when realloc() is called with its
length set to zero. If you want notification when other values are passed
to the realloc() function, use the -notify_realloc subcommand.
After execution stops, here is what the CLI displays when you type
another dheap -info command:
d1.<> dheap -info
process
1
(19387):
0x8049a48 -0x8049b48
0x100 [
flags: 0x3 (notify_dealloc, op_in_progress)
0x8049b50 -0x8049d50
0x200 [
flags: 0x0 (none)
0x8049d58 -0x804a058
0x300 [
256]
512]
768]
TVHEAP_ARGS
Environment variable for presetting MemoryScape values
When you start TotalView, it looks for the TVHEAP_ARGS environment
variable. If it exists, TotalView reads values placed in it. If one of these
values changes a MemoryScape default value, MemoryScape uses this
value as the default.
If you select a <Default> button in the GUI or a reset option in the CLI,
MemoryScape resets the value to the one you set here, rather than to its
default.
TVHEAP_ARGS Values
The values that you can enter into this variable are as follows:
display_allocations_on_exit=boolean
Tells MemoryScape to dump the allocation table
when your program exits. If your program ends because it received a signal, MemoryScape might not
be able to dump this table.
backtrace_depth=depth
Sets the backtrace depth value. See “Showing Backtrace Information: dheap -backtrace:” on page 41 for
more information.
ROGUEWAVE.COM
backtrace_trim=trim
Sets the backtrace trim value. See “Showing Backtrace Information: dheap -backtrace:” on page 41 for
more information.
enable_event_filtering=boolean
notify_free_not_allocated=boolean
notify_realloc_not_allocated=boolean
notify_addr_not_at_start=boolean
notify_double_alloc=boolean
notify_guard_corruption=boolean
notify_alloc_not_in_heap=boolean
notify_alloc_null=boolean
notify_alloc_returned_bad_alignment=boolean
notify_bad_alignment_argument=boolean
notify_dealloc=boolean
notify_realloc=boolean
notify_double_dealloc=boolean
Same meanings as dheap -event_filter.
enable_guard_blocks=boolean
guard_max_size=positive-integer
guard_pre_size=positive-integer
guard_post_size=positive-integer
guard_pre_pattern=integer
guard_post_pattern=integer
Same meanings as dheap -guard.
enable_hoarding=boolean
hoard_all_blocks=boolean
hoard_maximum_num_blocks=positive-integer
hoard_maximum_kb=positive-integer
Same meanings as dheap -hoard.
enable_hoard_autoshrink=boolean
hoard_autoshrink_threshold_kb=positive-integer
hoard_autoshrink_trigger_count=positive-integer
enable_red_zones=boolean
enable_rz_size_ranges=boolean
rz_alignment=positive-integer
Locating Memory Problems
49
rz_detect_underrun=boolean
rz_detect_overrun=boolean
rz_detect_use_after_free=boolean
rz_end_alligned=boolean
rz_exit_val=integer
rz_fence_size=positive-integer
rz_mode=overrun | underrun |unfenced | manual
rz_size_range=positive-integer,positive-integer,positive-integer
rz_size_range_enable=positive-integer,boolean
Same meanings as with dheap -
paint_on_alloc=boolean
paint_on_dealloc=boolean
paint_on_zalloc=boolean
paint_alloc_pattern=integer
paint_dealloc_pattern=integer
Same meanings as with dheap -paint
verbosity=int
0: Display no information. This is the default.
red_zones.
memalign_strict_alignment_even_multiple
MemoryScape provides an integral multiple of the
alignment rather than the even multiple described in
the Sun memalign documentation. By including this
value, you are telling MemoryScape to use the Sun
alignment definition. However, your results might be
inconsistent if you do this.
output_fd=int
output_file=pathname
Sends output from MemoryScape to the file descriptor or file that you name.
ROGUEWAVE.COM
Sets MemoryScape’s verbosity level. If the level is
greater than 0, MemoryScape sends information to
stderr. The values you can set are:
1: Print error messages.
2: Print all relevant information.
This option is most often used when debugging
MemoryScape problems. Setting the TotalView
VERBOSE CLI variable does about the same thing.
Example:
For more than one value, separate entries with spaces and place the
entire entry within quote. For example:
setenv TVHEAP_ARGS=”output_file=my_file backtrace_depth=16”
Locating Memory Problems
50
Examining Memory
So far, you’ve been reading about memory errors. If only things were this
simple. The large amount of memory available on a modern computer
and the ways in which an operating system converts actual memory into
virtual memory may hide many problems. At some point, your program
can hit a wall—thrashing the heap to find memory it can use or crashing
because, while memory is available, the operating system can’t find a
block big enough to contain your data. In these circumstances, and many
others, you should examine the heap to determine how your program is
managing memory.
MemoryScape can display a lot of information, at times too much.
You can simplify MemoryScape reports using a filter that suppresses
the display of information. For more information on filters, see Task
10: “Filtering Reports” on page 100.
Begin analyzing data by displaying the Memory Reports | Heap Status |
Graphical Report. After generating the report, MemoryScape displays a
visual report of the heap, Figure 27.
Figure 27: Heap Status Graphical Report
ROGUEWAVE.COM
Locating Memory Problems
51
If you place the mouse cursor over a block, MemoryScape displays information about this block in a tooltip.
The display area has three parts. The small upper area contains controls
that specify which content MemoryScape displays. The middle contains
many bars, each of which represents one allocation. The bar’s color indicates if the memory block is allocated, deallocated, leaked, or in the
hoard.
The bottom area has three divisions.
The Overall Totals area summarizes the kinds of information displayed within the top area as well as providing a key to the colors
used when drawing the blocks.
If you select a block in the top area, the Selected Block area (obscured by the information pop-up) contains information about this
block. When you select a block, MemoryScape highlights it within
the top area.
The Related Blocks area on the right displays how many other blocks
your program allocated from the same location. (Actually, this just
shows how many allocations had the same backtrace. If your program got to the same place in different ways, each different way
would have a different backtrace, so MemoryScape doesn’t consider
them related.)
ROGUEWAVE.COM
Now that you have this information, you can begin making decisions.
Obviously, you should fix the leaks. If there were a lot of small blocks, is
your program allocating memory too frequently? Should it be allocating
memory in larger blocks and managing the allocated memory directly? Is
there a pattern of allocations and deallocations that prevents reuse?
Memory managers tend to be lazy. Unless they can easily reuse
memory, they just get more. If you use the Memory Usage Page to
monitor how your program is using memory, you’ll probably find
that your program only gets bigger. Once your program grabs memory from the operating system, it doesn’t usually give it back. And,
while it could reuse this memory if your program deallocates the
block, it is easier and quicker just to grab new memory.
Block Properties
In many places within MemoryScape, you can right click on a displayed
block and select Properties, which launches the Memory Block Properties
dialog, Figure 28.
Locating Memory Problems
52
Figure 28: Memory Block Properties
MEMORY BLOCKS: Contains a list of all memory blocks for which you have
requested property information. Notice the + symbol. When selected,
MemoryScape displays more information about the block. Click on parts
of the third picture in this help topic for information.
POINT OF ALLOCATION: When selected, MemoryScape displays information it has collected about the memory block at the time when it was
allocated. Click over other areas in this picture for information.
ROGUEWAVE.COM
POINT OF DEALLOCATION: When selected, MemoryScape displays information it has collected about the memory block at the time when it was
deallocated. If this tab is empty, the block has not yet been deallocated.
The nformation displayed in this area is the same as the Point of
Allocation tab.
MEMORY CONTENTS: When selected, MemoryScape displays information
about the bytes contained within the block. Click on parts of the second
picture in this help topic for information.
Locating Memory Problems
53
BACKTRACE: Contains the backtrace associated with the block. (A backtrace is the call stack that existed when your program allocated the memory block.) Clicking on a function in this area changes the display in the
Source area.
SOURCE: The Source area shows the line in your program associated with
the selected function and the file containing this line of code.
CLOSE: Closes this window
HIDE BACKTRACE/CONTENT: Hides the bottom part of this window so that
only the Memory Blocks area is visible.
HELP: Tells MemoryScape to display Help text.
Memory Contents Tab
When you click the Memory Contents tab, MemoryScape displays the
contents of this memory block, Figure 29, in a manner similar to that
used in the shell od command.
Figure 29: Memory Block Properties, Memory Contents tab
MEMORY BLOCKS: Contains a list of all memory blocks for which you have
requested property information. Notice the + symbol. When selected,
MemoryScape displays more information about the block. Click on parts
of the third picture in this help topic for information.
ROGUEWAVE.COM
DISPLAY FORMAT: Tells MemoryScape to display information in one of the
following ways: Hexadecimal, Decimal, Unsigned Decimal, Octal,
Character, Float, Binary, or Address. How many characters and the size of
the blocks are set using the Count and Bytes controls.
COUNT: Controls how many memory blocks MemoryScape will display.
BYTES: Specifies the number of bytes to display in each block.
Locating Memory Problems
54
CONTENTS AREA: The left column names the first memory address being
displayed in the remaining columns in the row. The colors used to display
blocks indicates their status, as follows:
Figure 30: Memory Block Properties, Hide Backtrace/Content
CHARACTER DISPLAY AREA: If the contents of a memory address can be
interpreted as a character, it is displayed in this area.
CLOSE: Closes this window
HIDE BACKTRACE/CONTENT: Hides the bottom part of this window so that
only the Memory Blocks area is visible.
HELP: Tells MemoryScape to display Help text.
Additional Memory Block Information
If you expand the top area of the Block Properties window manually or if
you click the Hide Backtrace/Content button, you can see additional
information about the memory block, Figure 30.
BLOCK: Lists the starting and ending address of each block, its status—
means allocated. As this window contains an entry for each block for
which you’ve requested properties, more than one block can be displayed, as is shown here.
COMMENT AREA: As an aid to remember which block is which in this window, add a comment to the block.
GRAPHIC DISPLAY: Shows a display of the blocks similar to how it is
shown in the Heap Status Graphics display and other places where memory is displayed graphically. In this example, guard blocks were used, and
they are indicated by the lighter green area at the ends of the block
BLOCK INFORMATION: Contains status information about the block.
ROGUEWAVE.COM
Locating Memory Problems
55
BLOCK FLAGS: Selecting a checkbox tells MemoryScape that it should
stop execution and notify you when the block is deallocated or reallocated.
CLOSE: Closes this window.
SHOW BACKTRACE/CONTENT: Shows the Backtrace/Content part of this
window that was previously concealed.
HELP: Displays Help text.
Filtering
You can remove information from Backtrace and Source reports by adding a filter. For example, suppose you do not want MemoryScape to show
blocks related to a standard function such as strdup(). By creating and
applying a filter, MemoryScape removes this function’s information from
reports. The exception is the Heap Status Graphical Report. In this report,
filtered blocks are displayed using a lighter version of their ordinary color.
Filtering simplifies the display so you can more easily focus on problems.
For example, filtering allows you to remove leaks originating in libraries
for which you have no control.
Filtering by a function name is just one option. For more information, see
Task 10: “Filtering Reports” on page 100.
Using Guard Blocks
When a program allocates a memory block, it is responsible for not writing data outside the block. For example, if you allocate 16 bytes, you do
not want to write 32 bytes of information into it because this data would
corrupt the information contained in the next block.
MemoryScape can help you detect problems related to writing data
either before or after a block by surrounding blocks with a small amount
of additional memory. It will also write a pattern into this memory. These
additional memory blocks are called guard blocks. If your program writes
data into these blocks, MemoryScape can tell that a problem occurred,
as follows:
When you are displaying a Heap Status report, you can ask for a Corrupted Guard Blocks report. The Heap Status report also shows the
guard regions and corrupted blocks.
When your program deallocates memory, MemoryScape can check
the deallocated block’s guards. If they’ve been altered—that is, if
your program has written data into them—MemoryScape can stop
execution and alert you to the problem.
For example, suppose your program allocates 16 bytes and you write 64
bytes of data. While the first 16 bytes are correctly written, the remaining
48 aren’t. This write request will also overwrite the guard blocks for the
current block and the block that follows, as well as some of the next
block’s data. That is, you will have inadvertently changed some data—
data that when accessed will be incorrect.
Asking for notification when the block is deallocated lets you know that a
problem has occurred. Because you now know which block was corrupted, you can begin to locate the cause of the problem. In many cases,
you will rerun your program, focusing on those blocks.
ROGUEWAVE.COM
Locating Memory Problems
56
Using Red Zones
Red Zone controls appear on the toolbar only on platforms that support Red Zone capabilities. See the Platform Guide for specific platform support.
As discussed in “Using Guard Blocks” on page 56, when a program allocates a memory block, it is responsible to not write or read data outside
the block. Red Zones give you another tool, like guard blocks, for detecting access violations.
MemoryScape can immediately detect when your program oversteps the
bounds of your allocated memory by protecting it with a Red Zone, a
page of memory placed either before or after your allocated block. If your
program tries to read or write in this Red Zone, MemoryScape halts the
ROGUEWAVE.COM
execution of your program and notifies you. When the Red Zone is placed
before the block, MemoryScape detects underruns; conversely, if the Red
Zone is placed after the block, it detects overruns. It can also detect if
your program accesses the block after it has been freed.
Since your program halts when MemoryScape detects an overrun or
underrun, you know exactly where it overstepped the bounds of the
block. The event information shows the current stack trace, to allow you
to pinpoint where the event occurred. It also shows where the corrupted
block was allocated and deallocated, if appropriate.
Using Red Zones can significantly increase your program’s memory consumption, so MemoryScape provides ways to limit their use. You can turn
them on and off at any time during your program’s execution using the
Red Zone button on the toolbar. You can also restrict Red Zone use by
size range, defining a range such that only block sizes within that range
will be protected by Red Zones. You can use multiple ranges collectively
to exclude allocations of a particular size.
For a detailed description of how Red Zones work, see “Red Zones
Bounds Checking: dheap -red_zones” on page 45.
Locating Memory Problems
57
Using Guard Blocks and Red Zones
Block Painting
Guard blocks and Red Zones complement each other in several ways and
can be used together to find your memory corruption problem. While Red
Zones have a high memory consumption overhead, they provide immediate notification when an illegal read or write occurs. Guard blocks add
minimal overhead, but detect only illegal writes, and report corruptions
only when the block is deallocated or when you generate a report. Finding a memory problem with MemoryScape may require a couple of
passes to narrow down your problem.
Start by enabling guard blocks prior to running your program. You can run
a Corrupt Memory report at any time to see whether you have any corrupted blocks. The report shows the blocks that are corrupt and where
they were initially allocated. In your next run, turn off guard blocks and
turn Red Zones on. If memory is tight, enable Red Zones only where
needed, either manually or by using size ranges. MemoryScape should
detect when a block is overwritten and stop execution.
A caveat here: the layout of memory is controlled by the heap manager
and the operating system. Depending on the size of your allocated block
and its alignment on the page of memory, there may be a gap between
the block and the Red Zone. The overrun or underrun must be large
enough to span the gap and reach the Red Zone, or MemoryScape will
not generate an event. This is a potential issue only if you are using
memalign or posix_memalign. For malloc and calloc, the gap will probably
be one less than the size of the alignment, three or seven bytes. In any
case, the block will still show up as having a corrupted guard block,
because guard blocks are placed immediately before and after your allocated block without any gap.
Your program should initialize memory before it is used, and it should
never use memory that is deallocated. MemoryScape can help you identify these kinds of problems by writing a bit pattern into memory as it is
allocated or deallocated. You can either specify a pattern or use the
default, as follows:
The default allocation pattern is 0xa110ca7f, which was chosen because it resembles the word “allocate”.
The default deallocation pattern is 0xdea110cf, which was chosen
because it resembles the word “deallocate”. In most cases, you want
MemoryScape to paint memory blocks when your program allocates them.
ROGUEWAVE.COM
If your program displays this value, you’ll be able to tell what the problem
is. In some cases, using these values will cause your program to crash.
Because MemoryScape traps this action, you can investigate the cause of
the problem.
You can turn painting on and off without restarting your program. If, for
example, you change the deallocation pattern, you’ll have a better idea
when your program deallocated the block. That is, because MemoryScape is using a different pattern after you change it, you will know if
your program allocated or deallocated the memory block before or after
you made the change.
If you are painting deallocated memory, you could be transforming a
working program into one that no longer works. This is good, as MemoryScape will be telling you about a problem.
Locating Memory Problems
58
Example 1: Finding a Multithreading Problem
Hoarding
You can stop your program’s memory manager from immediately reusing
memory blocks by telling MemoryScape to hoard (that is, retain) blocks.
Because memory blocks aren’t being immediately reused, your program
doesn’t immediately overwrite the data within them. This allows your
program to continue running with the correct information even though it
is accessing memory that should have been deallocated. Because it has
been hoarded, the data within this memory is still correct. If this weren’t
the case, any pointers into this memory block would be dangling. In
some cases, this uncovers other errors, and these errors can help you
track down the problem.
If you are painting and hoarding deallocated memory (and you should
be), you might be able to force an error when your program accesses the
painted memory.
MemoryScape holds on to hoarded blocks for a while before returning
them to the heap manager so that the heap manager can reuse them. As
MemoryScape adds blocks to the hoard, it places them in a first-in, firstout list. When the hoard is full, MemoryScape releases the oldest blocks
back to your program’s memory manager.
To hoard all deallocated memory, set the maximum KB and blocks to
unlimited by entering 0 in the hoarding control fields. To prevent or delay
your program from running out of memory when you use this setting, use
the advanced option to set MemoryScape to automatically release
hoarded memory when available memory gets low.
You can also set a threshold for the hoard size so MemoryScape can warn
you when available memory is getting low. If the hoard size drops below
the threshold, MemoryScape halts execution and notifies you. You can
then view a Heap Status or Leak report to see where your memory is
being allocated.
ROGUEWAVE.COM
When a multithreaded program shares memory, problems can occur if
one thread deallocated a memory block while another thread is still using
it. Because threads execute intermittently, problems are also intermittent. If you hoard memory, the memory will stay viable for longer because
it cannot be reused immediately.
If intermittent program failures stop occurring, you know what kind of
problem exists.
One advantage of this technique is that you can relink your program (as
is described in Chapter 4, “Creating Programs for Memory Debugging,”
on page 119) and then run MemoryScape against a production program
that was not compiled using the -g compiler debugging option. If you see
instances of the hoarded memory, you’ll instantly know problems have
occurred.
This technique often requires that you increase the number of blocks
being hoarded and the hoard size.
Example 2: Finding Dangling Pointer References
Hoarding is most often used to find dangling pointer references. Once
you know the problem is related to a dangling pointer, you need to locate
where your program deallocated the memory. One technique is to use
block tagging (see Task 6: “Using Runtime Events” on page 88). Another
is to use block painting to write a pattern into deallocated memory. If you
also hoard painted memory, the heap manager will not be able to reallocate the memory as quickly.
If the memory was not hoarded, the heap manager could reallocate the
memory block. When it is reallocated, a program can legitimately use the
block, changing the data in the painted memory. If this occurs, the block
is both legitimately allocated and its contents are legitimate in some
context. However, the older context was destroyed. Hoarding delays the
recycling of the block. In this way, it extends the time available for you to
detect that your program is accessing deallocated memory.
Locating Memory Problems
59
Debugging with TotalView
You may find that you want to exert greater control over your process
execution than MemoryScape provides, or you may want to examine variables as you go. To do so, MemoryScape can bring up the TotalView Process Window.
ROGUEWAVE.COM
There are two ways to debug with TotalView:
Select a process and use the pop-up menu options Debug in TotalView or Debug in TotalView in New Window, Figure 31.
Use the icon in the MemoryScape toolbar.
Be aware that opening the TotalView Process Window from within MemoryScape does not initialize TotalView in the same way as starting
TotalView directly. The definitions in your .tvdrc file and your saved breakpoints are not loaded. However, you can load a breakpoint file using the
Action Point menu item in the Process Window. If you need the definitions in your .tvdrc file, start TotalView first and open MemoryScape from
within TotalView.
Locating Memory Problems
60
Figure 31: Memory Debugging Session Menu
ROGUEWAVE.COM
Locating Memory Problems
61
ROGUEWAVE.COM
Locating Memory Problems
62
Chapter 2
Memory Tasks
This chapter describes the tasks that you can perform using MemoryScape.
While each of these tasks can be read separately, you might want to skim
them in the order in which they are presented when you are learning MemoryScape.
Task 1: “Getting Started” on page 64
Task 2: “Adding Parallel Programs” on page 70
Task 3: “Setting MemoryScape Options” on page 72
Task 4: “Controlling Program Execution” on page 81
Task 5: “Seeing Memory Usage” on page 84
Task 6: “Using Runtime Events” on page 88
Task 7: “Graphically Viewing the Heap” on page 92
Task 8: “Obtaining Detailed Heap Information” on page 95
Task 9: “Seeing Leaks” on page 99
Task 10: “Filtering Reports” on page 100
Task 11: “Viewing Corrupted Memory” on page 104
Task 12: “Saving and Restoring Memory State Information” on
page 107
Task 13: “Comparing Memory” on page 109
Task 14: “Saving Memory Information as HTML” on page 112
Task 15: “Hoarding Deallocated Memory” on page 114
Task 16: “Painting Memory” on page 115
ROGUEWAVE.COM
The tasks described in the chapter assume that you are familiar with the
memory debugging concepts presented in Chapter 1, “Locating Memory
Problems”. If you haven’t yet read that chapter, you should read it before
trying to understand or perform any of the tasks described in this chapter.
Memory Tasks
63
Task 1: Getting Started
This task shows you how to start your memory debugging session. It also
presents an overview of the kinds of activities you might perform.
The sections within this task are:
“Starting MemoryScape” on page 64
“Adding Programs and Files to MemoryScape” on page 66
“Attaching to Programs and Adding Core Files” on page 67
“Stopping Before Finishing Execution” on page 68
“Exporting Memory Data” on page 68
“MemoryScape Information” on page 68
“Where to Go Next” on page 69
MemoryScape responds by displaying its Home | Summary screen.
You can now use the run control to start your program. (Figure 34 on
page 66.)
If you program needs command-line options, you can add them by
right-clicking on the program’s name and selecting Properties,
Figure 32.
Figure 32: Properties Dialog Box
Starting MemoryScape
There are five different ways to start debugging memory:
1 Display the MemoryScape window by typing:
memscape
After MemoryScape displays its opening screen, you can begin adding programs and files to your memory debugging session. If you are
running MemoryScape on a Macintosh, you can double-click on the
program icon. Figure 33 on page 65 shows starting MemoryScape
from a shell window and parts of screens you’ll use before you actually start debugging memory.
For additional information, see Adding Programs and Files to MemoryScape.
2 Directly invoke MemoryScape upon a file by typing:
memscape program_name
ROGUEWAVE.COM
Memory Tasks
64
Figure 33: Starting MemoryScape
ROGUEWAVE.COM
Memory Tasks
65
If you change these arguments after program execution starts, restart
your program for the changes to take effect.
3 Directly invoke MemoryScape, adding needed program arguments.
memscape program_name -a arguments
Type all your program’s arguments after the -a. The next time you
invoke MemoryScape on your program, these arguments will automatically be used.
MemoryScape displays its Home | Summary screen. (Figure 34.)
Information on changing these options is discussed in the previous
bullet.
4 Directly invoke MemoryScape, adding needed command-line
options. Here are two skeletons on starting MemoryScape:
memscape [ program_name [ memoryscape_options ] [ -a arguments ] ]
memscape memoryscape_options
MemoryScape options are typed either first or second, depending on
if you are also naming a file. In all cases, arguments to your program
must be the last arguments on the command line.
For more on options, see Chapter 6, “MemoryScape Command-Line
Options,” on page 145.
5 Invoke MemoryScape in batch mode, as follows:
memscript options
For more on batch mode, see Chapter 5, “MemoryScape Scripting,”
on page 139.
Before you begin program execution, you may want to configure MemoryScape for the different kinds of activities that it can perform. For more
information, see Task 3: “Setting MemoryScape Options” on page 72. In
most cases, the default options will meet your needs.
MemoryScape can provide memory information about a process only
when the process is stopped. Therefore, when you ask for a report, MemoryScape stops execution. MemoryScape also stops execution when you
ask for memory usage information. However, it quickly restarts execution
after it collects usage information.
Figure 34: MemoryScape Home Page
Adding Programs and Files to MemoryScape
To add programs, select the link on the Add Programs to Your
MemoryScape Session page. This page is automatically displayed if you
do not name a program when you invoke MemoryScape. In addition, you
can display this screen by selecting Home | Add Program. In general, to
add a program, just enter the information requested on a screen.
Figure 35 shows the screen displayed when you select Add new program.
You will probably use the commands on the Home | Summary screens to
stop and restart execution. The graph here either starts MemoryScape or
adds more programs, Figure 34.
ROGUEWAVE.COM
Memory Tasks
66
Figure 35: Add New Program Screen
you are running MemoryScape, with the exception of those heterogeneous platforms described in “Creating Programs for Memory
Debugging” on page 119. For example, if you are running MemoryScape on a linux-x86 machine, you cannot name a Sun Solaris system.
Any command-line arguments. Arguments that you would use
when invoking your program without MemoryScape. Enter them in
the same way as on the command line.
If you enter or change an argument after your program begins executing, your changes take effect only when you restart your program.
Any new or changed environment variables. Enter them one to a
line in the following format: variable-name=value.
Again, your changes take effect only when you restart your program.
When a program executes upon a remote host, MemoryScape launches a
helper program named tvdsvr on that machine. This small program interacts with your program and MemoryScape. Altogether, you’ll now have
three running programs:
MemoryScape
on your local computer
The program from which you will be obtaining memory information
and which is running on the remote host
tvdsvr, also running on the remote host
Notice the left portion of the screen. If adding a file has more than one
operation, the graphic displays the progression.
You can enter these kinds of information:
The name of your program. Either a relative or absolute path
name. In addition, you can use the Browse button to locate the file.
The name of the computer on which your program will execute. In most cases, you’ll be running your program on the same
machine as you used to invoke MemoryScape.
You can either type the name of the machine on which your program
will execute or select a previously named machine. The machine
entered must have the same architecture as the machine on which
ROGUEWAVE.COM
Attaching to Programs and Adding Core Files
If you wish to attach to a program that is already running or a core file,
click either the Attach to running program or Add core file link on the
Add Programs to Your MemoryScape Session page.
Within the Attach to a Running Program screen, select the processes you
would like to attach to, then click the Next button. Adding a core file is
done in exactly the same way as a regular program except that you need
to name the location of the core file and the executable.
Memory Tasks
67
Exporting Memory Data
MemoryScape requires that all programs use the MemoryScape
agent. In most cases, it does this behind the scenes for you before the
program begins executing. It cannot do this for an already executing
program or for a core file. So, just attaching to an already running
program will not provide the information you need as the agent isn’t
being used with your program. In some cases, you may want to add
it by starting the program using the shell env command. However,
the best alternative is to link the MemoryScape agent. For details,
see “Linking Your Application with the Agent” on page 131.
The information MemoryScape displays is created by analyzing information it stores while your program executes and it reflects the current
state. In many cases, you will also want to compare this current state
against an older state. To do this, you will need to use the Export Memory
Data command found on the left side of many screens to write memory
information to disk. At a later time, you can read this exported data back
into MemoryScape and then either compare it to the current state or
explore its information as if it were the current state.
We recommend that you export information frequently. It is better to
never use this information instead of wishing that you had taken the
time to export it.
Stopping Before Finishing Execution
Immediately before your program finishes executing, MemoryScape halts
the program. This lets you examine memory state information at that
time.
Stopping program execution when the program stops is optional. You
can use a MemoryScape option that lets your program finish executing. If
you do this, however, MemoryScape discards the state information associated with the program. (For information on changing this option, see
Task 3: “Setting MemoryScape Options” on page 72.)
MemoryScape allows you to halt your program’s execution at any time.
However, it does not allow you to select the exact code location for your
program to stop, and the program may stop inside a malloc or new call. If
this happens, you may see an odd corrupt guard block or leak in your
reports. When your process resumes execution, it will clear up the odd
result.
If you require fine program control using breakpoints, or you need thread
control, you will need to use TotalView with MemoryScape. See Debugging with TotalView in the Locating Memory Problems section of this documentation.
ROGUEWAVE.COM
MemoryScape Information
Most of the information you will use is contained within the Memory
Reports tab. Here is an overview of the kinds of reports that you can
receive.
Figure 36: Report Tabs
Leak
Detection. The Backtrace and Source reports in this section
are identical in format to those shown in the Heap Status reports.
They differ in that they only show leaked memory. You can group
these leaks in different ways. One of the most useful is to isolate the
largest leaks and then search for solutions to these problems first.
For information on these reports, see Task 9: “Seeing Leaks” on
page 99.
Memory Tasks
68
These reports, as well as the Heap Status reports, can contain considerable information. You can exclude information from Source and
Backtrace reports by filtering it. See Task 10: “Filtering Reports” on
page 100 for more information.
Heap Status. The reports in this section give you information on all
of your program’s allocations and deallocations. In particular, MemoryScape also groups allocations by the place where the allocation
occurred. This information includes the backtrace—which is your
program’s call stack when the allocation occurred—and the source
line that allocated the memory.
The Backtrace and Source reports present this information in tabular
form. The Heap Status Graphical Report is an easy way to browse
through the program’s allocated blocks. Also, placing your mouse
over a block gives you information about that block. (See Figure 61
on page 93.)
For information on these Heap Status reports, see Task 7: “Graphically Viewing the Heap” on page 92 and Task 8: “Obtaining Detailed
Heap Information” on page 95.
Corrupted Memory. MemoryScape can analyze your program’s
memory blocks to see if the program wrote past a block’s boundaries. If you had set the enable guard blocks option, selecting this report shows corrupted blocks.
For information, see Task 11: “Viewing Corrupted Memory” on
page 104.
Memory Comparisons. MemoryScape lets you save memory state
information and read it back in. After it is read back in, you can compare it against the current memory state. Or, you can read in an another save memory state and compare the states against one another.
ROGUEWAVE.COM
After MemoryScape reads in saved information, you can obtain
reports on the information in exactly the same way as you obtain
reports for an executing program.
For information, see Task 13: “Comparing Memory” on page 109.
Memory Usage. MemoryScape can display charts of how much
memory is being used and how this memory is allocated in sections
of your program. It can do this for one or more of your program’s
processes.
For information, see Task 5: “Seeing Memory Usage” on page 84.
Where to Go Next
Task 3: “Setting MemoryScape Options” on page 72
Describes how to change the MemoryScape default
settings or to add additional capabilities.
Task 4: “Controlling Program Execution” on page 81
Shows how to start, stop, and restart your program
in addition to several other operations.
Display MemoryScape Reports
Most of the tasks that you’ll perform with MemoryScape involve creating reports. The introduction to
this chapter (“Memory Tasks” on page 63) contains a
list of these tasks.
Memory Tasks
69
Task 2: Adding Parallel Programs
Everything discussed in Task 1: “Getting Started” on page 64 also applies
to parallel programs, but additional information is required before you
can collect memory information on programs running in parallel.
First, select Home | Add Program. (This is also the screen displayed if you
do not name a program when starting MemoryScape.) Next, select Add
parallel program to launch the Add New Program dialog, Figure 37.
Figure 37: Add New Program (Parallel) Screen
The information entered here could also be entered directly on a command line, with no difference in the way your program behaves. For
detailed information, see “Setting Up MPI Debugging Sessions” on
page 125.
The information that is unique to parallel programs is as follows:
MPI Type
Select one of the MPI systems in this list.
Tasks
Enter the number of processes that your program
should create. This is equivalent to the -np argument
used by most MPI systems.
Nodes
Some MPI systems let you specify the number of
nodes upon which your tasks will execute. For example, suppose your program will use 16 tasks. If you
specify four nodes, four tasks would execute on each
node.
MPI launcher arguments
If you need to send command-line information to
your MPI system, enter them in this area.
After selecting memory debugging options (the next task) and starting
execution, MemoryScape begins capturing information from each executing task. The sole difference between using MemoryScape on a parallel program versus a non-parallel program is that you have many processes to examine instead of just one. Figure 38 shows the Process
Status and Control area for a 32-process MPI job.
ROGUEWAVE.COM
Memory Tasks
70
Figure 38: Process Status and Control Area
Given this graph, you probably want to start with a look at process 6, as
it is using the most memory. You might also want to use memory comparison features to compare process 6 to process 9, the process using the
least memory.
If possible, run your program a few times, stopping it periodically to get
an idea of how it uses memory so you can identify any patterns. Another
time, you may want to stop the program periodically when you see memory use changing and then export memory data. In this way, you can perform detailed analyses later. This is particularly important in situations
where access to HPC machines is limited.
For remote processes, the only way to reliably configure MemoryScape is to set the TVHEAP_ARGS variable. For information, see
“TVHEAP_ARGS” on page 49.
Where to Go Next
MemoryScape will be collecting data on each of the 32 processes, allowing you to examine memory information for each. Examining each, however, is seldom productive. Instead, you need to focus in on where problems may occur. The Memory Usage charts are often the best place to
start. Figure 39 shows part of a stacked bar chart.
Figure 39: Process Status and Control Area, Stacked Bar Chart
ROGUEWAVE.COM
Task 3: “Setting MemoryScape Options” on page 72
Describes how to change the MemoryScape default
settings or add additional capabilities.
Task 4: “Controlling Program Execution” on page 81
Shows how to start, stop, and restart your program,
in addition to several other operations.
Display MemoryScape Reports
Most of the tasks that you’ll perform with MemoryScape involve creating reports. The introduction to
this chapter (“Memory Tasks” on page 63) contains a
list of these tasks.
Memory Tasks
71
Task 3: Setting MemoryScape
Options
This task discusses options that control MemoryScape activities. MemoryScape default options are probably right for most memory debugging
tasks, but in some cases, you may need additional activities. These are
set using the advanced Memory Debugging Options screen.
Some actions must be set before program execution begins. Others can
be set anytime. Also, while you normally enable and disable activities by
selecting basic options, you can also enable them from the advanced
options page.
Before reading this task, you should be familiar with the following information:
ROGUEWAVE.COM
Chapter 1, “Locating Memory Problems”
Contains an overview of memory concepts and
MemoryScape.
Task 1: “Getting Started” on page 64
Tells you how to start MemoryScape. It also contains
an overview of the kinds of information you can
obtain.
Topics within this task are:
“Basic Options” on page 72
“Advanced Options” on page 74
 “Where to Go Next” on page 80


Basic Options
MemoryScape automatically displays the Memory Debugging Options
screen after you add a program. You can also display it by selecting
Memory Debugging Options on the primary navigation bar, Figure 40 on
page 73.
Memory Tasks
72
Figure 40: Memory Debugging Options
ROGUEWAVE.COM
Memory Tasks
73
These options control the level of debugging activity: Low, Medium, High,
or Extreme.
Low
Records all memory requests, including calls to
malloc(), realloc(), and other calls to your malloc library. It also includes calls to C++ operators such
as new and delete that indirectly use this library. It
can even include memory management functions
performed by some Fortran libraries.
When you ask for a report, MemoryScape analyzes
this recorded information and displays the information you request.
This selection also sets automatic event notification.
In most cases, Low is all you’ll ever need.
Medium
In addition to performing all operations indicated by
Low, MemoryScape writes guard blocks before and
after allocated memory blocks. For more information
on guard blocks and locating corrupted memory, see
Task 11: “Viewing Corrupted Memory” on page 104.
This setting increases the size of the allocated memory block, but the extra overhead is small.
Select Medium only when you need to check for
corrupted memory.
High
In addition to performing all operations indicated by
the Low level, MemoryScape writes a Red Zone after
the allocated memory block and notifies you if you
access memory in this Red Zone. This is called an
overrun.
In this case, the additional allocated memory can result in significant extra overhead.
Select High only if you need to check for memory
overruns. As an alternative, select Low and use the
Red Zones button on the task bar to turn on Red
Zones as needed for suspect allocations.
ROGUEWAVE.COM
To find underruns in your allocated memory, see
“Use Red Zones to find memory access violations”
on page 77.
Extreme
In addition to performing all operations indicated by
the Low, Medium, and High levels, MemoryScape
paints allocated and deallocated memory as well as
hoard memory.
These activities both decrease performance and use
more memory. For information on when to use these
features, see Task 15: “Hoarding Deallocated Memory” on page 114 and Task 16: “Painting Memory” on
page 115.
Select Extreme only if you need hoarding and painting.
Red Zone controls appear on the toolbar only on platforms that support Red Zone capabilities. See the Platform Guide for specific platform support. This applies to the High and Extreme levels only.
For a combination of options unavailable on this screen, see “Advanced
Options” on page 74, which allow you to select options a la carte, as well
as change default settings.
Advanced Options
If you need to fine tune MemoryScape behavior, use the Advanced
Options display on the Memory Debugging Options screen.
Select the Advanced Options button to display advanced options,
Figure 40 on page 73.
The only way to reliably place MemoryScape configuration information into remote processes is to set the TVHEAP_ARGS variable.
For information, see “TVHEAP_ARGS” on page 49.
Use the Basic Options button to return to the original display.
Memory Tasks
74
This screen has six sets of controls. In this figure, all six are selected. The
initial options set here are pre-determined by the Low, Medium, High,
and Extreme selections in the basic screen.
Notice the process controls on the left of this screen. Select one or
more processes to limit the activities being performed.
Activities you can modify, enable, or disable:
“Halt execution at process exit (standalone MemoryScape only)” on
page 75
“Halt execution on memory event or error” on page 75
“Guard allocated memory” on page 77
“Use Red Zones to find memory access violations” on page 77
“Paint memory” on page 79
 “Hoard deallocated memory” on page 79
Halt execution at process exit (standalone
MemoryScape only)
This option is visible only when running MemoryScape standalone without TotalView.
When selected (Figure 41), MemoryScape halts your program’s execution
just before it stops executing. (In most cases, this is immediately before
your program executes its _exit routine.) At this time, you can analyze the
memory data that MemoryScape has collected.
If this option isn’t set, your program executes the _exit routine and MemoryScape discards the data it has collected for that process. This means
that MemoryScape cannot analyze your program’s memory use, so we
recommend that you leave this set.
Figure 41: Halt execution at process exit Options
ROGUEWAVE.COM
Halt execution on memory event or error
When selected, MemoryScape halts your program’s execution just before
it detects that a problem will occur when your program calls a function in
the malloc library. We recommend that you leave this set
Figure 42: Halt execution on memory event or error
When your program allocates memory, MemoryScape records this and
other information in an internal table. Every time your program deallocates or reallocates memory, it checks what is about to be done against
this information. If it detects that a problem will occur, it stops execution
and displays an event indicator, shown inFigure 43.
Figure 43: Event Indicators
MemoryScape can watch for a number of events. Its default is to watch
for all, but you can specify specific events using the Advanced button
which launches the Memory Event Actions Dialog Box, Figure 44.
Memory Tasks
75
Stop
Figure 44: Memory Event Actions Dialog Box
the process and show the event details: When selected, additional options are available to generate a core file or lightweight
memory file.
Generating a core file: MemoryScape writes the file to disk and
aborts execution. (The operating system routines that generate a
core file cause the program to be aborted.) As you are still within
MemoryScape, you can restart your program.
G enerate a lightweight memory file: MemoryScape creates a file
similar to that written when you use the File > Export command.
This files can then be read back into MemoryScape in the same
way as exported .dbg files. In contrast to a core file, your program
continues to execute after MemoryScape writes the file.
You can name the directory into which the MemoryScape writes
the file by identifying the location in the Directory field or use the
Browse button to navigate to a directory.
You can control this file’s name using the Naming Options button
which launches the Memory Data File Options dialog, Figure 45.
Figure 45: Memory Data File Options
This snapshot was created using TotalView Debugger Team and
Team Plus. If you are not licensed for these products, then the two
options Generate a core file and abort the program and
Generate a lightweight memory data file are unavailable.
1 Select events to trigger: Select or unselect events. In most cases,
you should unselect events coming from a library or system you can’t
control.
2 When the above events trigger: Select the action to perform, as
follows:
If you change the prefix or file extension, the change is reflected in the
Preview area.
ROGUEWAVE.COM
Memory Tasks
76
Guard allocated memory
When your program allocates a memory block, MemoryScape can write
additional memory segments both before and after the block. These segments are called guards. Immediately after creating the guards, MemoryScape initializes them to a bit pattern.
These guards can help you identify corrupted memory in two ways:
When your program deallocates a memory block, MemoryScape
checks to determine if the pattern differs from when it first wrote the
block. If so, your program will have overwritten memory that it
shouldn’t have used. This indicates that memory was corrupted.
(MemoryScape writes one pattern into the guard preceding a block
and another into the one after it.)
Whenever you halt execution, you can ask MemoryScape to check
for corrupted guard blocks, which looks at all guard blocks surrounding your allocations.
For information on guard blocks, see Task 11: “Viewing Corrupted Memory” on page 104.
Enable guard blocks by selecting either a level of Medium or selecting the
check box in the Advanced screen. Figure 46 shows the portion of that
screen that controls guard blocks.
to the way an operating system aligns information. If memory is tight,
setting a value here ensures that blocks do not use an excessive amount
of memory.
If the value is set to zero (0), which is the default, MemoryScape does not
set a maximum size.
Use Red Zones to find memory access violations
When your program allocates a memory block, MemoryScape can write
an additional memory buffer either before or after the block. These buffers are called Red Zones. MemoryScape watches the Red Zone for illegal
read or write access.
Red Zone controls appear on the toolbar only on platforms that support Red Zone capabilities. See the Platform Guide for specific platform support.
To enable Red Zones, set the debugging level to High (in the Basic
Options) or select the option “Use Red Zones to find memory access
violations” on the Advanced Options screen, Figure 47.
Figure 47: Advanced Red Zone Option
Figure 46: Guard allocated memory Option
These options control the size of guard blocks and their pattern.
You can also set a maximum size for the guard blocks that surround a
memory allocation. This can be useful because the size actually used for
a guard block can be greater than the pre-guard and post-guard sizes due
ROGUEWAVE.COM
This dialog controls the type of error to detect and defines ranges and
values for some of the detection types. In addition to detecting overruns
and underruns (discussed above), you can customize Red Zone definitions, discussed in “Customizing Red Zones” on page 78.
Red Zones can help identify where an illegal access occurs in these
cases:
Memory Tasks
77
Overruns:
reads or writes past the bounds of the allocated block, detected by placing a Red Zone after the block.
Underruns: reads or writes before the bounds of the allocated block,
detected by placing a Red Zone before the block.
Read / write access after a block is deallocated.
Figure 48: Red Zone Size Ranges
If you select “Detect memory access after it has been freed”, you are notified when this occurs. MemoryScape retains the deallocated blocks to
monitor them for both read and write access. This option will increase
memory consumption in your program.
One way to limit the overhead incurred in using Red Zones is to restrict
their use to blocks of specified sizes. (See “Restricting Red Zones” on
page 78 for details on using the option “Restrict Red Zones to allocations
within size ranges.”) Another way is to turn Red Zones on and off during
program execution using the Red Zones button
,on the toolbar.
Because of the increased memory consumption associated with Red
Zones, use them with caution.
To know when your program exits due to an access violation, use the last
option, “Set the exit value for an access violation.”
Customizing Red Zones
For a detailed description of how Red Zones work, see “Red Zones
Bounds Checking: dheap -red_zones” on page 45.
You can customize Red Zones in several ways using the screen in
Figure 49.
Buffer
Restricting Red Zones
You can restrict Red Zones to apply to blocks of defined sizes. For
instance, if you suspect that your program is overwriting the bounds of a
large array or structure, you can specify a range that includes the size of
the array or structure, Figure 48. (Note that specifying 0 as the upper limit
means the upper bound is unlimited.) For example, if you have an array
that is 1500 bytes, you can define the range to be from 1000 to 2000
bytes, and Red Zones are applied only to allocations within this range.
This limits the additional overhead in memory consumption and targets
your array or structure.
ROGUEWAVE.COM
placement: the Red Zone buffer may be placed before, after,
or both before and after the allocated block. Use caution when adding Red Zones both before and after your allocations, as this doubles the Red Zone overhead.
Buffer size: the default is the target machine page size, but you can
modify this. The number of bytes entered is rounded to the nearest
alignment specified by the machine.
You can elect not to use buffers. This setting detects whether a block
is used after having been freed, with much lower memory consumption.
Allocation alignment according to page start: this setting is useful for
catching underruns.
Memory Tasks
78
Allocation
alignment according to page end: the default alignment
for this setting is determined by the target machine and capped at
the machine’s page size. An alignment of 1 results in a final start address the same as the provisional start address. Other alignment values should be to a power of 2.
value. When your program reads these painted values, it may be able to
detect that there is a problem. In some cases, your program may even
stop executing.
Enable painting either by selecting a level of Extreme in the Basic
Options, or selecting the check box in the Advanced screen. Figure 50
shows painting controls
Figure 49: Custom Red Zone Options
Figure 50: Paint memory Option
These controls let you separately enable allocations and deallocations
(you might want to use one and not the other if memory is tight) and set
the pattern that MemoryScape writes. Notice that the default patterns
resemble the words “allocate” and “deallocate.
For information on painting, see Task 16: “Painting Memory” on
page 115.
Hoard deallocated memory
Paint memory
When your program reads a data value, you are assuming that the program has already set the memory to some value. If your program hasn’t
seen a value or if it tries to read data from the block after you’ve deallocated it, an error has occurred. MemoryScape can help you detect these
problems by setting the value of allocated or deallocated blocks to a
ROGUEWAVE.COM
After a program deallocates memory, it is quite possible that a pointer
still points into the deallocated block. If the program uses that pointer to
access information in this block, this data can be corrupt. Having MemoryScape hold on to deallocated blocks for awhile helps to keep this data
correct. Holding on to deallocated blocks is called hoarding. By retaining
this memory, you reduce program failures. More importantly, because the
program continues to execute, additional and often related memory
errors occur—errors that can help you diagnose the problem.
Enable hoarding either by selecting a level of Extreme in the Basic
Options, or by selecting the check box in the Advanced screen. Figure 51
shows the portion of that screen that controls hoarding.
Memory Tasks
79
Figure 51: Hoard deallocated memory Option
Hoarding deallocated memory may increase the risk of running out of
available memory sooner than expected because deallocated memory is
not released back to the heap manager. Reduce this risk by automatically
releasing the hoarded memory when available memory gets low. You can
also receive an event alerting you when the hoard size drops below the
defined threshold. At that point, you know your program is getting close
to running out of memory.
For more information, see “Hoarding” on page 59 and Task 15: “Hoarding
Deallocated Memory” on page 114.
Where to Go Next
This dialog displays the hoard size and the number of blocks to be
hoarded, which you can customize.
ROGUEWAVE.COM
Now that MemoryScape is set up, you are ready to start your program
executing under MemoryScape control. For more information, see Task 4:
“Controlling Program Execution” on page 81.
Memory Tasks
80
Task 4: Controlling Program
Execution
This task discusses how to control a program’s execution from within
MemoryScape. Once you’ve added programs to MemoryScape, you are
ready to execute your program(s). During execution, MemoryScape collects memory information. For long-running programs, you will want to
start execution, stop it, look at memory information, and then continue
execution.
MemoryScape allows you to halt your program’s execution at any time.
However, it does not allow you to select the exact code location for your
program to stop, and the program may stop inside a malloc or new call. If
this happens, you may see an odd corrupt guard block or leak in your
reports. When your process resumes execution, it will clear up the odd
result.
ROGUEWAVE.COM
If you require fine program control using breakpoints, or you need thread
control, use TotalView with MemoryScape. See “Debugging with
TotalView” on page 60.
Before reading this task, you should be familiar with the following:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape and an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
The controls for starting and stopping program execution are on the
Home | Summary screen as well as the lower left corner of many screens.
Additional controls are in the Manage Process and Files screen, Figure 52
on page 82.
Memory Tasks
81
Figure 52: Execution Controls
ROGUEWAVE.COM
Memory Tasks
82
Topics in this task are:
 “Controlling Program Execution from the Home | Summary Screen”
on page 83
 “Controlling Program Execution from the Manage Processes Screen”
on page 83
 “Controlling Program Execution from a Context Menu” on page 83
 “Where to Go Next” on page 83
Controlling Program Execution from the
Home | Summary Screen
The controls on the Home | Summary screen start and halt execution of
all your processes (Figure 52 on page 82). For additional controls or to
control processes separately, use the Manage Processes | Manage
Processes and Files screen.
MemoryScape cannot generate information while a process is running,
so it automatically halts the program for you. You are later asked if you
want to resume execution.
While your program executes, MemoryScape graphically displays the
memory usage, reflecting a pattern of memory use. If you see that the
graph’s shape is different from one run to another, you may learn when
to halt the program and inspect memory. Or, if memory use grows sharply
and unexpectedly, you may want to stop the program and see why.
ROGUEWAVE.COM
Controlling Program Execution from the
Manage Processes Screen
The controls on the Manage Process and Files screen include the ability
to run, halt, kill, and restart execution. In addition, you can detach a program from MemoryScape, which means remove it from MemoryScape.
You can control which processes this command affects by selecting the
processes from the list on this screen.
Controlling Program Execution from a Context
Menu
When you right-click on a process in the bottom left part of most
screens, MemoryScape displays a context menu that also includes execution controls. These controls operate in the same way as those in
other screens.
Where to Go Next
If
MemoryScape detects a problem while your program is executing,
it can stop execution, letting you know the kind of problem that just
occurred. For more information, see Task 6: “Using Runtime Events”
on page 88.
You can display charts of your memory use. For more information,
see Task 5: “Seeing Memory Usage” on page 84.
After you stop execution, you will want to obtain reports on memory
activity. You will find a list of these tasks in the introduction to this
chapter (“Memory Tasks” on page 63).
Memory Tasks
83
Task 5: Seeing Memory Usage
This task generates charts that visually display memory usage information, along with detailed tables that numerically describe this information.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape and an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
Describes how to configure MemoryScape so that it
performs the activities you want it to perform.
The totals shown in the Memory Usage reports may differ slightly from
those n the Heap Status reports, because heap status is generated from
monitoring program requests for memory (malloc or new) and program
release of memory (free or delete), while memory usage data is obtained
from the operating system facilities. Depending on the operating system,
memory usage totals may include anonymous memory regions that the
program or one of its libraries may have mapped into its address space.
The totals also include a small amount of overhead from MemoryScape
itself.
The Memory Usage report is intended to be a quick check of your program’s memory usage from the system’s perspective. For detailed information on your program’s use of the heap, see the Heap Status reports.
ROGUEWAVE.COM
To display memory usage data, select Memory | Memory Usage. Select
these reports:
High-level process report
Detailed program and library report
Chart Report
Topics in this task are:
“Information Types” on page 84
 “Process and Library Reports” on page 85
 “Chart Report” on page 85
 “Where to Go Next” on page 87

Information Types
While all information can be useful, the data in the heap column is the
most interesting as it contains information that you can control. Memory
Usage reports display the amount of memory:
Text
Your program uses to store your program’s machine
code instructions.
Data
Your program uses to store uninitialized and initialized data.
Heap
Your program is currently using for data created at
runtime.
Stack
Used by the currently executing routine and all the
routines in its backtrace.
If you are looking at a multithreaded process, MemoryScape only shows information for the main
thread’s stack.
The stack size of some threads does not change over
time on some architectures. On some systems, the
space allocated for a thread is considered part of the
heap.
Memory Tasks
84
Stack Virtual Memory
The logical size of the stack. This value is the difference between the current value of the stack pointer
and the value reported in the Stack column. Also,
this value can differ from the size of the virtual memory mapping in which the stack resides.
Total Virtual Memory
The sum of the sizes of the mappings in the process's address space.
Process and Library Reports
The Process report (the bottom snapshot in Figure 53) lists all your processes and information about them. To sort, click on a column header.
Figure 53: Memory Usage Library and Process Reports
In a similar manner, a Detailed program and library report of your memory
usage shows this information for your program and all libraries it uses.
Not shown in this figure are the process controls on the left. By selecting
(or unselecting) processes and threads, you can control which are shown
in these tables.
It can be difficult to know what to do if you identify a problem here. The
only component over which you have direct control is the one you’ve
written. Fortunately, this is usually where the problem is. If, however, the
problem is with a library that your program loaded, you do have options.
If you have control over the library, you can investigate that library’s
behavior. For example, MemoryScape does identify leaks within libraries.
If the problem is one you can’t control, your choices are limited. You
could attempt to obtain a different version of the library. Or, if you can
identify the cause of the problem, write a substitute function.
If, however, the problem is in your code, MemoryScape offers many ways
to drill down and obtain information.
Chart Report
While the information tables in the Process and Library reports are useful,
the best place to start is the Chart report, which offers a graphic look at
your program’s memory data, Figure 54 on page 86.
ROGUEWAVE.COM
Memory Tasks
85
Figure 54: Memory Usage
ROGUEWAVE.COM
Memory Tasks
86
MemoryScape can display your information using a range of charts: Bar,
Stack Bar, Line, and Pie, available from the pulldown list in the Controls
area. In addition, you can zoom in or out to control the view.
The Options area at the top controls which of the six types of memory
information are displayed.
The process area below the charts control which processes and threads
to chart.
ROGUEWAVE.COM
Where to Go Next
MemoryScape
can stop execution when an error occurs or when you
want notification for a block being allocated or reallocated. See Task
6: “Using Runtime Events” on page 88 for more information.
After you stop execution, you will want to obtain reports on memory
activity. You will find a list of these tasks in the introduction to this
chapter (“Memory Tasks” on page 63).
Memory Tasks
87
Error Notifications
Task 6: Using Runtime Events
This section describes how to tell MemoryScape to stop execution either
when an event or an error occurs. Telling you that a problem has
occurred is called notification. Notification requires that the Halt execution
on memory event or error option be enabled, which is the default. (This
option is located on the advanced display of the Memory Debugging
Options screen.
In addition, You can tell MemoryScape to notify you when a block is allocated or deallocated by setting a notification within the Block Properties
window.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
Contains an overview of memory concepts and
MemoryScape.
When your program uses a function from the malloc library, MemoryScape intercepts the call using a process called interposition (see “Behind
the Scenes” on page 6). If the action is an allocation, MemoryScape
records information about it. If your program is deallocating a block,
MemoryScape looks for the block in its table. Based on what it finds, it
can stop execution and notify you that a problem is about to occur. For
example, if the block was previously deallocated, MemoryScape can stop
execution and tell you about the problem.
For information on which events stop execution, see the help or examine
the contents of the dialog box displayed when you click the Advanced
button on the Memory Debugging Options Advanced screen.
Figure 55: Memory Event Notification
Task 1: “Getting Started” on page 64
Tells you how to start MemoryScape. It also contains
an overview of the kinds of information you can
obtain.
Task 3: “Setting MemoryScape Options” on page 72
Describes how to configure MemoryScape so that it
performs the activities you want it to perform.
Topics within this task are:
 “Error Notifications” on page 88
 “Deallocation and Reuse Notifications” on page 90
 “Where to Go Next” on page 91
ROGUEWAVE.COM
Memory Tasks
88
If an event occurs, MemoryScape stops execution and places an event
indicator on the screen, Figure 56.
Figure 57: Process Events Screen
Figure 56: Event Indicator
You can now display the Manage Processes| Process Event screen. MemoryScape will take you directly there if you click on the event link,
Figure 57.
You are now ready to look for detailed information about the notification
event. The top of the window (the text in bold) describes the event.
Immediately below this text are four tabs: Event Location, Allocation
Location, Deallocation Location, and Block Details. The information in the
first three is of the same kind as that shown in Figure 57.
When MemoryScape intercepts a call to the malloc library, it also records
the backtrace associated with the function call (that is, it records the
function’s call stack). Depending on the event, one or more of these four
tabs will have data. For example, if you try to free stack memory, the only
location that MemoryScape knows about is the place where the event
occurred.
To assist you in locating a problem, MemoryScape saves some of the
code surrounding the line in your program that caused the event.
ROGUEWAVE.COM
Memory Tasks
89
The Block Details tab presents information about this event in a different
form. This tab is very useful for obtaining additional information about
the block, Figure 58.
Figure 59: Block Notifications
Figure 58: Block Details Tab
Deallocation and Reuse Notifications
You can configure MemoryScape to notify you when an already allocated
block is deallocated or reallocated, like this:
1 Start, then stop execution.
2 Display the Memory Reports | Heap Status | Heap Status Graphical
Report screen.
3 Locate the block you want to be notified about and right-click on it.
4 In the pop-up, select Properties, Figure 59.
5 Select one or both of the Notify when deallocated and Notify when
reallocated check boxes at the bottom of the window.
If an event occurs while the program is executing (see Task 4: “Controlling
Program Execution” on page 81), MemoryScape stops execution and displays its indicator symbol.
You can now display the Manage Processes| Process Event screen
(Figure 57 on page 89). This is described in the previous section of this
task.
ROGUEWAVE.COM
Memory Tasks
90
Where to Go Next
To
visually display information about your memory use, see Task 7:
“Graphically Viewing the Heap” on page 92.
ROGUEWAVE.COM
After
you stop execution, you will want to obtain reports on memory
activity. You will find a list of these tasks in the introduction to this
chapter (“Memory Tasks” on page 63).
Memory Tasks
91
“Bottom
“Where
Tabbed Areas” on page 94
to Go Next” on page 94
Task 7: Graphically Viewing the Heap
Window Sections
This task is the first of a set of tasks that explain how to explore and
examine your program’s memory. Other important tasks for examining
memory are Task 9: “Seeing Leaks” on page 99 and Task 11: “Viewing Corrupted Memory” on page 104.
Before reading this task, you should be familiar with:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and
MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape and an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
Describes how to configure MemoryScape so that it
performs the activities you want it to perform.
The Heap Status Graphical Report screen has three sections. The top has
controls for viewing and filtering the graph. The middle contains a set of
blocks that represent your memory allocations, and the bottom section
provides information about blocks that you select in the middle. This
bottom section can contain either heap information or a Backtrace
report. (For information on Backtrace reports, see Task 8: “Obtaining
Detailed Heap Information” on page 95.)
The grid is this screen’s most prominent feature. As most programs use
more memory than can easily be displayed, you can use the zoom controls (identified by the magnifying glass in the top area) to either zoom
out to see more information or zoom in to get a better view.
Figure 60: Zoom and Search Controls
Task 4: “Controlling Program Execution” on page 81
Shows how to start and stop program execution
under MemoryScape control.
To display a grid showing how your program is using the heap, select
Memory Reports | Heap Status, and then click Heap Status Graphical
Report. (See Figure 61 on page 93.)
If your program has more than one process or thread, you should select
the thread or process of interest in the Current Processes area on the left
side of the screen.
Topics in this task are:
“Window Sections” on page 92
“Block Information” on page 93
ROGUEWAVE.COM
You can also use the search controls to move from memory block to
memory block using the curved arrow buttons in the control area. The
search button tells MemoryScape what kind of block to look for. There
are four choices, shown in Figure 60.
By default, leaks are not marked. If, however, you select the Detect Leaks
check box, MemoryScape takes a moment to analyze the heap. It then
displays leaked memory blocks in red, Figure 61.
Memory Tasks
92
Figure 61: Heap Status Graphical Report Screen
If you select the Enable Filtering check box, MemoryScape applies filters
to the display. Unlike other reports where filtered information is removed,
this information is displayed in gray. For information on filtering, see Task
10: “Filtering Reports” on page 100.
ROGUEWAVE.COM
Block Information
If you place the cursor over a block, MemoryScape opens a pop-up containing information about the block, Figure 61. The information in this
window is, of course, specific to the block. For example, this pop-up
shows that guard blocks were being used when the block was allocated.
When you select a block, MemoryScape highlights all other blocks that
have the same backtrace. So, if 100 different blocks share the same
backtrace—which means that the execution path within the program is
Memory Tasks
93
the same, and they were allocated from the same place in your program—they’ll be highlighted. (Full details can be found in Task 8:
“Obtaining Detailed Heap Information” on page 95.)
Bottom Tabbed Areas
The left most block within the Heap Information tab at the bottom of the
screen summarizes of the type of information that can be displayed as
well as explains the color coding used for these blocks, Figure 62.
Figure 62: Heap Status Graphical Reports: Tabbed Area
ROGUEWAVE.COM
When you select a block, MemoryScape places information in the center
and right boxes within the Heap Information tab. This information in the
center list is the same as in the pop-up displayed when you place the
mouse over a block. The information on the right is summary information
about related blocks.
The Memory Content tab displays the bytes stored in memory. For more
information, see “Viewing Memory Contents” on page 106.
Where to Go Next
the Heap Status Graphical Report is a starting point for
viewing other reports. For a list of reports, see to the introduction of
this chapter, Chapter 2, “Memory Tasks”.
If you want to continue execution, use the execution controls described in Task 4: “Controlling Program Execution” on page 81.
You may want to set notifications that tell you when a block is deallocated or reused. For more information, see “Deallocation and Reuse Notifications” on page 90.
Typically,
Memory Tasks
94
Task 8: Obtaining Detailed Heap
Information
This task discusses the Source and Backtrace reports, Figure 63.
Figure 63: Heap Status Source and Backtrace Reports
ROGUEWAVE.COM
Memory Tasks
95
These reports are the most important sources of information within
MemoryScape. While these reports relate directly to the Heap Status
reports, they are available throughout MemoryScape as separate reports
or as areas within a report.
The totals shown in the Heap Status reports may differ slightly from
those n the Memory Usage reports, because heap status is generated
from monitoring program requests for memory (malloc or new) and program release of memory (free or delete), while memory usage data is
obtained from the operating system facilities. Depending on the operating system, memory usage totals may include anonymous memory
regions that the program or one of its libraries may have mapped into its
address space. The totals also include a small amount of overhead from
MemoryScape itself.
The Memory Usage report is intended to be a quick check of your program’s memory usage from the system’s perspective. For detailed information on your program’s use of the heap, use the Heap Status reports.
Which report to use, or when to use it, depends on how you want to
approach the data. In general, most users prefer to approach this kind of
information through Source reports. However, some like to see memory
information organized on the way the program creates blocks.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape and a summary of the
kinds of information you can obtain.
Task 4: “Controlling Program Execution” on page 81
How to start and stop program execution.
Task 7: “Graphically Viewing the Heap” on page 92
How to obtain a graphic overview of the way this
heap is laid out, as well as how to get more detailed
information about individual blocks.
ROGUEWAVE.COM
Topics in this task are:
“Heap Status Source Report” on page 96
“Heap Status Source Backtrace Report” on page 98
“Where to Go Next” on page 98
Heap Status Source Report
The Source report (the top screen in Figure 63 on page 95) contains three
scrolling areas as well as a top control area. The area Data Source specifies the information to display: allocations, deallocations, or the hoard.
In most cases, you’ll want to see allocations. You cannot combine these
kinds of information into one report.
By default, MemoryScape does not show leaks. To see them, select the
Detect Leaks check box. If you have created a filter, apply it to the display
by using the Enable Filtering check box. (For information on filtering, see
Task 10: “Filtering Reports” on page 100.)
The top area organizes information by your program’s source files. The
Bytes column contains the amount of memory associated with a line in
each file. Sorting on the Bytes column while displaying leaks helps to
focus on those that waste the most memory; why focus on a leak that is
under 1K when there’s a 10M leak?
By repeatedly clicking, you’ll soon get to the line in your program from
which memory was allocated. The information here shows each block
allocated from this line and the backtrace ID associated with it.
There is a distinction between backtraces associated with the statement
and the statement in your program that allocates memory. Suppose you
have a function called create_list(). This function could be called from
many different places in your code, and each location will have a separate backtrace. For example, if create_list() is called from eight different
places and each was called five times, there would be eight different
backtraces (and eight different backtrace IDs) associated with it. Each
individual backtrace would have five items associated with it.
Memory Tasks
96
As you click on lines in the top portion, the bottom right area shows lines
from your source code. The line mentioned in the top area is highlighted
here, Figure 64.
Figure 64: Uncovering Information
When you need to see the backtrace, just click on the backtrace ID at the
bottom left. As you select different levels in the stack in the backtrace,
the display in the source area changes.
ROGUEWAVE.COM
Memory Tasks
97
Heap Status Source Backtrace Report
The Backtrace Report (the bottom screen in Figure 63 on page 95) contains similar information, organized by backtraces rather than source
files. The backtrace ID displayed here is just a number that MemoryScape
creates, useful in helping you coordinate information in different screens
and tabs as it doesn’t change from report to report.
Clicking on a line in the top portion of the backtrace displays a source
line.
ROGUEWAVE.COM
Where to Go Next
These
reports can contain too much information, which can be simplified using filters. See Task 10: “Filtering Reports” on page 100 for
more information.
Task 14: “Saving Memory Information as HTML” on page 112 describes one method of saving memory information. Task 12: “Saving
and Restoring Memory State Information” on page 107 describes a
second.
Task 13: “Comparing Memory” on page 109 contains information on
comparing more than one memory state.
Memory Tasks
98
Task 9: Seeing Leaks
The Leak reports are essentially the same as the Heap Status Source and
Heap Status Backtrace reports. Honing in on the information you want is
simpler in these reports as there are fewer controls and less data. For
example, there is no Data Source area. The real difference between a
Heap Status Source report and a Leak Source report is that a Leak Source
report does not show allocations that are not leaked. That is, these two
reports focus only on leaked memory.
As using these Leak reports is identical to using Heap Status reports, see
Task 8: “Obtaining Detailed Heap Information” on page 95.
ROGUEWAVE.COM
Memory Tasks
99
Task 10: Filtering Reports
The amount of information displayed in a Leak Detection or Heap Status
report can be considerable. In addition, this information includes memory blocks allocated within all libraries, shared or otherwise, that your
program uses. In other cases, your program may be allocating memory in
many different ways, and you want to focus on only a few of them. This
task shows you how to use filters to eliminate information from reports.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape with a summary of the
kinds of information you can obtain.
When filtering is enabled, MemoryScape considers each enabled filter
and applies it to the report’s data. Filters can have any number of actions
associated with them. Enable a filter by selecting the check box at the
top of a report.
Topics in this task are:
 “Adding, Deleting, Enabling and Disabling Filters” on page 100
 “Where to Go Next” on page 103
Adding, Deleting, Enabling and Disabling Filters
To begin filtering data, right-click on a routine name or line number in the
top pane of a Leak Detection, Heap Status Source or Backtrace report, or
in a Heap Status Graphical report, and select Filter out this entry from the
context menu.
Figure 65: Filter out this entry Context Menu
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
Task 4: “Controlling Program Execution” on page 81
How to start and stop program execution.
Creating Reports
How to create reports, discussed in the introduction
to this chapter (“Memory Tasks” on page 63).
ROGUEWAVE.COM
This command adds the routine to those that can be filtered. It does not
actually enable filtering; enabling is done by selecting the Enable Filtering
check box in the command area of many screens.
To apply the filter, select Manage Filters, which is in the Operations area
on the left side of the screen, Figure 66.
Memory Tasks
100
Figure 66: Memory Debugging Data Filters Dialog Box
Enable All
Enables (checks) all filters in the list.
Disable All
Disables (unchecks) all filters in the list.
Adding and Editing Filters
Selecting the Add button in the Memory Debugging Data Filters dialog
(Figure 66), launches the Add Filter dialog, Figure 67.) Similarly, clicking
the Edit button launches a nearly identical window.)
Figure 67: Add Filter Dialog Box
The controls in this dialog box:
Enable/Disable
When checked, MemoryScape enables the filter.
Add
Displays the Add Filter dialog box where you define
a filter (discussed later in this section in Adding and
Editing Filters).
Edit
Displays a dialog box where you can change the selected filter’s definition. The displayed Edit Filter dialog box is identical to the Add Filter dialog box.
Remove
Deletes the selected filter.
Up and Down
Moves a filter up or down in the filter list. Filters are
applied in the order in which they appear, so you
should place filters that remove the most entries at
the top of the list. Filtering can be a time-consuming
operation, so the right order can increase performance.
ROGUEWAVE.COM
The controls in this window are:
Filter name
The name of the filter. This name will appear in the
Memory Debugging Data Filters dialog box.
Memory Tasks
101
In Figure 67, notice that one filter is named
“Function Name contains _S_chunk_alloc”. This is
the name created by MemoryScape when you use
the context menu to add a function name. Similarly,
you’ll see a filter named “Line Number = 490”.
Share filter
Creates a shared filter. Shared means that anyone using MemoryScape can use the filter.
Evaluate
Limits which backtraces MemoryScape looks at.
allocation focus entry only
Removes an entry only if the criteria is
valid on an entry that is also the allocation focus.
The allocation focus is the point in the
backtrace where MemoryScape believes
your code called malloc().
This button appears only if you have write permissions for
the MemoryScape lib directory.
Add
Adds a blank line beneath the last criterion in the
list. You can now enter information defining another
criterion for this filter in this new line.
Remove
Deletes the selected criterion. To select a criterion,
select the number to the left of the definition.
Up and Down
Changes the order in which criteria appear in the list.
Criteria are applied in the order in which they appear,
so you should place criteria that remove the most
entries at the top of the list. Filtering can be a timeconsuming operation, so this can increase performance.
Exclude data matching
For more than one criterion, the selected radio button indicates if any or all of the criteria have to be
met.
any of the following
Removes an entry when the entry
matches any of the criteria in the list.
all of the following
For example, if you define a filter condition that says Function Name contains
my_malloc and set this entry to allocation
focus entry only, MemoryScape removes
entries only whose allocation focus contains my_malloc. That is, it removes only
allocations that originated from
my_malloc.
In contrast, if you set this entry to all
backtrace entries, MemoryScape removes all blocks that contain my_malloc
anywhere in their backtrace.
all backtrace entries
Applies filter criteria to all function
names in the backtrace.
Criteria
A filter is made up of criteria. Each criterion specifies
what to eliminate from the list. Each criterion has
three parts: a property, an operator, and a value. For
example, you can look for a Process/Library Name
(the property) that contains (the operator) strdup (the
value).
Removes a memory entry only if it fulfills
all of the criteria.
ROGUEWAVE.COM
Memory Tasks
102
Property
When evaluating an entry, MemoryScape
can look at one of eight properties for
one criterion, Figure 68. Select one of the
items from the pulldown list. These items
are:
Backtrace ID
PC
Class Name
Process/Library Name
Count
Size (bytes)
Function Name
Source File Name
Value
A string or a number that indicates what to compare.
Figure 68: Add Filter Dialog Box
Line Number
Operator
Indicates the relationship the value has to the property, Figure 68. Select one of the items from the pulldown list. If the property is a string, MemoryScape
displays the following list:
contains
not contains
ends with
starts with
equals
not equals
If the item is numeric, it displays the following list:
<=
>=
<
>
=
!=
ROGUEWAVE.COM
Where to Go Next
After creating a filter, you’ll want to use it. You’ll find a list of tasks associated with reports at the beginning of this chapter (“Memory Tasks” on
page 63).
Memory Tasks
103


Task 11: Viewing Corrupted Memory
If your program writes data either immediately before or immediately
after an allocated block, it can alter data that other parts of the program
will use. That is, this error means that these values are not what they are
expected to be. This task shows how MemoryScape can help you with
this problem.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape and a summary of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
Task 10: “Filtering Reports” on page 100
How you can remove information from the report
that you do not need or want to see.
“Examining Corrupted Memory Blocks” on page 104
“Viewing Memory Contents” on page 106
Examining Corrupted Memory Blocks
When your program uses functions in the malloc library, MemoryScape
intercepts them, recording the action you have requested. If you enable
guard blocks—by selecting Medium in the Memory Options screen—the
MemoryScape agent also writes small blocks of information before and
after all blocks that your program allocates. These blocks are called guard
blocks. The guard block preceding the allocated block is initialized to one
value (by default, this value is 0x77777777). The guard block following
the allocated block is initialized to a second value (by default,
0x99999999). Because they are different, MemoryScape can determine
which block was the source of the problem.
If your program writes data into either of the guard blocks, it changes this
pattern. MemoryScape can detect this change in two ways:
When your program deallocates a memory block, MemoryScape
checks the guard block. If your program altered a guard block, MemoryScape stops execution and notifies you about the data corruption. (Task 6: “Using Runtime Events” on page 88.)
You can halt execution (see Task 4: “Controlling Program Execution”
on page 81) and display the Memory Reports | Corrupted Memory
screen. This setting has MemoryScape examine all guard blocks and
check for changes. If any are found, it displays a report similar to
that shown on the right side of Figure 69.
Topics in this task are:
ROGUEWAVE.COM
Memory Tasks
104
Figure 69: Corrupted Memory
The Corrupted Memory report contains two sections: a top section
graphically displaying each corruption, and a bottom section containing
a backtrace and the allocation source line for the allocated block. This is
the same kind of information that is displayed in other reports. For information on these reports, see Task 8: “Obtaining Detailed Heap Information” on page 95.
If you place your cursor over a block, MemoryScape displays additional
information about the block. In addition, if you right-click on a block and
ROGUEWAVE.COM
Memory Tasks
105
in the pop-up display and it may contain additional information. For
more on using the Block Properties window, see Task 6: “Using Runtime
Events” on page 88.
Viewing Memory Contents
The Memory Contents tab directly displays the information in memory.
See Task 11: “Viewing Corrupted Memory” on page 104. This information is
presented in a manner similar to such shell tools as od. Controls in this
tab specify how MemoryScape should display this information. For example, you can choose hexadecimal, octal, and character. (The default is
hexadecimal) You can also change the number of bytes shown. The right
area displays an ASCII representation of this information. The Bytes area
lets you specify how many bytes are contained within each cell.
In this figure, notice that bytes are displayed using the same color as in
the selected block at the top of the figure.
ROGUEWAVE.COM
Orange
indicates a corrupted guard block.
green indicates an allocated data block
Light green indicates an uncorrupted guard block.
Dark
Now look at the data. When MemoryScape created a pre guard block, it
used its default setting, which set bytes to 0x77. However, the eighth
byte in the corrupted guard block has a value of 0x41. All other values are
0x77.
Notice also that the boundary between the data in the corrupted block
and the following block has two guard blocks: the following guard from
one data allocation and the preceding guard of a second.
When the program that generated this program was run, guard block
notification was set. This insured that execution was halted when the
memory block containing the guard block was deallocated. This is a good
starting point for trying to locate the cause of the problem.
Memory Tasks
106
Task 12: Saving and Restoring
Memory State Information
In many cases, obtaining data from an executing program doesn’t give
you the information you need. What you may really need is to examine a
past state or compare memory states over time. This task describes saving state information and bringing it back into MemoryScape so that it
can be examined.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape with an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
Task 13: “Comparing Memory” on page 109
The procedure for comparing two memory states.
Topics in this task are:
 “Procedures for Exporting and Adding Memory Data” on page 107
 “Using Saved State Information” on page 107
 “Where to Go Next” on page 108
Procedures for Exporting and Adding Memory
Data
To save state information:
1 Select Export Memory Data, located on the left side of most reports.
2 Enter a file name into the dialog box.
If you are exporting a multiprocess program, MemoryScape places information for each process in its own file. For example, if the file name you
enter is monte_carlo, MemoryScape appends a process number to each
file so that it writes files named monte_carlo0, monte_carlo1, and so on.
The procedure for adding saved information is similar to adding a program to MemoryScape:
1 From the Home | Add Program screen, select Add Memory debugging
file.
2 Enter the name of the file containing the saved state information.
Using Saved State Information
You can use saved state information in two ways:
In many cases, you’ll begin using saved state information in a
Compare Memory Report.
You can use saved state information in exactly the same way as state
information for the currently executing program. That is, generate
reports from the saved state information in exactly the same way as
you would from an executing program.
MemoryScape saves a great deal of information in the saved state file.
This means that you can compare the saved state information against an
executing program or against other saved and recalled state information.
You can also generate any report that you can generate from live state
information. For example, you can display a Leak Source report based on
the saved state information.
The sole difference between a live program and data from saved stated
information is that MemoryScape displays a disk icon
next to the
file’s name.
ROGUEWAVE.COM
Memory Tasks
107
Where to Go Next
You
can also save reports as HTML. See Task 14: “Saving Memory Information as HTML” on page 112.
For
information on using saved state information in comparisons,
see Task 13: “Comparing Memory” on page 109.
ROGUEWAVE.COM
Memory Tasks
108
Overview
Task 13: Comparing Memory
Previous tasks have shown you how to locate explicit memory problems.
These problems are often the most obvious, even though they can be
difficult to locate. A more difficult task is tracking down problems related
to using too much memory. For these problems, you need to understand
how your program is using memory over time.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape with an overview of the
kinds of information you can obtain.
Task 12: “Saving and Restoring Memory State Information” on
page 107
How to save state information to disk and read it
back into MemoryScape.
Topics in this task are:
 “Overview” on page 109
 “Obtaining a Comparison” on page 109
 “Memory Comparison Report” on page 110
 “Where to Go Next” on page 111
ROGUEWAVE.COM
You would compare memory states after you notice that your program is
using memory in a way that you don’t understand. For example, you are
periodically displaying memory usage charts and you notice something
unusual. Or, you see something unexpected on the Home | Summary
screen’s Heap Usage Monitor.
Figure 70: Heap Usage Monitor
This graph shows that memory increases, then decreases slightly before
remaining steady. This could be what you expect. However, it could be
that you believe that your program should not have acquired so much
memory.
Obtaining a Comparison
To create a comparison:
1 Stop your program while it is executing within the first plateau.
2 Save the memory state.
3 Run your program for a short time. Stop it at a later time.
4 Add the saved state back into MemoryScape by selecting Add
memory debugging file from Home | Add Program. On the next
screen, specify the previously saved state file.
5 Display the Memory Reports | Memory Comparisons screen.
6 Select the two processes being compared. Note that the saved state
has a small disk icon (
) next to it. Figure 71 shows part of the
screen containing controls for selecting the processes. The screen
containing information is also displayed.
Memory Tasks
109
Figure 71: Memory Use Comparisons
Memory Comparison Report
Not unexpectedly, the information displayed in the Memory Comparison
Report closely resembles the information in other reports. The buttons in
the Data Source area control the kind of information being displayed,
which can be allocations, deallocations, leaks, or the hoard.
The comparison area displays the number of bytes allocated in each of
the processes, and the difference between these values. In some cases,
you may want to reverse the order in which MemoryScape compares
ROGUEWAVE.COM
information. That is, MemoryScape compares processes in the order in
which you selected the processes. Change this order by clicking the
Reverse Diff
button.
When you select a line in the table, MemoryScape displays the line in
your program associated with it. Depending on what is being displayed
and your program, these lines can differ. In many cases, however, they’re
identical.
Memory Tasks
110
Where to Go Next
Now that you’ve seen comparisons, you will probably want to obtain
more information on using other MemoryScape reports. You’ll find a
summary at the beginning of this chapter (“Memory Tasks” on page 63).
ROGUEWAVE.COM
Memory Tasks
111
Task 14: Saving Memory Information
as HTML
Figure 72: Saved HTML File
ROGUEWAVE.COM
Memory Tasks
112
Saving memory state and bringing it back into MemoryScape is one way
for you to save memory state information. MemoryScape provides an
alternative. You can save report information as an HTML file. (See
Figure 72 for an example.)
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape with an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
Task 12: “Saving and Restoring Memory State Information” on
page 107
How to save all memory data in a way that allows it
to be brought back into MemoryScape.
Saving Report Information
To save report information:
1 Select Save Report, which is on the left side of most report screens.
2 Type a filename in the displayed dialog box.
There are many advantages and one disadvantage to saving information
as HTML instead of exporting it. The disadvantage is that you need to
decide what reports you want to save. That is, MemoryScape writes a set
of HTML files for each report you want saved; if you don’t save a report,
there’s no method for deriving another report from this saved information.
On the other hand, there are a number of advantages. The most important is that you can view the HTML report outside of MemoryScape in a
browser. Another advantage is that you can share this information with
others no matter where they are located, and these people need not
have a MemoryScape license. One last advantage—and we’re sure you’ll
have others—is that this makes it really easy to compare what you’ve
done over time so that you can evaluate if you’re making progress in
solving memory problems.
Topics in this task are:
 “Saving Report Information” on page 113
ROGUEWAVE.COM
Memory Tasks
113
Task 15: Hoarding Deallocated
Memory
Hoarding is not an often-used feature. Its primary use is to prevent problems in which memory is deallocated by one part of the program but
another part is using this memory, not knowing it is deallocated. For two
examples of how hoarding is used, see “Hoarding” on page 59.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape with an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
Task 4: “Controlling Program Execution” on page 81
How to start and stop program execution.
To enable memory hoarding, select Extreme from the Memory Debugging
Options screen. (described in Task 3: “Setting MemoryScape Options” on
page 72.) If you need to tune how MemoryScape hoards memory, select
Advanced Options. Figure 73 shows the portion of the options page
where you set hoarding options.
ROGUEWAVE.COM
Figure 73: Hoard deallocated memory Option
Hoarding is actually a very simple process. When your program deallocates memory, MemoryScape stashes the deallocation request away. It
also records information on the size of the block that would have been
deallocated. And then it ignores the deallocation request.
Ignoring the deallocation request means that other parts of the program
can continue to access this valid memory instead of using data that may
have incorrect values. Said differently, the program can keep executing
with the correct information a while longer. This improves your chances
of identifying the location of the problem.
MemoryScape doesn’t ignore your program’s deallocations request
indefinitely. By default, MemoryScape hoards 32 requests. Also by
default, it defers only the deallocation of up to 256 KB of memory. You
can, of course, change either of these values by using MemoryScape
options.
To hoard all deallocated memory, set the maximum KB and blocks to
unlimited by entering 0 in the hoarding control fields. To prevent or delay
your program from running out of memory when using this setting, use
the advanced option to set MemoryScape to automatically release
hoarded memory when available memory gets low.
You can also set a threshold for the hoard size so MemoryScape can warn
you when available memory is getting low. If the hoard size drops below
the threshold, MemoryScape halts execution and notifies you. You can
then view a Heap Status or Leak report to see where your memory is
being allocated.
Memory Tasks
114
To enable painting memory, select Extreme from the Memory Debugging
Options screen (described in Task 3: “Setting MemoryScape Options” on
Task 16: Painting Memory
page 72.) If you need to tune how MemoryScape paints memory, select
Advanced Options. Here is the portion of the options screen for setting
painting options:
Your program may be using memory either before it is initialized or after it
is deallocated. MemoryScape can help you identify these kinds of problems by initializing allocated or deallocated memory to a bit pattern. This
is called painting. If you can recognize this bit pattern, you’ll be taking a
large step toward identifying the problem.
Before reading this task, you should be familiar with the following information:
Chapter 1, “Locating Memory Problems,” on page 1
An overview of memory concepts and MemoryScape.
Task 1: “Getting Started” on page 64
How to start MemoryScape with an overview of the
kinds of information you can obtain.
Task 3: “Setting MemoryScape Options” on page 72
How to configure MemoryScape so that it performs
the activities you want it to perform.
Task 4: “Controlling Program Execution” on page 81
How to start and stop program execution.
ROGUEWAVE.COM
Figure 74: Paint memory option
Here are some of the ways in which you use painting:
If you paint memory and your application displays this memory, you
will have proof that you are using uninitialized or deallocated
memory.
Painting memory provides consistency for uninitialized memory in
that you should not experience situations where the program works
for some users and doesn’t for others.
Painting memory will change your program’s behavior if it is not using memory correctly. This may aid in identifying the problem. In addition, it may correct the problem so that the program doesn’t appear
to fail.
Some painting patterns can force an error such as a crash to occur.
(Crashes during debugging sessions are useful, allowing you to identify where problems are occurring.)
After painting memory, your program can look for the pattern in order to check if something was not initialized.
Memory Tasks
115
ROGUEWAVE.COM
Memory Tasks
116
Chapter 3
Remote Access
Using Remote Display
Both MemoryScape and TotalView use the same client, discussed in the
TotalUser User Guide in the chapter “Accessing TotalView Remotely.” No special configuration or use is required when using the client to access MemoryScape.
Using the TotalView Remote Display client, you can start and then view
TotalView and MemoryScape as they execute on another system, so that
they need not be installed on your local machine.
Remote Display is currently bundled into all TotalView releases.
Supported platforms include:
Linux x86 and Linux x86-64
Microsoft Windows 7, Vista, and XP
Apple Mac OS X Intel
No license is needed to run the Client, but TotalView running on any supported operating system must be a licensed version of TotalView 8.6 or
greater.
ROGUEWAVE.COM
Remote Access
117
ROGUEWAVE.COM
Remote Access
118
Chapter 4
Creating Programs for
Memory Debugging
MemoryScape tries to handle the details involved in starting your program, but differences in development and production environments may
require customizations outside MemoryScape defaults.
This chapter contains information you’ll need if our defaults do not meet
your need. Topics in this chapter are:
“Compiling Programs” on page 120
“Linking with the dbfork Library” on page 121
“Ways to Start MemoryScape” on page 123
“Attaching to Programs” on page 124
“Setting Up MPI Debugging Sessions” on page 125
“Linking Your Application with the Agent” on page 131
“Using env to Insert the Agent” on page 134
“Installing tvheap_mr.a on AIX” on page 135
“Using MemoryScape in Selected Environments” on page 136
ROGUEWAVE.COM
Creating Programs for Memory Debugging
119
Compiling Programs
The first step when preparing a program to load into MemoryScape is
adding your compiler’s -g debugging command-line option to generate
symbol table debugging information; for example:
cc -g -o executable source_program
Compiler Option or
Library
What It Does
When to Use It
Debugging symbols option
(usually -g)
Generates debugging infor- Before debugging any
mation in the symbol
program with Memorytable.
Scape.
Optimization option
(usually -O)
Rearranges code to optimize your program’s execution.
After you finish debugging your program.
Some compilers won’t let
you use the -O option and
the -g option at the same
time.
You can also use MemoryScape on programs that you did not compile
using the -g option, or programs for which you do not have source code.
However, MemoryScape may not be able to provide source code information.
The following table presents some general considerations.
Even if your compiler lets
you use the -O option,
don’t use it when debugging your program, since
unexpected results often
occur.
Multiprocess programming
library (usually dbfork)
Uses special versions of
Before debugging a multhe fork() and execve() sys- tiprocess program that
explicitly calls fork() or
tem calls.
In some cases, you need to execve().
use the -lpthread option.
.
For more information
about dbfork, see “Linking
with the dbfork Library” on
page 121.
ROGUEWAVE.COM
Creating Programs for Memory Debugging
120
For example:
Linking with the dbfork Library
If your program uses the fork() and execve() system calls, and you want to
debug the child processes, you need to link programs with the dbfork
library.
While you must link programs that use fork() and execve() with the
dbfork library so that MemoryScape can automatically attach to
them when your program creates them, programs that you attach to
need not be linked with this library.
dbfork on IBM AIX on RS/6000 Systems
Add either the -dbfork or -ldbfork_64 argument to the command that you
use to link your programs. If you are compiling 32-bit code, use the following arguments:
/memscape_install_dir/lib/libdbfork.a \
-bkeepfile:/usr/totalview/rs6000/lib/libdbfork.a
-L/memscape_install_dir/lib \
-ldbfork -bkeepfile:/usr/totalview/rs6000/lib/libdbfork.a
For example:
cc -o program program.c \
-L/usr/totalview/rs6000/lib/ -ldbfork \
-bkeepfile:/usr/totalview/rs6000/lib/libdbfork.a
If you are compiling 64-bit code, use the following arguments:
/memscape_install_dir/lib/libdbfork_64.a
\
-bkeepfile:/usr/totalview/rs6000/lib/libdbfork.a
-L/memscape_install_dir/lib -ldbfork_64 \
-bkeepfile:/usr/totalviewrs6000//lib/libdbfork.a
ROGUEWAVE.COM
cc -o program program.c \
-L/usr/totalview/rs6000/lib -ldbfork \
-bkeepfile:/usr/totalview/rs6000/lib/libdbfork.a
When you use gcc or g++, use the -Wl, -bkeepfile option instead of the bkeepfile option, which will pass the same option to the binder. For
example:
gcc -o program program.c \
-L/usr/totalview/rs6000/lib -ldbfork -Wl, \
-bkeepfile:/usr/totalview/rs6000/lib/libdbfork.a
Linking C++ Programs with dbfork
You cannot use the -bkeepfile binder option with the IBM xlC C++ compiler. The compiler passes all binder options to an additional pass called
munch, which will not handle the -bkeepfile option.
To work around this problem, MemoryScape provides the C++ header
file libdbfork.h. You must include this file somewhere in your C++ program. This forces the components of the dbfork library to be kept in your
executable. The file libdbfork.h is included only with the RS/6000 version
of MemoryScape. This means that if you are creating a program that will
run on more than one platform, lace the include within an #ifdef statement’s range. For example:
#ifdef _AIX
#include “/usr/totalview/include/libdbfork.h”
#endif
int main (int argc, char *argv[])
{
}
In this case, you would not use the -bkeepfile option and would instead
link your program using one of the following options:
/usr/totalview/include/libdbfork.a
-L/usr/totalview/include
-ldbfork
Creating Programs for Memory Debugging
121
dbfork and Linux or Mac OS X
dbfork and SunOS 5 SPARC
Add one of the following arguments or command-line options to the
command that you use to link your programs:
/usr/totalview/platform/lib/libdbfork.a
-L/usr/totalview/platform/lib -ldbfork
or
-L/usr/totalview/platform/lib -ldbfork_64
Add one of the following command line arguments or options to the
command that you use to link your programs:
where platform is one of the following: darwin-x86, linux-x86, linux-x86-64,
linux-ia64, or linux-power.
In general, 32-bit programs use libdbfork.a, and 64-bit programs use
libdbfork_64.a. Of course, if your architecture doesn’t support 32-bit
programs, the option won’t work.
/opt/totalview/sun5/lib/libdbfork.a
-L/opt/totalview/sun5/lib
-ldbfork
For example:
cc -o
program program.c \
-L/opt/totalview/sun5/lib -ldbfork
As an alternative, you can set the LD_LIBRARY_PATH environment variable
and omit the -L option on the command line:
setenv LD_LIBRARY_PATH /opt/totalview/sun5/lib
For example:
cc -o program program.c \
-L/usr/totalview/linux-x86/lib -ldbfork
However, linux-ia64 uses libdbfork for 64-bit programs.
ROGUEWAVE.COM
Creating Programs for Memory Debugging
122
Memory Debugging Options page to turn memory
Ways to Start MemoryScape
MemoryScape can debug programs that run in many different computing
environments and which use many different parallel processing modes
and systems. This section looks at few of the ways you can start MemoryScape.
In most cases, the command for starting MemoryScape looks like this:
memscape [ executable [ corefile ] ] [ options ]
where executable is the name of the executable file and corefile is the name
of the core file that you want to examine.
Your environment may require you to start MemoryScape in another way.
For example, if you are debugging an MPI program, you may need to
invoke MemoryScape on mpirun. For an example, see “Debugging an MPI
Program” on page 124 and several other discussions in this chapter.
The following examples show different ways of starting MemoryScape:
Starting MemoryScape
memscape
Starts MemoryScape without loading a program or
core file. You now select Add new program or Add
parallel program to load a program.
Starting MemoryScape and Naming a program
memscape executable
Starts MemoryScape and loads the executable program.
Starting MemoryScape from TotalView
From TotalView, select the Tools menu item from the
Root Window or the Debug menu item from the Process Window. Select the Open MemoryScape option.At launch, MemoryScape tries to interpret the
state of TotalView and opens to the appropriate
page, most likely the Home page. You can select the
ROGUEWAVE.COM
debugging on or off, but if your program is running,
you must kill it before the settings take effect.
Using core files
memscape executable corefile
Starts MemoryScape and loads the executable program and the corefile core file.
Passing arguments to the program
memscape executable -a args
Starts MemoryScape and passes all the arguments
following the -a option to the executable program.
When you use the -a option, you must enter it as the
last MemoryScape option on the command line.
If you don’t use the -a option and you want to add
arguments after MemoryScape loads your program,
right click on the executable and select Properties.
Debugging a program that runs on another computer
memscape executable -remote hostname_or_address[:port]
Starts MemoryScape on your local host and the TotalView Debugger Server (tvdsvr) on a remote host.
After MemoryScape begins executing, it loads the
program specified by executable for remote debugging. You can specify a host name or a TCP/IP address. If you need to, you can also enter the TCP/IP
port number.
If MemoryScape fails to automatically load a remote
executable, you may need to disable autolaunching for
this connection and manually start the Debugger
Server (tvdsvr). (Autolaunching is the process of automatically launching tvdsvr processes.) You can disable autolaunching by adding the
hostname:portnumber suffix to the name you type in
the Host field of the Add new program or Add
parallel program screens. As always, the portnumber
is the TCP/IP port number on which our server is
communicating with MemoryScape. For more inforCreating Programs for Memory Debugging
123
mation on how to disable autolaunching, see “Starting the TotalView Server Manually” in the TotalView
User Guide.
Debugging an MPI Program
memscape executable
(method 1) In many cases, you start an MPI program in
much the same way as you would any other program,
but you need to set its properties. One way is to select the executable’s name from within MemoryScape, right-click for the context menu, and choose
Properties. In the displayed dialog box, select the
MPI version, in addition to other options.
mpirun -np count -tv executable
(method 2) The MPI mpirun command starts the
MemoryScape pointed to by the TOTALVIEW environment variable. MemoryScape then starts your
program. This program will run using count processes.
Attaching to Programs
If a program you’re testing is using too much memory, you can attach to
it while it is running. You can attach to single and multiprocess programs,
and these programs can be running remotely.
MemoryScape requires that all programs use the MemoryScape
agent. In most cases, it does this behind the scenes before the program begins executing. However, it cannot do this for an already
executing program or for a core file. So, just attaching to an already
running program will not provide the information you need as the
agent won’t be used. In some cases, you may want to add it by
starting the program using the shell env command. However, the
best alternative is to link the MemoryScape agent. For details, see
“Linking Your Application with the Agent” on page 131.
To attach to a process, select the Attach to running program item from
the Home | Add Program page.
When you exit from MemoryScape, it kills all programs and processes that it started. However, programs and processes that were
executing before you brought them under MemoryScape’s control
continue to execute.
If you want MemoryScape to automatically attach to programs that use
fork() and execve(), you must use the MemoryScape dbfork library. However, programs that you manually attach to need not be linked with this
library.
ROGUEWAVE.COM
Creating Programs for Memory Debugging
124
“Debugging
LAM/MPI Applications” on page 129
QSW RMS Applications” on page 129
“Debugging Sun MPI Applications” on page 130
“Debugging
Setting Up MPI Debugging Sessions
Debugging MPI Programs
This section explains how to set up MemoryScape MPI debugging sessions. This section includes:
“Debugging MPI Programs” on page 125
“Debugging MPICH Applications” on page 126
“Debugging IBM MPI Parallel Environment (PE) Applications” on
page 128
In many cases, the way in which you invoke an MPI program within MemoryScape control differs little from discipline to discipline. If you invoke
MemoryScape from the command line without an argument, MemoryScape displays its Add Programs to Your MemoryScape Session screen.
Select Add parallel program, and then enter the required information.
Figure 75: Adding a Parallel program
ROGUEWAVE.COM
Creating Programs for Memory Debugging
125
For example, you should select the Parallel system, the number of Tasks,
and possibly Nodes. If there are additional arguments to send to the
starter process, enter them in the MPI launcher arguments area. Note
that these arguments are those sent to a starter process such as mpirun
or poe; arguments sent to your program are instead entered in the
Command line arguments area. If you need to add environment variables,
enter them within the Envrionment variables tab.
In most cases, MemoryScape remembers your entries between invocations of MemoryScape and pre-populates the relevant fields.
Debugging MPICH Applications
In many cases, you can bypass the procedure described in this section. For more information, see “Debugging MPI Programs” on
page 125.
To examine Message Passing Interface/Chameleon Standard (MPICH)
applications, you must use MPICH version 1.2.5 or later on a homogenous collection of computers. If you need a copy of MPICH, you can
obtain it at no cost from Argonne National Laboratory at http://
www.mcs.anl.gov/mpi. (We strongly urge that you use a later version of
MPICH.)
The MPICH library should use the ch_p4, ch_p4mpd, ch_shmem,
ch_lfshmem, or ch_mpl devices.
For networks of workstations, the default MPICH library is ch_p4.
For shared-memory SMP computers, use ch_shmem.
On an IBM SP computer, use the ch_mpl device.
The MPICH source distribution includes all these devices. Choose the
device that best fits your environment when you configure and build
MPICH.
For more information, see:
Starting MemoryScape on an MPICH Job, below
“Attaching to an MPICH Job” on page 127
“Using MPICH P4 procgroup Files” on page 127
ROGUEWAVE.COM
Starting MemoryScape on an MPICH Job
Before you can bring an MPICH job under MemoryScape’s control, both
MemoryScape and the Debugger Server must be in your path, performed
through either a login or shell startup script.
The official syntax for starting MemoryScape is as follows:
mpirun -tv [ other_mpich-args ] program [ program-args ]
For example:
mpirun -tv -np 4 sendrecv
The -tv option tells mpirun that it should obtain information from the
TOTALVIEW environment variable.
For example, the following is the C shell command that sets the
TOTALVIEW environment variable so that mpirun passes the -verbosity
option to MemoryScape:
setenv TOTALVIEW "memscape -verbosity 1"
In this example, the memscape command must be in your path. If it isn’t,
you need to specify either an absolute or relative path to the memscape
command. MemoryScape begins by starting the first process of your job,
the master process, under its control.
On the IBM SP computer with the ch_mpl device, mpirun uses the poe
command to start an MPI job. While you still must use the MPICH mpirun
(and its -tv option) command to start an MPICH job, the way you start
MPICH differs. For details on using MemoryScape with poe, see “Starting
MemoryScape on a PE Program” on page 129.
Starting MemoryScape using the ch_p4mpd device is similar to starting
MemoryScape using poe on an IBM computer or other methods you
might use on Sun and HP platforms. In general, you start MemoryScape
using the memscape command, with the following syntax;
memscape mpirun [ memscape_args ] -a [ mpich-args ] \
program [ program-args ]
As your program executes, MemoryScape automatically acquires the processes that are part of your parallel job as your program creates them.
MemoryScape automatically copies memory configuration information to
the slave processes.
Creating Programs for Memory Debugging
126
Attaching to an MPICH Job
Using MPICH P4 procgroup Files
You can attach to an MPICH application even if it was not started under
MemoryScape’s control. These processes, however, must have previously
been linked with the MemoryScape agent. See “Linking Your Application
with the Agent” on page 131.
To attach to an MPICH application:
1 Start MemoryScape.
Select Attach to running program from the Add Programs to Your
MemoryScape Session screen. You are now shown processes that are
not yet owned.
2 Attach to the first MPICH process in your workstation cluster by
selecting it, then clicking Next.
3 On an IBM SP with the ch_mpi device, attach to the poe process that
started your job. For details, see “Starting MemoryScape on a PE Program” on page 129.
Normally, the first MPICH process is the highest process with the correct program name in the process list. Other instances of the same
executable can be:
The p4 listener processes if MPICH was configured with ch_p4.
Additional slave processes if MPICH was configured with
ch_shmem or ch_lfshmem.
Additional slave processes if MPICH was configured with ch_p4
and has a file that places multiple processes on the same computer.
4 After you attach to your program’s processes, you are prompted to
also attach to slave MPICH processes. To do so, press Return or
choose Yes. If you choose Yes, MemoryScape starts the server processes and acquires all MPICH processes.
If you’re using MPICH with a P4 procgroup file (by using the -p4pg
option), you must use the same absolute path name in your procgroup file
and on the mpirun command line. For example, if your procgroup file
contains a different path name than that used in the mpirun command,
even though this name resolves to the same executable, MemoryScape
assumes that it is a different executable, which causes debugging problems.
The following example uses the same absolute path name on the MemoryScape command line and in the procgroup file:
In some situations, the processes you expect to see might not exist (for
example, they may crash or exit). MemoryScape acquires all the processes it can and then warns you if it can not attach to some of them. If
you attempt to dive into a process that no longer exists (for example,
using a message queue display), MemoryScape reports hat the process
no longer exists.
ROGUEWAVE.COM
% cat p4group
local 1 /users/smith/mympichexe
bigiron 2 /users/smith/mympichexe
% mpirun -p4pg p4group -tv /users/smith/mympichexe
In this example, MemoryScape does the following:
1 Reads the symbols from mympichexe only once.
2 Places MPICH processes in the same MemoryScape share group.
3 Names the processes mypichexe.0, mympichexe.1, mympichexe.2,
and mympichexe.3.
If MemoryScape assigns names such as mympichexe<mympichexe>.0, a
problem occurred and you need to compare the contents of your
procgroup file and mpirun command line.
Starting MPI Issues
In many cases, you can bypass the procedure described in this section. For more information, see “Debugging MPI Programs” on
page 125.
If you can’t successfully start MemoryScape on MPI programs, check the
following:
Can you successfully start MPICH programs without MemoryScape?
Creating Programs for Memory Debugging
127
The MPICH code contains some useful scripts that help verify that
you can start remote processes on all computers in your computers
file. (See tstmachines in mpich/util.)
Does the TotalView Server (tvdsvr) fail to start?
Remember that MemoryScape uses ssh -x to start the server, and that
this command doesn’t pass your current environment to remotely
started processes.
Under some circumstances, MPICH kills MemoryScape with the
SIGINT signal. You can see this behavior when you use the Kill command as the first step in restarting an MPICH job.
Debugging IBM MPI Parallel Environment (PE)
Applications
In many cases, you can bypass the procedure described in this section. For more information, see “Debugging MPI Programs” on
page 125.
You can debug IBM MPI Parallel Environment (PE) applications on the
IBM RS/6000 and SP platforms.
To take advantage of MemoryScape’s ability to automatically acquire
processes, you must be using release 3.1 or later of the Parallel Environment for AIX.
Topics in this section are:
“Using Switch-Based Communications” on page 128
“Performing a Remote Login” on page 128
“Starting MemoryScape on a PE Program” on page 129
“Attaching to a PE Job” on page 129
The following sections describe what you must do before MemoryScape
can debug a PE application.
You must link the MemoryScape agent into your IBM MPI Parallel
Environment program before running it. For details, see “Installing
tvheap_mr.a on AIX” on page 135.
ROGUEWAVE.COM
Using Switch-Based Communications
If you’re using switch-based communications (either IP over the switch or
user space) on an SP computer, you must configure your PE debugging session so that MemoryScape can use IP over the switch for communicating
with the TotalView Server (tvdsvr). Do this by setting the -adapter_use
option to shared and the -cpu_use option to multiple, as follows:
If you’re using a PE host file, add shared multiple after all host names
or pool IDs in the host file.
Always use the following arguments on the poe command line:
-adapter_use shared -cpu_use multiple
If you don’t want to set these arguments on the poe command line, set
the following environment variables before starting poe:
setenv MP_ADAPTER_USE shared
setenv MP_CPU_USE multiple
When using IP over the switch, the default is usually shared adapter use and
multiple cpu use; we recommend that you set them explicitly using one of
these techniques. You must run MemoryScape on an SP or SP2 node.
Since MemoryScape will be using IP over the switch in this case, you cannot
run MemoryScape on an RS/6000 workstation.
Performing a Remote Login
You must be able to perform a remote login using the ssh -x command.
You also need to enable remote logins by adding the host name of the
remote node to the /etc/hosts.equiv file or to your .rhosts file.
When the program is using switch-based communications, MemoryScape
tries to start the TotalView Server by using the ssh -x command with the
switch host name of the node.
Setting Timeouts
If you receive communications timeouts, you can set the value of the
MP_TIMEOUT environment variable; for example:
setenv MP_TIMEOUT 1200
If this variable isn’t set, the default timeout value is 600 seconds.
Creating Programs for Memory Debugging
128
Starting MemoryScape on a PE Program
The following is the syntax for running Parallel Environment (PE) programs from the command line:
program [ arguments ] [ pe_arguments ]
You can also use the poe command to run programs as follows:
poe program [ arguments ] [ pe_arguments ]
If, however, you start MemoryScape on a PE application, you must start
poe as MemoryScape’s target using the following syntax:
memscape poe -a program [ arguments ] [ PE_arguments ]
For example:
memscape poe -a sendrecv 500 -rmpool 1
Attaching from a Node Not Running poe
The procedure for attaching MemoryScape to poe from a node that is not
running poe is essentially the same as the procedure for attaching from a
node that is running poe.
To place poe in this list:
1 Connect MemoryScape to the startup node.
2 From the Home | Add Programs to Your MemoryScape Session page,
select Attach to running program.
3 Look for the process named poe and continue as if attaching from a
node that is running poe.
Debugging LAM/MPI Applications
You should start all of your parallel tasks using the Run command.
Attaching to a PE Job
To take full advantage of MemoryScape’s poe-specific automation, you
need to attach to poe itself, and let MemoryScape automatically acquire
the poe processes on all its nodes. In this way, MemoryScape acquires
the processes you want to debug.
Attaching from a Node Running poe
To attach MemoryScape to poe from the node running poe:
1 Start MemoryScape in the directory of the debug target.
If you can’t start MemoryScape in the debug target directory, you can
start MemoryScape by editing the Debugger Server (tvdsvr) command
line before attaching to poe.
2 In the Home | Add Program screen, select Attach to running program,
then find the poe process list, select it, and hit the Next button. When
necessary, MemoryScape launches tvdsvr processes.
3 Locate the process you want to debug and dive on it.
If your source code files are not displayed in the Source Pane, you might
not have told MemoryScape where these files reside. You can fix this by
invoking the File > Search Path command to add directories to your
search path.
ROGUEWAVE.COM
In many cases, you can bypass the procedure described in this section. For more information, see “Debugging MPI Programs” on
page 125.
You debug a LAM/MPI program in a similar way to how you debug most
MPI programs. Use the following syntax if MemoryScape is in your path:
mpirun -tv mpirun args prog prog_args
As an alternative, you can invoke MemoryScape on mpirun:
memscape mpirun -a prog prog_args
Debugging QSW RMS Applications
In many cases, you can bypass the procedure described in this section. For more information, see “Debugging MPI Programs” on
page 125.
MemoryScape supports automatic process acquisition on AlphaServer
SC systems and 32-bit Red Hat Linux systems that use Quadrics RMS
resource management system with the QSW switch technology.
Creating Programs for Memory Debugging
129
Starting MemoryScape on an RMS Job
To start a parallel job under MemoryScape’s control, use MemoryScape
as if you were debugging prun:
memscape prun -a prun-command-line
MemoryScape starts and shows you the machine code for RMS prun.
Since you’re not usually interested in debugging this code, use the Run
command to let the program run.
The RMS prun command executes and starts all MPI processes.
Attaching to an RMS Job
To attach to a running RMS job, attach to the RMS prun process that
started the job.
You attach to the prun process the same way you attach to other processes.
Debugging Sun MPI Applications
In many cases, you can bypass the procedure described in this section. For more information, see “Debugging MPI Programs” on
page 125.
MemoryScape can debug a Sun MPI program and display Sun MPI message queues. This section describes how to perform job startup and job
attach operations.
ROGUEWAVE.COM
To start a Sun MPI application, use the following command:
memscape mprun [ totalview_args ] -a [ mpi_args ]
For example:
memscape mprun -g blue -a -np 4 /usr/bin/mpi/conn.x
When the MemoryScape Window appears, select the Go button.
Attaching to a Sun MPI Job
To attach to an already running mprun job:
1 Find the host name and process identifier (PID) of the mprun job by
typing mpps -b. For more information, see the mpps(1M) manual
page.
The following is sample output from this command:
JOBNAME
cre.99
cre.100
MPRUN_PID
12345
12601
MPRUN_HOST
hpc-u2-9
hpc-u2-8
2 Go to Attach to Running Program and look for the process.
3 If MemoryScape is running on a different node than the mprun job,
enter the host name in the Remote Host field.
You must link the MemoryScape agent into your Sun MPI Parallel
Environment program before running it. For details, see “Linking
Your Application with the Agent” on page 131.
Creating Programs for Memory Debugging
130
Linking Your Application with
the Agent
MemoryScape puts its heap agent between your program and its heap
library which allows the agent to intercept the calls that your program
makes to this library. After it intercepts the call, it checks the call for
errors and then sends it on to the library so that it can be processed. The
MemoryScape agent does not replace standard memory functions; it just
monitors what they do. For more information, see “Behind the Scenes”
on page 6.
In most cases, MemoryScape arranges for the heap agent to be loaded
automatically when it starts your program. In some cases, however, special steps must be taken to ensure the agent loads. One example is when
you are starting an MPI program using a launcher that does not propagate environment variables. (If you start your MPI program in MemoryScape using the Add Parallel Program page, MemoryScape propagates
the information for you.) Another is when you want to start your program
outside, or independently of, TotalView, and want to attach to the program later after it has started.
There are two ways you can arrange for the heap agent to be loaded:
Link the application with the agent, as described in this section.
Request that the heap agent be preloaded by setting the runtime
loader's preloading environment variable. See “Using env to Insert
the Agent” on page 134.
Here is some important platform-specific information:
On AIX, the malloc replacement code and heap agent application
must be in directories searched by the dynamic loader. If they are
not in any of the standard directories (you can check with your system administrator), you can set LIBPATH to search these directories
when you run the program. Another option is to add the directories
to the program's list of search directories when you link the pro-
ROGUEWAVE.COM
gram. To do this, use the -L option as described in the table below. If
you are in doubt about the directories being searched, you can obtain a list of the searched directories with dump -Hv <programname>.
For additional requirements with AIX, see “Installing tvheap_mr.a on
AIX” on page 135.
On Cray, TotalView supports both static and dynamic linking. See
the table below for the link lines you need to use.
On Blue Gene/L, a special heap agent must be used. This needs to
be statically linked with your program, as shown in the table below.
Blue Gene/P supports static and dynamic linking. If your program is
dynamically linked and you start your job under TotalView using a
launching program such as mpirun or runjob that honors the MPIRUN_ENV environment variable, you don't need to take any special
steps to prepare your application for memory debugging. In this
case, TotalView arranges for the heap agent to be loaded with your
program.
If, however, you are starting the job outside TotalView, such as when
you intend to attach to the job later, or you are using a launching program that does not honor MPIRUN_ENV, you must arrange for the heap
agent to be loaded when the program runs. This can be done in one
of two ways:
Link your application with the heap agent. The link options for
doing so are shown in the table below.
Set the LD_PRELOAD environment variable in your program's environment to path/libtvheap.so. Note that path refers to the file
system in which the program executes, not the one in which the
launching program runs. If you are using mpirun you can use the
-env option, or set MPIRUN_ENV to pass the environment variable
setting. See the manual page for mpirun on your system.
There is also a version of the heap agent available for statically linked
programs. The link options you should use when linking your program
are also shown in the table below. Both statically and dynamically
linked versions of the heap agent are thread-safe and can be used
with multi-threaded programs.
Creating Programs for Memory Debugging
131
Blue
Gene/Q supports static or dynamic linking. In either case, you
must link your application with the heap agent as described in the
table below, or, if your application is dynamically linked, arrange for
it to be preloaded. Note also that memory debugging and event notification should be enabled on the starter program.
As with Blue Gene/P, if your program is dynamically linked you can
avoid having to link the heap agent with your program if you set the
LD_PRELOAD variable in your program's environment. If you are using
runjob to launch your program, you can use its --envs option to
pass this environment variable setting. If you are using srun, you will
Platform
Compiler
need to add the runjob --envs option to srun's --runjob-opts
option; for example, --runjob-opts="--envs LD_PRELOAD=...".
However you arrange for the environment variable to be passed,
LD_PRELOAD should be set to path/libtvheap_64.so. Both statically
and dynamically linked versions of the heap agent are thread-safe
and can be used with multi-threaded programs.
On Apple Mac OSX, you cannot link the agent into your program.
The following table lists additional command-line linker options that you
must use when you link your program:
Binary Interface Additional linker options
Cray XT, XE, XK CLE (dynamic) -
64
-L<path> -ltvheap_cnl -Wl,-rpath,<path>
Cray XT, XE, XK CLE (static)
-
64
-L<path> -ltvheap_cnl
Cray XT3 Catamount
-
64
-L<path> -lgmalloc -ltvheap_xt3
IBM Blue Gene/L (static)
-
32
-L<path> -ltvheap_bluegene
IBM Blue Gene/P (dynamic)
-
32
-L<path> -ltvheap -Wl,-rpath,<path>
IBM Blue Gene/P (static)
-
32
-L<path> -ltvheap_bluegene_p
IBM Blue Gene/Q (dynamic)
IBM/GCC
64
-L<path> -ltvheap_64 -Wl,-rpath,<path>
IBM Blue Gene/Q (static)
IBM/GCC
64
-L<path> -Wl,@<path>/tvheap_bgqs.ld
IBM RS/6000 (all)
IBM/GCC
32/64
-L<path_mr> -L<path>
AIX 5
IBM/GCC
32
-L<path_mr> -L<path> <path>/aix_malloctype.o
64
-L<path_mr> -L<path> <path>/aix_malloctype64_5.o
Linux x86
GCC/Intel/PGI
32
-L<path> -ltvheap -Wl,-rpath,<path>
Linux x86-64
GCC/Intel/PGI
32
-L<path> -ltvheap -Wl,-rpath,<path>
64
-L<path> -ltvheap_64 -Wl,-rpath,<path>
Linux IA64
GCC/Intel
64
-L<path> -ltvheap -Wl,-rpath,<path>
Linux Power
GCC/Intel/PGI
32
-L<path> -ltvheap -Wl,-rpath,<path>
64
-L<path> -ltvheap_64 -Wl,-rpath,<path>
ROGUEWAVE.COM
Creating Programs for Memory Debugging
132
Platform
Compiler
Binary Interface Additional linker options
Sun
Sun/Apogee
32
-L<path> -ltvheap -R <path>
Sun
64
-L<path> -ltvheap_64 -R <path>
GCC
32
-L<path> -ltvheap -Wl,-R,<path>
64
-L<path> -ltvheap_64 -Wl,-R,<path>
The following list describes the options in this table:
<path>
The absolute path to the agent in the MemoryScape installation hierarchy. More precisely, this directory is:
<path_mr>
The absolute path of the malloc replacement library.
This value is determined by the person who installs
the MemoryScape malloc replacement library.
<installdir>/toolworks/memoryscape.<version>/
<platform>/lib
<installdir>
The installation base directory name.
<version>
The MemoryScape version number.
The heap agent library path can be hard to determine. If you have
access to the command line interface (CLI), you can use the following command to print out its path:
<platform>
The platform tag.
puts $TV::hia_local_dir
ROGUEWAVE.COM
Creating Programs for Memory Debugging
133
Using env to Insert the Agent
When MemoryScape attaches to a process that is already running, the
agent must already be associated with it. You can do this in two ways:
Manually link the agent as described in previous sections.
Start the program using env (see man env on your system). This
pushes the agent into your program.
Platform
Variable
Apple Mac OS X
DYLD_INSERT_LIBRARIES=<hia_dir>/libtvheap.dylib
IBM AIX
MALLOCTYPE=user:tvheap_mr.a
If you are already using MALLOCTYPE for another purpose, reassign its value to the variable TVHEAP_MALLOCTYPE and assign MALLOCTYPE as above; when the
agent starts it will correctly pass on the options.
Linux and HP-UX
32-bit
LD_PRELOAD=<hia_dir>/libtvheap.so
64-bit
LD_PRELOAD=<hia_dir>/libtvheap_64.so
Sun
Preloading cannot be used with Cray or Blue Gene/L platforms.For
information on preloading with Blue Gene/P and Blue Gene/Q, see
the earlier section Linking Your Application with the Agent.
The variables required by each platform are shown in the following table.
The placeholder <hia_dir> represents the directory in which the agent is
found. See the previous section for how to determine this location.
ROGUEWAVE.COM
32-bit generic
LD_PRELOAD=<hia_dir>/libtvheap.so
32-bit specific
LD_PRELOAD_32=<hia_dir>/libtvheap.so
64-bit generic
LD_PRELOAD=<hia_dir>/libtvheap_64.so
64-bit specific
LD_PRELOAD_64=<hia_dir>/libtvheap_64.so
If the agent is the only library you are preloading,
use the generic variable. Otherwise, use whichever
variable was used for the other preloaded libraries.
Creating Programs for Memory Debugging
134
LIBPATH and Linking
Installing tvheap_mr.a on AIX
Installing tvheap_mr.a on AIX requires that the system have the
bos.adt.syscalls System Calls Application Toolkit page installed.
You must install the tvheap_mr.a library on each node on which you plan
to run the MemoryScape agent. The aix_install_ tvheap_mr.sh script
contains most of the required setup, and is located in this directory:
toolworks/totalview.version/rs6000/lib/
For example, after you become root, enter the following commands:
cd toolworks/memscape.1.0.0-0/rs6000/lib
mkdir /usr/local/tvheap_mr \
./aix_install_tvheap_mr.sh ./tvheap_mr.tar \
/usr/local/tvheap_mr
Use poe to create tvheap_mr.a on multiple nodes.
The pathname for the tvheap_mr.a library must be the same on each
node. This means that you cannot install this library on a shared file system. Instead, you must install it on a file system that is private to the
node. For example, because /usr/local is usually accessible only from the
node on which it is installed, you might want to install it there.
The tvheap_mr.a library depends heavily on the exact version of
libc.a that is installed on a node. If libc.a changes, you must recreate
tvheap_mr.a by re-executing the aix_install_tvheap_mr.sh script.
This section discusses compiling and linking your AIX programs. The following command adds path_mr and path to your program’s libpath:
xlc -Lpath_mr -Lpath -o a.out foo.o
When malloc() dynamically loads tvheap_mr.a, it should find the library in
path_mr. When tvheap_mr.a dynamically loads tvheap.a, it should find it in
path.
The AIX linker supports relinking executables. This means that you can
make an already complete application ready for the MemoryScape agent;
for example:
cc a.out -Lpath_mr -Lpath -o a.out.new
Here's an example that does not link in the heap replacement library.
Instead, it allows you to dynamically set MALLOCTYPE:
xlC -q32 -g \
-L/usr/local/tvheap_mr \
-L/home/memscape/interposition/lib prog.o -o prog
This next example shows how a program can be set up to access the
MemoryScape agent by linking in the aix_malloctype.o module:
xlc -q32 -g \
-L/usr/local/tvheap_mr \
-L/home/memscape/interposition/lib prog.o \
/home/memscape/interposition/lib/aix_malloctype.o \
-o prog
You can check that the paths made it into the executable by running the
dump command; for example:
% dump -Xany -Hv tx_memdebug_hello
tx_memdebug_hello:
If this malloc replacement library changes (which is infrequent) you’ll
need to rerun this procedure. Any change will be noted among a
release’s new features.
ROGUEWAVE.COM
***Loader Section***
Loader Header Information
VERSION#
#SYMtableENT
#RELOCent
0x00000001 0x0000001f
0x00000040
LENidSTR
0x000000d3
#IMPfilID
OFFstrTBL
OFFidSTR
LENstrTBL
Creating Programs for Memory Debugging
135
0x00000005
INDEX
0
1
2
3
4
0x00000608
0x00000080
0x000006db
***Import File Strings***
PATH
BASE
MEMBER
/.../lib:/usr/.../lib:/usr/lib:/lib
libc.a
shr.o
libC.a
shr.o
libpthreads.a
shr_comm.o
libpthreads.a
shr_xpg5.o
Index 0 in the Import File Strings section shows the search path the runtime loader uses when it dynamically loads a library. Some systems propagate the preload library environment to the processes they will run; others, do not. If they do not, you need to manually link them with the
tvheap library.
In some circumstances, you might want to link your program instead of
setting the MALLOCTYPE environment variable. If you set the
MALLOCTYPE environment variable for your program and it uses fork()/
exec() a program that is not linked with the agent, your program will terminate because it fails to find malloc().
Using MemoryScape in Selected
Environments
This topic describes using the Memory Debugger within various environments. The sections within this topic are:
MPICH
IBM PE
RMS MPI
ROGUEWAVE.COM
MPICH
Here's how to use MemoryScape with MPICH MPI codes. Rogue Wave
Software has tested this only on Linux x86.
1 You must link your parallel application with the MemoryScape agent
as described “LIBPATH and Linking” on page 135. On most Linux x86
systems, you’ll type:
mpicc -g test.o -o test -Lpath \
-ltvheap -Wl,-rpath,path
2 Start MemoryScape using the -tv command-line option to the mpirun
script in the usual way. For example:
mpirun -tv mpirun-args test args
MemoryScape will start up on the rank 0 process.
3 If you need to configure MemoryScape, you should do it now.
4 Run the rank 0 process.
IBM PE
Here's how to use MemoryScape with IBM PE MPI codes:
1 You must prepare your parallel application to use the MemoryScape
agent in “LIBPATH and Linking” on page 135 and in “Installing
tvheap_mr.a on AIX” on page 135. Here is an example that usually
works:
mpcc_r -g test.o -o test -Lpath_mr -Lpath \
path/aix_malloctype.o
“Installing tvheap_mr.a on AIX” on page 135 contains additional
information.
2 Start MemoryScape on poe as usual:
memscape poe -a test args
Because tvheap_mr.a is not in poe’s LIBPATH, enabling MemoryScape upon the poe process will cause problems because poe will
not be able to locate the tvheap_mr.a malloc replacement library.
3 If you need to configure MemoryScape, you should do it now.
4 Run the poe process.
Creating Programs for Memory Debugging
136
RMS MPI
Here's how to use MemoryScape with Quadrics RMS MPI codes. Rogue
Wave Software has tested this only on Linux x86.
ROGUEWAVE.COM
1 There is no need to link the application with MemoryScape because
prun propagates environment variables to the rank processes. However, if you’d like to link the application with the agent, you can.
2 Start MemoryScape on prun. For example:
memscape prun -a prun-args test args
3 If you need to configure MemoryScape, you should do it now.
4 Run the prun process.
Creating Programs for Memory Debugging
137
ROGUEWAVE.COM
Creating Programs for Memory Debugging
138
Chapter 5
MemoryScape Scripting
You can obtain information from MemoryScape by executing it in batch
mode using the memscript command. Batch mode requires the use of
command-line options, like so:
memscript command_line_options
display_specifiers Command-Line
Option
The -display_specifiers command-line option controls how MemoryScape
writes information to the log file.
-display_specifiers “list_item”
Specifies one or more items that can be added or excluded from the log file. Separate items with a comma.
ROGUEWAVE.COM
list_item values are described in the following table. The word no in front of
item suppresses its display.
lItem
Controls display of ...
[no]show_allocator
The allocator for the address space
[no]show_backtrace
The backtrace for memory blocks
[no]show_backtrace_id
The backtrace ID for memory blocks
[no]show_block_address
The start and end addresses for a memory block
[no]show_flags
Memory block flags
[no]show_guard_id
The guard ID for memory blocks
[no]show_guard_settings
The guard settings for memory blocks
[no]show_image
The process/library associated with a
backtrace frame
[no]show_owner
The owner of the allocation
[no]show_pc
The backtrace frame PC
MemoryScape Scripting
139
lItem
Controls display of ...
[no]show_pid
The process PID
[no]show_red_zones_settings The Red Zone entries for allocations and
deallocations in the entire address space
ROGUEWAVE.COM
MemoryScape Scripting
140
event_action Command-Line Option
Event
Description
guard_corruption
Guard corruption was detected when
program deallocated a block.
hoard_low_memory_threshold Hoard low memory threshold is
crossed.
The -event_action command-line option is the most complex of the command line options. Its format is as follows:
-event_action “event=action list”
Specifies one or more actions that the script should
perform if an event occurs. The “event=action list”
consists of comma-separated set event=action pairs.
For example:
"alloc_null=save_memory_debugging_file, \
dealloc_notification=list_allocations"
event can be:
Event
Description
addr_not_at_start
A block is being freed, and the address
is not at the beginning of the block.
alloc_not_in_heap
The block being freed is not in the heap.
alloc_null
The malloc() function returned a null
block.
alloc_returned_bad_alignment The block is misaligned.
realloc_not_allocated
Program attempted to reallocate a
block that was not allocated.
rz_overrun
Program attempted to access memory
beyond end of allocated block.
rz_underrun
Program attempted to access memory
before start of allocated block.
rz_use_after_free
Program attempted to access block
after it was deallocated.
rz_use_after_free_overrun
Program attempted to access memory
beyond end of deallocated block.
rz_use_after_free_underrun
Program attempted to access memory
before start of deallocated block.
termination_notification
Program is about to execute its _exit
routine.
action is as follows:
any_memory_event
Action
Description
All memory notification events.
bad_alignment_argument
check_guard_blocks
The block returned by the malloc library is not
aligned on a byte boundary required by your
operating system. The heap may be corrupted.
(This is not a program error.)
Check for guard blocks and generate a
corruption list.
list_allocations
Create a list of all your program’s allocations.
list_leaks
Create a list of all of your program’s
leaks.
save_html_heap_status_source_view
Save the Heap Status Source report as
an HTML file.
double_alloc
Allocator returned a block already in
use. The heap may be corrupted.
double_dealloc
Program is attempting to free a block
already freed.
free_not_allocated
Program is attempting to free a block
that was not allocated.
ROGUEWAVE.COM
MemoryScape Scripting
141
Action
Description
save_memory_debugging_file
Save a memory debugging file; you can
reload this file at a later time.
save_text_heap_status_source_ Save the Heap Status Source report as a
view
text file.
ROGUEWAVE.COM
MemoryScape Scripting
142
x:y allocations from x to y
:y allocations from 1 to y
Other Command Line Options
The memscript command takes these additional options.
-guard_blocks
Turn on guard blocks.
-red_zones_overruns
Turn on testing for Red Zone overruns.
-red_zones_underruns
Turn on testing for Red Zone underruns.
x: allocations of x and higher
x allocation of x
-maxruntime hh:mm:ss
Specify the maximum amount of time the script
should run where:
hh: number hours
mm: number of minutes
ss: number of seconds
As a script begins running, MemoryScape adds information to the beginning of the log file. This information includes time stamps for both the
file when processes start, the name of the program, and so on.
-detect_use_after_free
Turn on testing for use after memory is freed.
-hoard_freed_memory
Turn on the hoarding of freed memory.
-hoard_low_memory_threshold nnnn
Specify the low memory threshold that will generate
an event.
-detect_leaks
Turn on leak detection.
-red_zones_size_ranges min:max,min:max,...
Specify the memory allocation ranges for which Red
Zones are in effect. Ranges can be in the following
formats:
memscript Example
The example here performs these actions:
Runs the filterapp program under MemoryScape control.
Passes an argument of 2 to the filterapp program.
Whenever any event occurs—an HIA event, SEGV, and the like—
saves a memory debugging file.
Allows the script to run for no longer than 5 seconds.
Performs the following activities: use guard blocks, hoard freed
memory, and detect memory leaks.
memscript -maxruntime "00:00:05" \
-event_action "any_event=save_memory_debugging_file" \
-guard_blocks -hoard_freed_memory -detect_leaks \
~/Work/filterapp -a 2
ROGUEWAVE.COM
MemoryScape Scripting
143
ROGUEWAVE.COM
MemoryScape Scripting
144
Chapter 6
MemoryScape Command-Line
Options
This chapter presents the commands used to invoke MemoryScape as
well as the variables you can place in a .memrc file.
Syntax
{ memscript | memscape } [ filename [ corefile ]] [ options ]
Arguments
filename
Invoking MemoryScape
Use the memscape command to invoke the MemoryScape GUI and the
memscript command to invoke MemoryScape in batch mode.
Topics in this section are:
“Syntax”
on page 145
on page 146
“Options”
corefile
Specifies the pathname of the executable being debugged. This can be an absolute or relative pathname. The executable must be compiled with
debugging symbols turned on, normally the -g compiler option. Any multiprocess programs that call
fork(), vfork(), or execve() should be linked with the
dbfork library.
Specifies the name of a core file. Use this argument
in addition to filename when you want to examine a
core file with MemoryScape.
If you specify mutually exclusive options on the same command line (for
example, -ccq and -nccq), MemoryScape uses the last option that you
enter.
ROGUEWAVE.COM
MemoryScape Command-Line Options
145
-a args
All MemoryScape console output is written to stderr.
-display displayname
Sets the name of the X Windows display to displayname. For example, -display vinnie:0.0 displays
MemoryScape on the machine named “vinnie.”
Default:
Options
Passes all subsequent arguments (specified by args)
to the program specified by filename. This option
must be the last on the command line.
-aix_use_fast_trap Specifies use of the AIX fast trap mechanism. You
must either set this option on the command line or
place it within a .memrc file.
-bg color
Same as -background.
-compiler_vars
Some Fortran compilers (HP f90/f77, HP f90, SGI 7.2
compilers) output debugging information that describes variables the compiler itself has invented for
purposes such as passing the length of character*(*)
variables. By default, MemoryScape suppresses the
display of these compiler-generated variables.
Default:
The value of your DISPLAY environment variable.
-dump_core
-no_dumpcore
(Default) Does not dump a core file when it gets an
internal error.
-env variable=value
Adds an environment variable to the environment
variables passed to your program by the shell. If the
variable already exists, this option replaces the previous value. You need to use this command for each
variable being added; that is, you cannot add more
than one variable with an env command.
However, you can specify the -compiler_vars option
to display these variables. This is useful when you
are looking for a corruption of a runtime descriptor
or are writing a compiler.
-nptl_threads
-no_compiler_vars
(Default) Does not show variables created by the
Fortran compiler.
-control_c_quick_shutdown
-ccq
(Default) Kills attached processes and exits.
-debug_file consoleoutputfile
Redirects MemoryScape console output to a file
named consoleoutputfile.
Specifies the use of NPTL threads by your application. You need to use this option only if MemoryScape cannot determine which thread package your
program is using.
-no_nptl_threads
Specifies that your application is not using the NPTL
threads package. Use this option only if MemoryScape thinks your application is using it when it is
not.
-no_control_c_quick_shutdown
-nccq
Invokes code that sometimes allows MemoryScape
to better manage the way it kills parallel jobs when it
works with management systems. This has only been
tested with SLURM. It may not work with other systems.
Dumps a MemoryScape core file when an internal
error occurs. This is used to help Rogue Wave Software debug MemoryScape problems.
-pid pid filename
Attaches to process pid for executable filename after
TotalView starts executing.
-search_path pathlist
Specifies a colon-separated list of directories to
search for source files. For example:
memscape -search_path proj/bin:proj/util
ROGUEWAVE.COM
MemoryScape Command-Line Options
146
-signal_handling_mode “action_list”
For example, here’s how to set the default action for
the SIGTERM signal to resend:
Modifies the way in which MemoryScape handles
signals. You must enclose the action_list string in
quotation marks to protect it from the shell.
“Resend=SIGTERM”
Here’s how to set the action for SIGSEGV and
SIGBUS to error, the action for SIGHUP to resend,
and all remaining signals to stop:
An action_list consists of a list of signal_action descriptions separated by spaces:
signal_action[ signal_action] ...
A signal action description consists of an action, an
equal sign (=), and a list of signals:
action=signal_list
“Stop=* Error=SIGSEGV,SIGBUS \
Resend=SIGHUP”
-shm “action_list”
Same as -signal_handling_mode.
-stderr pathname
Names the file to which MemoryScape writes the target program’s stderr information while executing
within MemoryScape. If the file exists, MemoryScape
overwrites it. If the file does not exist, MemoryScape
creates it.
-stderr_append
Tells MemoryScape to append the target program’s
stderr information to the file named in the -stderr
command or specified in the GUI. If the file does not
exist, MemoryScape creates it.
An action can be one of the following: Error, Stop,
Resend, or Discard.
A signal_specifier can be a signal name (such as
SIGSEGV), a signal number (such as 11), or a star (*),
which specifies all signals. We recommend that you
use the signal name rather than the number because
number assignments vary across UNIX sessions.
The following rules apply when you are specifying an
action_list:
-stderr_is_stdout
(1) If you specify an action for a signal in an action_list, MemoryScape changes the default action
for that signal.
-stdin pathname
Names the file from which the target program reads
information while executing within MemoryScape.
-stdout pathname
Names the file to which MemoryScape writes the target program’s stdout information while executing
within MemoryScape. If the file exists, MemoryScape
overwrites it. If the file does not exist, MemoryScape
creates it.
-stdout_append
Tells MemoryScape to append the target program’s
stdout information to the file named in the -stdout
command or specified in the GUI. If the file does not
exist, MemoryScape creates it.
-verbosity level
Sets the verbosity level of MemoryScape-generated
messages to level, which can be one of silent, error,
warning, or info.
Redirects the target program’s stderr to stdout.
(2) If you do not specify a signal in the action_list,
MemoryScape does not change its default action for
the signal.
(3) If you specify a signal that does not exist for the
platform, MemoryScape ignores it.
(4) If you specify an action for a signal more than
once, MemoryScape uses the last action specified.
If you need to revert the settings for signal handling
to MemoryScape’s built-in defaults, use the Defaults
button in the File > Signals dialog box.
Default:
ROGUEWAVE.COM
info
MemoryScape Command-Line Options
147
ROGUEWAVE.COM
MemoryScape Command-Line Options
148
Index
Numerics
0xa110ca7f allocation pattern 45, 58
0xdea110cf deallocation pattern 45, 58
A
-a option 123
-a option to memscape command 146
Add Filter Dialog Box 101
Add Filter dialog box 101
Add memory debugging file command 15, 107
Add parallel program option 70
Add parallel program screen 125
Add Program screen 107
Add Programs to Your MemoryScape Session page
66
Add Programs to Your MemoryScape Session screen
125, 127
adding command-line arguments 67
adding core files 67
adding environment variables 67
adding files 67
adding parallel programs 70
adding programs and files 13
adding remote programs 67
Address not at start of block problems 10
address space 3
addr_not_at_start event 141
advanced memory debugging options 74
Advanced Options button 74
ROGUEWAVE.COM
agent linking 131
agent, inseting with env 134
agent. See heap debugging.
agent’s shared library 6
AIX
compiling 64-bit code 121
linking C++ to dbfork library 121
linking to dbfork library 121
aix_install_ tvheap_mr.sh script 135
aix_use_fast_trap command-line option 146
-aix_use_fast_trap option 146
allocated blocks, seeing 40
allocation
0xa110ca7f pattern 58
adding guards 77
block painting 2
information 96
allocation focus 102
Allocation Location tab 18
allocation pattern 45
alloc_not_in_heap event 141
alloc_null event 141
alloc_returned_bad_alignment event 141
any_event event 141
arguments, remembering 126
Attach to running program screen 127
attaching to MPICH job 127
attaching to mprun job 130
attaching to PE jobs 129
attaching to programs 134
attaching to programss 124
attaching to running program 67
attaching to running program, limitation 68, 124
attaching to Sun MPI job 130
autolaunching 123
automatic variables 8
automatically halting program 83
B
backtrace
deallocation 19
recording 89
reports 98
which displayed 22
backtrace ID 96
backtrace ID, defined 98
-backtrace option 40, 41
backtrace reports 95
backtrace_depth TV_HEAP_ARGS value 49
backtraces 18, 22, 41
depth 40
displaying 27
setting depth 41
setting trim 41
trim 40
backtrace_trim TV_HEAP_ARGS value 49
bad_alignment_ argument event 141
Basic Options button 74
bg command-line option 146
-bg option 146
Index
149
bit painting
0xa110ca7f 58
0xdea110cf 58
bit pattern
writing 23
bit pattern, writing 2
-bkeepfile option 121
Block Allocation tab 89
block color coding 94
Block Deallocation tab 89
Block Details tab 18, 89
block display 92
block highlighting 93
block information 52, 93
block painting 2, 11, 14, 23
changing pattern 58
defined 2
Block Properties window 105
Block Properties window. 88
block tagging 23
blocks, allocating guards 77
bss data error 19
byte display 106
C
C++
including libdbfork.h 121
ccq command-line option 146
changing filter order 101
changing guard block patterns 77
changing guard block size 77
chart report 5, 85
check_guard_blocks action 141
checking for leaks 27
checking for problems 2, 64
checking guard blocks 41
-check_interior option 44
CLI commands
dheap 27, 34
dheap -apply_config 28
dheap -backtrace 27, 28
ROGUEWAVE.COM
dheap -compare 27, 29
dheap -disable 27
dheap -display 28
dheap -enable 27, 28
dheap -event_filter 29
dheap -event_flter 27
dheap -export 30
dheap -filter 31
dheap -guard 31
dheap -hoard 32
dheap -info 33
dheap -is_dangling 34
dheap -leaks 34
dheap -paint 34
dheap -reset_depth 28
dheap -reset_trim 28
dheap -set_depth 28
dheap -set_trim 28
dheap -status 27, 28
dheap -tag_alloc 35, 38
dheap -verbosity 38
dheap -version 39
-export 27
-guard 27
-hoard 27
-info 27
-is_dangling 27
-leaks 27
-nonotify 27
-notify 27
-paint 27
-tag_alloc 27
-version 27
color coding of blocks 94
Command line arguments area 126
command-line arguments, entering 67
command-line arguments, setting 64
command-line options
-aix_use_fast_trap 146
-bg 146
-ccq 146
-control_c_quick_shutdown 146
-debug_file 146
-display 146
-dump_core 146
-env 146
-nccq 146
-no_compiler_vars 146
-no_control_c_quick_shutdown 146
-no_dumpcore 146
-no_nptl_threads 146
-nptl_threads 146
-pid 146
-search_path 146
-shm 147
-signal_handling_mode 147
-stderr 147
-stderr_append 147
-stderr_is_stdout 147
-stdin 147
-stdout 147
-stdout_append 147
-verbosity 147
commands
dheap -guards 41
companring memory states 71
Compare Memory Report 107
comparing memory states 15, 27, 109
comparing state information 107
comparisons
process 110
compiling 64-bit code on AIX 121
compiling programs 120
concealed allocation 12
Configuration page 23
configuring 66
console output redirection 146
context menu, controlling processes 83
control_c_quick_shutdown command-line option
146
controlling execution 83
controlling processes
from context menu 83
individually 83
Index
150
controlling program execution task 81
core
dumping for MemoryScape 146
core files
writing 76
core files, adding 67
core fils, starting within MemoryScape 123
corrupt memory 14
notification 104
Corrupted Guard Blocks Report 56
Corrupted Memory report 69, 104
criteria
changing order 102
filters 102
operators 103
property 103
removing 102
Current Processes area 92
custody changes 12
D
dangling checks 27
dangling interior pointer 44
dangling pointer
problems 23
dangling pointers 9, 44
example 24
dangling pointers and leaks
compared 10
data section 4
data segment memory 84
Data Source area 110
Data Source controls 96
dbfork and Linux for Mac OS X 122
dbfork library
linking with 121
dbg files 76
deallocate, defined 7
deallocated memory, hoarding 114
deallocated memory, retaining 59
deallocation
ROGUEWAVE.COM
0xdea110cf pattern 58
backtrace 19
block painting 2
notifications 90
deallocation information 96
deallocation pattern 45
Deallocation tab 18
debug_file command-line option 146
-debug_file option 146
debugging command-line option 13
debugging MPICH applicaitions 126
debugging options 14
Painting memory 79
depth, backtraces 41
Detailed program and library report 85
Detect Leaks checkbox 96
-detect_leaks 143
dheap 27
-compare 26
-disable 26
ed_zones 26
-enable 26
example 27
-export 43
-export, data option 43
-export, output option 43
-export, set show_backtraces option 43
-export, set_show_code option 43
-filter 26, 43
-filter, enable filtering 43
-filter, enabling a filter 43
-hoard 26
-info 26
-leaks 26
-nonotify 26
-notify 26
-paint 26
status of Memory Tracker 26
dheap command, see also heap debugging
dheap -guards 41
disabling 28
disabling all filters 101
disabling memory debugging 27
disabling notification 27
discarding memory information, when 14
disk icon, memory comparisons 109
display command-line option 146
-display option 146
display_allocations_on_exit 49
displaying backtrace 27
displaying memory debugger information 27
-display_specifiers command-line option 139
dont_free_on_dealloc flag 40
double_dealloc event 141
dump_core command-line option 146
dynamically allocate space 10
E
Edit Filter Dialog Box 101
editing filters 101
Enable Filtering check box 96, 100
Enable Filtering checkbox 93
enable guard blocks option 69
enabling
memory debugging 27
notification 27
enabling all filters 101
enabling painting 79
entering command-line arguments 67
entering environment variables 67
-env command-line option 146
env, inserting agent 134
environment variables
LD_LIBRARY_PATH 122
environment variables, entering 67
environment variables, TV_HEAP_ARGS 49
Envrionment variables tab 126
error
freeing stack memory 19
error notification 88
error notifications 75
event backtrace 18
event indicator 17, 75
Index
151
Event Location tab 18, 89
event notification options 88
-event_action command-line option 141
events 88
writing file when occurring 76
examining memory 51
executing on remote hosts 67
execution controls 83
execution, stopping 68
execve() 121
exit events 14
_exit routine 75
exit, notification option 75
Export Memory Data command 15, 68, 107
exporting memory data 68
exporting memory information 27
extending a block 11
F
fifo hoard queue 42
File > Export command 76
files, libdbfork.h 121
filter criteria 102
Filter out this entry 100
filter properties 101
filtering 27, 93, 96, 100
heap information 43
Heap Status Graphical Report 56
overview 56
reports 51
filters
changing criteria order 102
criteria 102
criteria operators 103
criteria properties 103
disabling all 101
editing 101
enabling all 101
naming 101
ordering 101
removing 101
ROGUEWAVE.COM
removing criteria 102
filters, editing 101
finding deallocation problems 10
finding differences 110
finding heap heap allocation problems 10
finding memory leaks 21
flags 40
dont_free_on_dealloc 40
hoarded 40
notifiy_dealloc 40
notifiy_realloc 40
paint_on_dealloc 40
fork() 121
Fortran, tracking memory 6
frames, eliminating 40
free not allocated problems 10
free problems 2, 40
finding 17
free stack memory errir 89
freeing bss data error 19
freeing data section memory error 19
freeing freed memory 19
freeing memory that is already freed error 19
freeing stack memory error 19
freeing the wrong address 20
freeing the wrong address error 20
free_not_allocated event 141
function backtrace, backtrace
G
-g 13
Generate a core file and abort the program option 76
Generate a lightweight memory data file option 76
graphical heap display 18
Graphical report 51, 52
Graphical View 52
graphically viewing the heap 92
Guard allocated memory option 77
guard block display 106
guard blocks 2, 14, 27
altering 104
changing patterns 77
changing size 77
checking 41
checking for errors 56
defined 104
enabling 104
explained 56
manually checking for 77
maximum size 77
medium debugging level 77
notification 14, 41, 56
notifications 104
notify on deallocation problem 77
overwriting 14
patterns 104
-guard_blocks command-line option 143
guard_corruption event 141
H
Halt execution at process exit 14
Halt execution at process exit option 75
Halt execution on memory event or error option 75,
88
handling signals 147
header section 4
heap
defined 10
status 15
viewing graphically 92
heap allocation problems 10
heap API 10
stopping allocation when misused 11
heap API problems 40
heap debugging 17, 28
attaching to programs 134
backtraces 33
enabling 28
enabling notification 39
environment variable 134
freeing bss data 19
freeing data section memory error 19
Index
152
freeing memory that is already freed error 19
freeing the wrong address 20
functions tracked 17
IBM PE 136
incorporating agent 131
interposition
defined 6
linker command-line options 132
MPICH 136
preloading 6
realloc problems 20
RMS MPI 137
tvheap_mr.a
library 135
using 17
heap displays, simplifying 43
heap information 95
filtering 43
Heap Information tab 94
heap information, saving 43
heap interpositiona agent 6
heap library functions 6
heap memory 84
Heap Source Backtrace report 98
heap status 27
Heap Status Backtrace report 99
Heap Status Graphical Report 69, 90, 92, 94
color coding key 52
zoom controls 92
Heap Status Graphical report 51, 52
Heap Status Graphical Report screen 92
Heap Status Graphical View 52
Heap Status reports 92
heap status reports 69
Heap Status Source Report 96
Heap Status Source report 99
Heap Usage Monitor 109
heap usage monitor 83
HIA, linking 14
hoard capacity 42
Hoard deallocated memory option 79
hoard information 96
ROGUEWAVE.COM
-hoard option 42
hoard size 80
hoarded flag 40
-hoard_freed_memory command-line option 143
hoarding 14, 23, 27, 42, 59
block maximum 42
deallocated memory 114
defined 2
enabling 42
finding a multithreading problem 59
finding dangling pointer references 59
KB size 42
option 114
status 42
Host field 123
host names, specifying’specifiying host names 123
hosts, remote 67
HTML, saving reports as 113
I
identifying leaks within libraries 85
importing memory state 107
individually controlling processes 83
-info option 40
information 27
interposition 6, 88
interposition defined 6
-is_dangling option 44
L
LAM and MemoryScape 129
LD_PRELOAD heap debugging environment variable
134
leak consolidation 44
leak detection 44
checking interior 44
Leak Detection report 22
Leak Detection reports 21, 68
Leak Source report 99
leaks 27
concealed ownership 12
custody changes 12
defined 2, 11
-leaks option 44
listing 2
orphaned ownership 12
showing 96
underwritten destructors
leaks 12
why they occur 11
leaks and dangling pointers
compared 10
leaks reports 99
leightweight memory file
writing 76
lib directory 102
libdbfork.a 121, 122
libdbfork.h file 121
libdbfork_64.a 122
LIBPATH and linking 135
libraries
leaks within 85
library report 85
linking 4
linking agent 131
linking MemoryScape 14
linking to dbfork library 121
AIX 121
C++ and dbfork 121
SunOS 5 122
list_allocations action 141
listing leaks 2
list_leaks action 141
load file 4
loading programs and files 13
M
Mac OS X, linking dbfork 122
machine code section 4
magnifying glass controls 92
MALLOCTYPE heap debugging environment variable
134, 135
Index
153
Manage Filters option 100
Manage Process and Files screen 81, 83
managing processes 83
-maxruntime command-line option 143
memalign_strict_alignment_even_multiple
TV_HEAP_ARGS value 50
memory
data segment 84
examining 51
heap 84
maps 3
pages 3
stack 84
text segment 84
total virtual memory 85
virtual stack 85
memory block painting 14
Memory Comparison report 110
memory comparisons 71, 109
Memory Comparisons report 69
Memory Comparisons screen 109
Memory Content tab 94
memory contents tab 106
memory corruption 2
memory data, exporting 68
Memory Debugger 27
functions tracked 6
using 13
Memory Debugging Data Filters Dialog Box 101
memory debugging file 107
indicator 107
memory debugging options 13
advanced 74
basic 72
Guard allocated memory 77
Halt execution at process exit 75
Halt execution on memory event or error 75
high 74
Hoard deallocated memory 79
low 74
medium 74
screen 72
ROGUEWAVE.COM
Memory Debugging Options screen 74, 88
memory error notification 14
Memory Event Details Window
Point of Deallocation tab 18
memory hoarding 14
memory information, exporting 27
memory leak
defined 11
memory painting 27, 77, 79
Memory Reports area 68
memory state
importing 107
restoring 107
saving 107
memory states
comparing 15
memory states, comparing 15
Memory Tracker, see dheap command
memory usage
seeing 84
Memory Usage reports 5, 15, 69, 84
chart 85
Library 85
Process 85
memory, painting 115
memory, reusing 42
MemoryScape
command options 145
linking 14
starting 13, 64
MemoryScape and LAM 129
MemoryScape and MPICH 126
MemoryScape and PE 128
MemoryScape and QSW RMS 129
MemoryScape and Sun MPI 130
memscape command 64, 66, 126
memscript command 66
merging object files 4
MmeoryScape command line 123
MPI
on Sun 130
MPI debugging 71
MPI issues 127
MPI launcher arguments area 126
MPI programs, starting 70, 124
MPICH
and heap debugging 136
MPICH and MemoryScape 126
MPICH and poe 126
MPICH applications, debugging 126
MPICH library, selecting 126
MPICH P4 procgroup 127
MPICH, attaching to job 127
mpirun 123
mprun 130
mprun command 130
mprun job, attaching to 130
N
Naming Options dialog box 76
-nccq option 146
-no_compiler_vars option 146
-no_control_c_quick_shutdown option 146
Nodes, selecting number of 126
no_dumpcore command-line option 146
-no_dump_core option 146
non-invasive 6
no_nptl_threads command-line option 146
notification 40
disabling 27, 39
enabling 39
notification for guard blocks 41
notifications 14, 88, 89
defined 14
error 75, 88
exit 14
guard blocks 14, 77
setting individual events 75
notify 34
-notify option 40
Notify when deallocated 90
Notify when reallocated 90
notify_dealloc flag 40
Index
154
notifying at process exit option 75
notify_realloc flag 40
nptl_threads command-line option 146
O
object files
merging 4
od-like features 106
options 14
advanced 74
-aix_use_fast_trap 146
basic 72
Guard allocated memory 77
Halt execution at process exit 75
Halt execution on memory event or error 75
high 74
Hoard deallocated memory 79
low 74
medium 74
painting 115
Painting memory 79
setting 72
orphaned ownership 12
output TV_HEAP_ARGS value 50
Overall Totals area 52
overwriting guard blocks 14
P
Paint memory option 79
-paint option 45
painting 45
allocation pattern 45
blocks 2
deallocated memory 59
deallocation pattern 45
enabling 45
memory 27, 77, 79, 115
options for 115
pattern 115
patterns 77, 79
zero allocation 45
ROGUEWAVE.COM
painting. See block painting
paint_on_dealloc flag 40
parallel progams, adding 70
Parallel system, selecting 126
parameter values
returning 7
parameters
by reference 9
by value 9
passing arguments to programs 123
passing pointer to memory to lower frames 8
passing pointers 9
patterns for guard blocks 104
patterns for painting 115
PC, setting 11
PE and MemoryScape 128
PE jobs, attaching 129
pid command-line option 146
poe and MPICH 126
poe, starting using 129
Point of Deallocation tab 18
pointers
dangling 9
passing 8
realloc problem 11
pop-up with block information 93
port number. 123
preload variables, by platform 134
preloading 6, 14
preloading Memory Debugger agent 6
process comparisons 110
process control from context menu 83
Process Event screen 90
Process Events screen 17, 89
process report 85
Process Status and Control area 70
processes, attaching to 124
processes, individually controlling 83
processes, managing 83
program execution, controlling 81
program, attaching 67
program, attaching limitation 68, 124
program, mapping to disk 3
programs
compiling 120
programs, attaching to 124
programs, passing arguments to 123
properties dialog box 64
Properties window 90
properties, filters 101
prun, using 130
Q
QSW RMS and MemoryScape 129
R
reachable blocks 44
reading saved memory state information 69
realloc errors 20
realloc not allocated problems 10
realloc pointer problem 11
realloc problems 11, 20
finding 17
reallocation timing 9
realloc_not_ allocated event 141
recording memory requests 74
reference counting 12
Related Blocks area 52
-remote 123
remote computers, debugging on 123
remote hosts 67
remote login 128
remote programs, adding 67
remote programs, starting 123
removing filters 101
reports
filtering 51
when to create 14
requests, recording 74
restoring memory state 107
retaining deallocated memory 59
returning parameter values 7
reuse notifications 90
Index
155
reusing memory 42
Reverse Diff button 110
running out of memory 12
run-time events 88
S
Save Report command 113
saved state information, using 107
save_html_heap_ status_source_view action 141
save_memory_ debugging_file action 142
save_text_heap_status_source_view action 142
saving heap information 43
saving memory state 107
saving memory state information 69
saving reports
as HTML 113
search controls 92
search_path command-line option 146
sections
data 4
header 4
machine code 4
symbol table 4
seeing memory usage 84
Selected Block area 52
selecting a block 94
setting MemoryScape options 72
setting the PC 11
setting timeouts 128
-shm option 147
show_backtrace item 139
show_backtrace_id item 139
show_block_address item 139
show_flags item 139
show_guard_details item 139
show_guard_id item 139
show_guard_status item 139, 140
show_image item 139
showing backtraces 40, 41
showing leaks 96
show_leak_stats item 139
ROGUEWAVE.COM
show_pc item 139
show_pid item 140
signal_handling_mode command-line option 147
-signal_handling_mode option 147
signals, handling in MemoryScape 147
slave processes 39
SLURM, control_c_quick_shutdown variable 146
source report 95
source reports 96
space, dynamically allocating 10
stack frames 8
arranging 7
stack memory 7, 9, 84
stack virtual memory 85
stack, compared to data section 7
stacl frame
data blcok 8
staring MPI programs 70
starting MemoryScape 13, 64, 123
memscript command 66
starting MPI programs 124
starting remove programs 123
starting with poe 129
state information 40
comparing 107
exporting 68
when discarded 68
-status option 40
-stderr command-line option 147
-stderr_append command-line option 147
stderr_append command-line option 147
stderr_is_stdout command-line option 147
stdin command-line option 147
-stdout command-line option 147
stdout_append command-line option 147
stopping execution 68, 89
stopping execution on heap API misue 11
stopping when free problems occur 2
strdup allocating memory 10
Summary screen 109
Sun MPI 130
Sun MPI and MemoryScape 130
SunOS 5
linking to dbfork library 122
switch-based communications 128
symbol table section 4
T
-tag_alloc 48
tagging 23, 27, 45, 48
notify on dealloc 48, 49
notify on realloc 48, 49
Tasks, selecting number of 126
tasks, specifying 126
termination_ notification event 141
text segment memory 84
timing of reallocations 9
tmeouts, setting 128
tooltip displaying block data 52
TotalView lib directory 102
tracking memory problems 17
tracking realloc problems 20
trim, backtrace 41
-tv option 126
tvdsvr 67, 123
TVHEAP_ARGS 71
TV_HEAP_ARGS environment variable 49
backtrace_depth 49
backtrace_trim 49
display_allocations_on_exit 49
memalign_strict_alignment_even_multiple 50
output 50
verbosity 50
TV_HEAP_ARGS value 49
tvheap_mr.a
aix_install_tvheap_mr.sh script 135
and aix_malloctype.o 135
creating using poe 135
dynamically loading 135
libc.a requirements 135
pathname requirements 135
relinking executables on AIX 135
tvheap_mr.a library 135
Index
156
U
underwritten destructors 12
using env to insert agent 134
using prun 130
using the Memory Debugger 13
V
-verbosity option 147
verbosity TV_HEAP_ARGS value 50
version 27
-version option 40
version, memory debugger 27
ROGUEWAVE.COM
viewing memory contents 106
viewing the heap graphically 92
views
simplifying 43
virtual memory 85
virtual stack memory 85
visual block display 92
W
watchpoints 23
-Wl,-bkeepfile option 121
writing a core file 76
writing a lightweight memory file 76
writing core files 76
writing lightweight memory files 76
wrong address, freeing 20
Z
zero allocation 45
zero allocation painting 45
zoom controls 92
zooming 87
Index
157
ROGUEWAVE.COM
Index
158
Download PDF