Home
Contact Information
Announcements
Discussion Forum (LMS)
Syllabus
Learning Outcomes
Prerequistites
Course Grades
Calendar
Lecture notes
Lab materials
Homework
Test reviews
Weekly Schedule
Office Hours
Lab Times
Getting Help
Tutoring
Advice from TAs
Advice from Students
Homework
Due Date and Time
Late Day Policy
Compilers
Electronic Submission
HW Grading Criteria
Collaboration Policy &
Academic Integrity
References
Optional Textbooks
Web Resources
C++ Development
Compilers
Code Editors & IDEs
Misc. C++ Programming
Command Line Args
File I/O
string → int/float
Memory Debugging
Valgrind
Dr. Memory
|
Memory Debugging
Segmentation faults and other memory bugs (reading uninitialized
memory, reading/writing beyond the bounds of an array, memory leaks,
etc.) can be hard to track down with a traditional debugger. Memory
errors can be elusive, and may not cause the program to crash
immediately. A program with memory errors may even appear to work
correctly on some datasets or on some machines.
We recommend using a special debugger to find memory errors, for
example Valgrind or Dr. Memory. Commercial
versions of these tools include Purify and
Insure++.
Valgrind
Valgrind
only works on Unix-based systems (e.g., GNU/Linux, FreeBSD, and
MacOSX). Valgrind does not work on Cygwin because Cygwin emulates
UNIX at the library layer, but Valgrind operates at the system call
layer and the Windows system calls are significantly different than
UNIX system calls.
Note: Valgrind on the more recent Mac OSX versions
10.8 & 10.9 is still a work in progress -- you will likely see
false positive memory errors, but it may still be a helpful tool
in debugging.
To use Valgrind...
-
Valgrind is installed by default on most Linux distributions.
For MacOSX you'll need to install it yourself -- you may want to try
Homebrew, a package manager for Mac OSX.
Once Homebrew is setup, you can just type:
brew install valgrind
Your program should be compiled with debug information enabled
by specifying the -g flag. For example:
g++ -g main.cpp foo.cpp -o foo.out
Then run the program by adding Valgrind to the beginning of
your command line (replace foo.out arg1 arg2 with your
program name and any command line arguments for your program):
valgrind --leak-check=full --show-reachable=yes foo.out arg1 arg2
If that example run of your program contains any memory errors
Valgrind will output information to help you track down the error.
Note that using Valgrind can significantly slow down execution time as
it inspects every memory action. You may need to craft a smaller test
case that exhibits the same bug you would like to solve.
Note: Because some STL classes (including string) use their
own allocators (and do other optimization tricks), there may be a
warning about memory that is ``still reachable'' even though you've
deleted all your dynamically allocated memory. The newer versions of
Valgrind automatically suppresses some of these common false positive
errors, so you may see this listed as a ``suppressed leak''.
Suppression of False Positives in Valgrind
If you see false positive error messages in Valgrind (this is likely to
happen with Valgrind on the newest versions of Mac OSX), you will
probably want to create an error suppression file to allow you to focus on your actual errors.
Add the --gen-suppressions=all option to the valgrind command line:
valgrind --leak-check=full --gen-suppressions=all foo.out arg1 arg2
-
For each false positive (an error not obviously pointing at your
code), copy-paste the suppression text (a block of text in curly
braces) into a new file containing your custom suppressions, let's
call it my_suppressions.txt.
- Use that suppression file every time you run Valgrind:
valgrind --leak-check=full --suppressions=my_suppressions.txt foo.out arg1 arg2
You may need to add to that file in the future, when you use
additional library functions that cause different false positive errors.
Read more about Valgrind suppressions here:
http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress
Dr. Memory
Dr. Memory detects
the same classes of errors as Valgrind and can be used on GNU/Linux
and Microsoft Windows operating systems.
For questions, bug reports, and discussion, use the
Dr. Memory Users group:
http://groups.google.com/group/drmemory-users
Dr. Memory on GNU/Linux
-
Obtain Dr. Memory for Linux from
https://code.google.com/p/drmemory/wiki/Downloads?tm=2
Untar the package to a directory of your choice. Type something like:
tar -xvzf DrMemory-Linux-1.6.1-2.tar.gz
We'll assume DrMemory is in the directory
"~/DrMemory-Linux-1.6.1-2/" for the rest of these instructions.
Ensure your Linux installation is able to build 32-bit
applications. On 64-bit Ubuntu you will want these packages:
sudo apt-get install ia32-libs g++-multilib
Build your application as 32-bit by passing -m32 to g++
(Dr. Memory does not yet support 64-bit).
Be sure to include debug information by passing -g to g++.
For example:
g++ -g -m32 main.cpp foo.cpp -o foo.out
Run this command, replacing foo.out arg1 arg2
with your executable name and any command line arguments:
~/DrMemory-Linux-1.6.1-2/bin/drmemory.pl -brief -- foo.out arg1 arg2
Dr. Memory will report errors to the screen as it runs. It will print a
summary at the end of what it found.
Dr. Memory on Mac OSX
NOTE: This is a beta test release of Dr. Memory on Mac OSX. It
has been initially tested on 10.7.5 (Lion) and 10.9.1 (Mavericks). If
you encounter a problem, you can report these issues to the
Dr. Memory Users Group by email:
drmemory-users@googlegroups.com. Don't send your full
homework submission (it is a public mailing list). Alternatively,
upload the your homework to the submission site and email the
instructor a detailed description of the issue and she will forward it
to the Dr. Memory development team.
-
Download:
http://dl.bintray.com/bruening/DrMemory/DrMemory-MacOS-1.7.0-5.tar.gz
Untar the package to a directory of your choice. Type something like:
tar -xvzf DrMemory-MacOS-1.6.1-105.tar.gz
We'll assume DrMemory is in the directory
"~/DrMemory-MacOS-1.6.1-105/" for the rest of these instructions.
Build your application as 32-bit by passing -m32 to your C++ compiler
(Dr. Memory does not yet support 64-bit).
Be sure to include debug information by using the -g option.
For example:
g++ -g -m32 main.cpp foo.cpp -o foo.out
Run this command, replacing foo.out arg1 arg2
with your executable name and any command line arguments:
~/DrMemory-MacOS-1.6.1-105/bin/drmemory.pl -brief -- foo.out arg1 arg2
Dr. Memory will report errors to the screen as it runs. It will print a
summary at the end of what it found.
Installing Dr. Memory on Windows
-
Obtain Dr. Memory. To easily place it on the system path, use the
installer (the .exe file). Alternately, you can instead obtain the
.zip file for a local install.
https://code.google.com/p/drmemory/wiki/Downloads?tm=2
Run the installer. Select ``Add to system path for current user''.
-
Follow the instructions below to compile & run your program
using MinGW g++, the Visual Studio IDE, or the Visual Studio Command
Prompt.
Dr. Memory and MinGW
You can't use the Cygwin version of g++ with Dr. Memory, but you can
run Dr. Memory on Windows using the MinGW compiler (Minimalist GNU for
Windows):
-
Install Cygwin
-
Run the Cygwin installer (setup-x86.exe), search for "mingw", open
Devel, and install "mingw-gcc-g++"
-
Open a Cygwin terminal, navigate to the directory with your
files, and compile your program with the mingw compiler by typing:
i686-pc-mingw32-g++.exe -static-libgcc -static-libstdc++ -ggdb -o foo.exe main.cpp foo.cpp
-
You can run your program under Dr Memory by typing:
drmemory -brief -batch -- foo.exe arg1 arg2
Replace "foo.exe arg1 arg2" with your program name and any
command line arguments for your program.
Dr. Memory and Visual Studio
Alternatively, you can use Dr. Memory with the Microsoft Visual Studio compiler:
Build your application as 32-bit with Visual Studio (32-bit is
the default). Be sure to include debug information. You can verify
that you are including debug information by looking at the properties
of your build target:
Press Alt-F7 to bring up the configuration properties.
Under "Configuration Properties | C/C++ | General", the "Debug
Information Format" entry should either say "Program Database (/Zi)"
or "Program Database for Edit and Continue (/ZI)". Additionally, under
"Configuration Properties | Linker | Debugging", the "Generate Debug
Info" entry should say "Yes (/DEBUG)".
-
Disable Runtime Checks: The Visual Studio compiler's
/RTC1 flag can prevent Dr. Memory from reporting
uninitialized reads of local variables, and the /RTC1 checks
for uninitialized reads themselves may not catch everything that
Dr. Memory finds. However, /RTC1 does perform additional
stack checks that Dr. Memory does not, so for best results, your
application should be run under Dr. Memory without /RTC1, and
run natively (for development & testing without Dr. Memory) with
/RTC1.
In the Visual Studio IDE, press Alt-F7 and then under
"Configuration Properties | C/C++ | Code Generation" ensure "Basic
Runtime Checks" says "Default".
-
To run Dr. Memory within the IDE you
will need to set up Dr. Memory as a Visual Studio "External Tool",
which adds it as a new menu item.
If using Visual Studio Express 2010 or later, first enable the full
menu system by selecting "Tools | Settings | Expert Settings" (this
step is not necessary for Visual Studio Professional).
Select the "Tools | External Tools..." menu option to open the
External Tools dialog box. Click Add and fill in the fields as follows
(adjusting the path to drmemory.exe if you installed it somewhere
else):
Title: Dr. Memory
Command: C:\Program Files (x86)\Dr. Memory\bin\drmemory.exe
Arguments: -visual_studio -- $(TargetPath)
Initial Directory: $(TargetDir)
Check both the "Use Output window" and "Prompt for arguments" checkboxes. Then click OK.
-
Now you can select the "Tools | Dr. Memory" menu item and Visual
Studio will run your application under Dr. Memory. You can add
arguments to your application in the box that pops up immediately
after selecting the men item by adding them at the end, after "$(TargetPath)".
-
The output of Dr. Memory (along with your program) will be
printed to the Visual Studio Output Window. Dr. Memory will report
errors to the screen as it runs. It will print a summary at the end
of what it found. You can double-click on a source file on any
error's callstack frame in order to automatically open up that file to the
line number indicated.
Using the Visual Studio compiler without the Visual Studio Integrated
Development Environment (IDE)
-
Launch the Visual Studio Command Prompt. From the Start menu,
under All Programs, find your Visual Studio version (e.g., 2010) and
expand it. Then expand Visual Studio Tools. Select the "Visual
Studio 2010 Command Prompt". (You don't want the x64 or Cross Tools
versions.)
Note: this is not the Cygwin shell.
This Command Prompt is a cmd shell in which a batch file that
comes with Visual Studio has been executed. This batch file is called
vcvars.bat and it sets up the path and environment variables
needed to run the compiler from the command line.
Note: You can extract the environment variables from the batch file and set them
up in your .bashrc so you can build from a Cygwin shell.
-
At the command line, change to the directory containing your
source files.
Run the compiler, which is called "cl". This will build
hw.exe from all .cpp files in the current directory:
cl /Zi /MT /EHsc /Oy- /Ob0 /Fehw.exe *.cpp
-
If you installed Dr. Memory before you opened the Command Prompt, you
can run drmemory from the same prompt.
Run this command, replacing foo.exe arg1 arg2
with your executable name and any command line arguments:
drmemory -brief -batch -- foo.exe arg1 arg2
If you don't see any extra output from Dr. Memory as your program
runs, remove the -batch flag and the Dr. Memory output will be sent to
a file and notepad will launch automatically to display this file.
drmemory -brief -- foo.exe arg1 arg2
-
Dr. Memory will print a summary at the end of what errors it found.
|