Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Detecting Memory Corruption with Dog Tags


May 1998/Detecting Memory Corruption with Dog Tags

Detecting Memory Corruption with Dog Tags

Jim Williams

A simple marker can reveal a broad class of storage overwrite problems.


One of the few systematic techniques for finding bugs related to memory corruption uses debugging versions of malloc and free. When asked for a block of memory, such a malloc implementation allocates an extra byte at the beginning and end of the block it returns. These bytes, known as "dog tags" or "guard words," are initialized by malloc to some known value before returning. Since they are hidden from the calling program, their contents should not change during the lifetime of the block. This allows free to check each block it receives for changes, treating any found as errors. This technique can detect memory overwrites, multiple frees of the same pointer, and frees of pointers that do not address dynamically-allocated memory.

This article describes a C++ class, DogTag, that uses the same idea. Simply adding a DogTag as a member of a class enables that DogTag to detect the above problems when they occur in objects of the class. Adding a few more lines to the same class enables its DogTags to detect uses of objects after they've been destroyed, and uses of objects that were never constructed. DogTags also have some advantages over debugging malloc libraries. One is the ability to find problems in objects of any storage type: heap, stack, or static.

Implementation

Listing 1 shows a conceptual implementation of the DogTag class. The full source is available online (see page 3 for downloading instructions). As shown, DogTags own a single data member named _this. During the lifetime of the object, _this holds the same value as the object's this pointer, initialized to that value at construction. Notice that the copy constructor and assignment operator do not copy the member from their argument, since all DogTags must have a unique _this member. Only in the destructor does the pointer finally change, being set there to null.

Controlling the member pointer in this way allows the isValid method to detect whether or not a problem has occurred. If isValid finds _this not equal to the object's address (this), it returns false. In such a case, one of the problems listed above has probably occurred. The destructor calls isValid within an assertion before setting _this to null. Thus, as objects owning DogTags go in and out of scope, or are allocated and deleted, they automatically check themselves for problems.

Using DogTags

The obvious way to use a DogTag is to add one to any class whose objects are getting corrupted. However, an even better way is to add them to your code from the beginning, ignoring them until they bark, much like assertions. Adding DogTags to a few, commonly-used classes is a good way to passively find these problems throughout development.

Instead of explicitly declaring DogTags or calling isValid, I have implemented two macros that accomplish the same thing. Both are conditionally defined with preprocessor directives (not shown here) that allow you to control whether they expand to the code shown or to nothing. To add a DogTag to a class, insert a call to the DECL_DOG_TAG macro in its body as follows:

class MyClass {
public:
   ...
   void method();

private:
   ...
   DECL_DOG_TAG(_dogTag)  //added
};

Note that no semicolon should be used in this macro call; otherwise, when the macro expands to nothing (as in a production build) it will leave a lone semicolon hanging in your class.

You can find problems earlier, plus additional types of problems, by inserting calls to CHECK_DOG_TAG into the methods of the class. CHECK_DOG_TAG conditionally expands to a call to isValid within an assertion or to nothing. Note that semicolons are needed after calls to this macro.

Summary

DogTags offer a way to automatically find many of the costliest bugs that exist in C++ software. They cannot find all such bugs, only those that corrupt the DogTag bytes. Nor are DogTags meant to replace more powerful commercial debugging tools. Even so, DogTags helped us find some subtle compiler bugs we were unable to find any other way. They are a worthy addition to the programmer's toolbox. o

Jim Williams received his education at Texas A&M University, where he earned a BS and MS in mechanical engineering. He currently writes software for United Space Alliance in support of space shuttle and space station robotics. His interests include object-oriented programming, classical mechanics, control systems, and numerical methods. He can be reached at [email protected].


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.