10 Debugging Tips for sharing Visual Studio native development

Source: Internet
Author: User
This article only covers some basic debugging techniques for Visual Studio, but there are other equally useful tricks. I've collated some of the debugging techniques for native development of visual Studio (at least vs 2008). (If you are working under managed code, the debugger will have more features, there are articles that describe them in codeproject), here are some tips for my grooming:

Abnormal Interrupts | Break on Exception
Pseudo-Variables in Watch Window | Pseudo-variables in Watch Windows
View heap objects after a symbol is out of bounds |
View the value of an array
Avoid entering unnecessary functions
Start Debugger from Code | Launch the debugger from code
Print in the Output window
Isolate memory leaks
Debug Release Version | Debug the Release Build
Remote debugging


Tip 1: Abnormal interrupts

Before processing is called, the debugger can be started to break when an exception occurs, allowing you to debug the program immediately after the exception occurs. The action call stack allows you to find the root cause of the exception.

Vistual Studio allows you to specify the type of exception or special exception that you want to break. Select the menu debug>exceptions Pop-up dialog box, you can specify a native (or managed) exception, and you can add your own custom exception, in addition to some default exceptions that the debugger comes with.








The following is an example of a debugger break when an Std::exception exception is thrown.






Tricks 2:watch the pseudo-variables in the window

The Watch window or QuickWatch dialog box provides some specific (debugger-recognizable) variables, called pseudo-variables. The document contains the following:

$tid-the thread ID of the current thread
$pid--Process ID
$cmdline the command-line string ———-the startup program
$user ———-The account information that is running the program
$registername-Display the contents of the Register Registername
In any case, the pseudo-variable about the last error is very useful:

$err--– Displays the error code for the last error
$err, hr-displays the error message for the last error






Tip 3: Review the heap objects after crossing the line

Sometimes, after the debug symbol is out of bounds, you also want to see the value of the object, at which point the variables in the Watch window are disabled and can no longer be viewed (nor updated), even though the object still exists. If you know the address of the object, you can continue to observe it fully. You can convert the address into a pointer to the object type and place it in the Watch window.

In the following example, when you step out of Do_foo (), _foo can no longer be accessed. However, after you convert its address to foo*, you can continue to observe the object.






Tip 4: View the value of an array

If you're manipulating a very large array (let's say we have at least hundreds of elements, but maybe less), expanding the array in the Watch window and finding some specific range of elements is a hassle because you're going to keep scrolling. If the array is allocated on the heap, You can't even expand an array element in the Watch window. There is a solution to this. You can use (array+ <offset>),<count> to see a specific range of <count> elements starting from the <offset> position (of course, the array here is your actual object). If you want to see the entire array, you can simply use Array,<count>.






If your array is on the heap, you can expand it in the Watch window, but to see the values for a particular range, the usage is slightly different: ((t*) array + <offset>),<count> (note that this usage is also valid for multidimensional arrays on the heap). But in this case, T is the type of the exponential group element.






If you are using MFC, and use one of the ' array ' containers, like CArray, Cdwordarray,cstringarray and so on. You can of course use the same filtering method. In addition, you must look at the M_pdata member of the array, which is the true cache of the saved data.






Tip 5: Avoid entering unnecessary functions



Many times, when you debug your code, you may get into functions you want to skip, like constructors, assignment operations, or something else. One of the things that bothers me most is the CString constructor. Here is an example, when you are ready to step into the take_a_string () function, first enter into the CString constructor.



void take_a_string (CString const &text) {}void test_string () {take_a_string (_t ("sample"));}






Fortunately, you can tell the debugger which methods, classes, or entire namespaces to skip. The way to implement it has also changed, returning to the days of using VS6, usually specified by the Autoexp.dat file. Vistual Studio 2002 was changed to use registry settings. To skip some functions, you need to add some values to the registry (details below):



The actual location depends on the Vistual studio version you are using and the operating system platform (x86 or x64, because the registry can only be browsed under 64-bit Windows) The name of the value is a number, which represents the priority of the rule; the higher the number, the higher the priority level. The value data is the REG_SZ value of a regular expression that specifies how to filter and execute.



To avoid entering any of the CString methods, I added the following rule:






