MFC advanced debugging technology

Source: Internet
Author: User

MFC advanced debugging technology

1. Use of TRACE macros

The TRACE macro is like the printf function we used in the C language before, so that the program outputs some debugging information during the running process, so that we can understand some of the program status. However, one difference is that the TRACE macro outputs only in the debugging status, and the Printh function used previously has outputs in any situation. Like the printf function, the TRACE macro can accept multiple parameters, such:

Int x = 1;

Int y = 16;

Float z = 32.0;

TRACE ("This is a TRACE statement/n ");

TRACE ("The value of x is % d/n", x );

TRACE ("x = % d and y = % d/n", x, y );

TRACE ("x = % d and y = % d and z = % f", x, y, z );

Note that the TRACE macro only works for the Debug project. In the Release project, the TRACE macro is ignored.

2. Use of assert macros

In the development process, we can assume that a certain condition must be true as long as the program runs correctly. If not, we can assert that the program is definitely wrong. In this case, we can use ASSERT to set assertions. The ASSERT macro parameter is a logical expression. When the program is running, if the logical expression is true, no action is taken. If the expression is false, a dialog box is displayed to warn you, and stop the program execution. At the same time, you must make a choice: Cancel, ignore, and retry. If you choose to cancel, the system stops running the program. If you choose to ignore, the system ignores the error and continues executing the program. If you choose to retry, the system recalculates the expression, and activate the debugger. Like the TRACE macro, The ASSERT macro only works for the Debug project. In the Release project, the TRACE macro is ignored.

The following example shows how to use ASSERT to check the return value of a function:

Int x = SomeFunc (y );

ASSERT (x> = 0); // ASSERT fails if x is negative.

Assertions can be used:

(1) You can use asserted statements to capture logical errors. You can set an assertion when the program logic must be true. The assertions have no effect on the program unless a logical error occurs.

(2) You can use an asserted statement to check the operation results. Assertions are most valuable for quick and intuitive checks on non-obvious operation results.

(3) You can use assertions to test the error type at the point where the error has been processed in the code.

3. Use assert_valid macro

The assert_valid macro is used to check the internal validity of an object while the program is running. For example, there is a student object. We know that each student is older than zero. If the age is less than zero, the student object must be faulty. In fact, the assert_valid macro is a call to the assertvalid function that is converted to an object, but the method is safer. Its parameter is an object pointer that calls its assertvalid member function.

In addition, each time a new class inherited from the cobject class is created, the member function can be reloaded to perform a specific validity check. The following example shows how to declare the assertvalid function:

Sclass cperson: Public cobject

{

Protedted:

Cstring m_strname;

Float m_salary;

Public:

# Ifdef _ debug

Virtual void assertvalid () const; // override

# Endif

//.....

};

When you override AssertValid, call the base class template of AssertValid before executing the program check. Then, use the ASSERT macro to check the unique members of the derived class, as shown below:

# Ifdef _ DEBUG

Void CPerson: AssertValid () const

{

// Call inherited AssertValid first

CObject: AssertValid ();

// Check CPerson menbers...

ASSERT (! M_strName.IsEmpty (); // Must have a name

ASSERT (m_salary> 0); // Must have an income

}

# Endif

4. Check for memory Vulnerabilities

In C ++ and C, the pointer problem, that is, memory application and release, is a headache. If the memory is applied but not released, and the program needs to run for a long time, then, the system resources will gradually decrease. When all resources of the system are used up, the system will crash. Therefore, you must ensure the full release of resources during the development process.

The method for checking memory vulnerabilities is as follows:

If you want to check whether a program segment has a memory vulnerability, you only need to map the system memory usage at the beginning of the program segment to record the memory usage at the beginning of the program, then, the system performs a memory ing at the end of the program segment. Compare two mappings to check whether there is unreleased memory and add unreleased memory, based on the allocation information in this section, the user is notified that the memory applied for there has not been released.

Specifically, it takes several steps to check the memory vulnerability:

(1) create a CmemoryState object at the beginning of the detected program segment and call its member function Checkpoint to obtain the current memory usage ing;

(2) create a CmemoryState object at the end of the detected program segment and call its member function Checkpoint to obtain the current memory usage ing;

(3) create 3rd CmemoryState objects, call the member function Difference, and take the first CmemoryState object and the second CmemoryState object as its parameters. If the two memory mappings are different, this function returns a non-zero value, indicating that the program segment has a memory vulnerability.

Here is an example:

# Ifdef _ DEBUG

CMemoryState oldMemState, newMemState, diffMemState;

OldMemState. Checkpoint ();

# Endif

CString s = "This is a frame variable ";

// The next object is a heap object

CPerson * p = new CPerson ("Smith", "Alan", "582130215 ");

# Ifdef _ DEBUG

NewMemState. Checkpoint ();

If (diffMemState. Difference (oldMemState, newMemState ))

{

TRACE ("Memory Leaked! /N ");

}

In this example, three CMemoryState objects are defined first. Then call the CMemoryState object member function Checkpoint before and after the code to detect the memory vulnerability, and then call the member function Difference of the 3rd CMemoryState object to determine whether there is a memory vulnerability. If yes, the TRACE macro is used to print the prompt message.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.