With this, even if you force the take_a_string () in the previous example, the debugger skips the CString constructor.



Tip 6: Start the debugger from code Launch the debugger



You may rarely need to attach a debugger to a program, but you cannot do so in the Attach window (which may not have been captured because of an outage), and you cannot start the program in the debugger at the outset. You can create interrupts in the program to give the debugger an opportunity to attach by calling internal _degbugbreak ().


void break_for_debugging() {
__debugbreak();
}


There are actually other ways to do this, such as triggering interrupt 3, but this applies only to the x86 platform (the C++64 bit no longer supports ASM). There is also the DebugBreak () function, but it is not easy to use, so it is recommended to use an internal method.


__asm int 3;


When the program runs an internal method, it stops running, and you have the opportunity to attach the debugger to the process.












Tip 7: Print in the Output window

By calling Debugoutputstring, you can display a specific piece of text in the Output window of the debugger. If there is no debugger attached, the function does nothing.






Tip 8: Isolate memory leaks

Memory leaks are an important issue in native development, and it is a serious challenge to detect memory leaks, especially in large projects. Vistual Studio can provide reports that detect memory leaks, and there are other applications (free or commercial) that can also help you detect memory leaks. In some cases, the debugger can be used to interrupt when some memory allocations eventually lead to a leak. But you have to find a reproducible allocation number (though it's not that easy). If you can do this, the debugger will not break when you execute the program.

Let's take a look at the code below, allocating 8 bytes, but never releasing the allocated memory. Visual Studio provides reports of objects that cause memory leaks, runs several times, and finds that the same allocation number (341) is always the same.


void leak_some_memory() 
{ 
char* buffer = new char[8]; 
} 
Dumping objects -> 
d:\marius\vc++\debuggingdemos\debuggingdemos.cpp(103) : {341} normal block at 0x00F71F38, 8 bytes long. 
Data: < > CD CD CD CD CD CD CD CD


The steps to break at a specific (reproducible) location are as follows:

Make sure you have enough reporting patterns for memory leaks (refer to using the CRT library to detect memory leaks)
Run the program multiple times until you can find a reproducible allocation number in the memory leak report after the end of the program, as in the previous example (341)
Set a breakpoint at the beginning of the program so that you can break it as quickly as possible.
When the initial interrupt occurs, the Watch window's Name field is displayed: {,, Msvcr90d.dll}_crtbreakalloc, write the location number you want to find in the Value column
Continue Debugging (F5)
The program execution stops at the specified location, and you can use the call stack to be directed to find the code that was triggered by that location.
Following these steps, in the previous example, the cause of the memory leak can be identified using the assigned number (341).






Tip 9: Debug the release version

Debugging and publishing are two different purposes. The Debug configuration is used for development, and the release configuration, as the name implies, is used as the final version of the program, because it must strictly follow the quality requirements of the release, which contains settings for tuning part and debug version of the Interrupt debugging. And, sometimes, debug the release as you would debug a debug version. To do this, you need to make some changes in the configuration. But in this case, you are no longer debugging the release, but debugging and distributing the hybrid version






You should also do something, and here's what you have to do:

Configure C/C + + >general>debug information Format should be "program Database (/zi)"
Config/C + + >optimization>optimization should be "disabld (/od)"
Configuration linker>debugging>generate Debug Info should be "yes/(Debug)"






Tip 10: Remote Debugging

Another important debugging is remote debugging, this is a bigger topic, many times, here I just do a simple summary:

You need to install remote debugging monitoring on the remote machine
Remote debugging monitoring must be run as Administrator and the user must belong to the Administrators group
When you run monitoring, a new service is opened, and the name of the service must be the value of the qualifier combo box of the Visual Studio attach to progress window.









Firewalls on remote and local machines must allow for communication between Visual Studio and remote debugging monitoring



To debug, PDB files are key; To enable VisualStudio to load them automatically, the following conditions must be met:



1) The local PDB file must be available (place a corresponding module under the same path as the remote machine).



2) The managed PDB culture on the remote machine must be available.



Conclusion

Ivan Shcherbakov's article and the debugging techniques I mentioned in this article are essential in most debugging issues.


Related Article

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.