10 debugging skills developed by Visual Studio (2): Visual Studio

Source: Internet
Author: User

10 debugging skills developed by Visual Studio (2): Visual Studio

My previous articles on Visual Studio debugging skills have aroused great interest, so I decided to share more debugging knowledge. In the following list, you can see the Native Development debugging skills (followed by previous articles ). These skills can be applied to VS2005 or later versions (of course some of them can be applied to earlier versions ). If you continue, you can learn the details of each technique.

Tip 11: Data breakpoint

When the memory location of the data changes, the debugger will interrupt. However, this is the only way to create a data breakpoint for a hardware such as 4 at a time. Data breakpoints can only be added during compilation. You can use the menu (compile> New breakpoint> new data breakpoint) or the breakpoint window to add data breakpoints.

You can use a memory address or address expression. Even if you can see two values on the stack, I think this function is useful when the value on the stack is changed. This helps identify memory corruption.

In the following example, the pointer value has been changed to the object value. To find out where the changes are made, I set a breakpoint at the position of the pointer value storage, such as & ptr (note that this occurs after the pointer is initialized ). When the data is changed, the debugger terminates when someone changes the pointer value and then finds out which code has caused the change.

Tip 12: rename a thread

When you debug a multi-threaded application, the Threads window displays the created Threads and the current Threads. The more threads you need, the more difficult you will find the thread you are looking for (especially when the same program is executed by multiple threads at the same time, you do not know which thread instance is being executed)

The debugger allows you to rename a thread. Right-click a thread and rename it.

You can also name a thread in programming mode. Although this is tricky and must be done after the thread starts, otherwise the debugger will reinitialize it with its default naming rules, the following functions show how to define and use a thread.

Typedef struct tagTHREADNAME_INFO {DWORD dwType; // It must be two-byte length: LPCSTR szName; // The Pointer Points to the name (the same address space) DWORD dwThreadID; // thread ID (-1 call thread) DWORD dwFlags; // reserved for use, in most cases 0} THREADNAME_INFO; void SetThreadName (DWORD dwThreadID, LPCSTR szThreadName) {THREADNAME_INFO info; info. dwType = 0x1000; info. szName = szThreadName; info. dwThreadID = dwThreadID; info. dwFlags = 0; _ try {RaiseException (0x406D1388, 0, sizeof (info)/sizeof (DWORD), (DWORD *) & info);} _ partition T (prediction_continue_execution) {}}

Tip 13: specify a thread to set a breakpoint

  Another useful technique for Multithreaded Applications is to set breakpoints on specified threads, processes, and even computers. You can use the breakpoint Filer command to implement this function.

The debugger allows you to use different combinations of thread name, thread ID, process name, process ID, AND machine name (using AND, OR, NOT connection ). Mastering how to set the thread name makes this filtering technique easier.

Tip 14: (inaccurate) scheduled execution

In my previous article, I mentioned using pseudo variables in the Watch window. One of the unmentioned ones is @ clk, which displays the value of a counter to obtain the approximate time required for code execution between two breakpoints, in milliseconds (MS ). However, this method cannot be used for configuration program execution. You should use Visual Studio Profiler or performance timer to complete these configurations.

Reset the timer by adding @ clk = 0 in the Watch window or Immediate window. Therefore, if you need to calculate the time required for the last code execution, do the following:

  • Set a breakpoint at the beginning of a code block
  • Set a breakpoint at the end of the code block
  • Add @ clk in the Watch window
  • When the first breakpoint is triggered, enter @ clk = 0 in the Intermediate window.
  • Run the program until the breakpoint at the end of the code block is reached, and view the value of @ clk in the Watch window.

Note that you need to add two expressions in the Watch window: @ clk and @ clk = 0. It is said that the timer can be reset at the position where the breakpoint is executed each time. This technique can only be used in earlier versions of Visual Studio, but cannot be used in later versions of Visual Studio, such as VS2005 (tested by the author and not supported by vs2005) and later versions.

Tip 15: format a number

When you use the Watch or Quick Watch window to view variables, these values are displayed in the default predefined visual format. When a variable is a number, it is displayed in decimal format according to its type (int, float, double. However, you can set the debugger to use different types for displaying numbers, or use different hexadecimal values.

To change the display type of a variable, you can add the following prefix before the variable:

  • By -- unsigned char (unsigned byte)
  • Wo -- unsigned short (unsigned word)
  • Dw -- unsigned long (unsigned double word)

You can add the following prefix before the variable to change the OS:

  • D Or I -- signed decimal number
  • U -- unsigned decimal number
  • O -- unsigned octal number
  • X -- lowercase hexadecimal number
  • X -- uppercase hexadecimal number

Tip 16: Format memory data

In addition to numbers, debugger can also display formatted memory data in the Watch window, up to 64 bytes. You can add the following suffix after the expression (variable or memory address) to format the data:

  • Mb or m-hexadecimal 16-byte data, followed by 16 ASCII characters
  • Mw -- 8 words (WORD, usually 1 WORD = 2 BYTE) data
  • Md -- four dual-words (DWORD, usually 1 DWORD = 4 BYTE) data
  • Mq -- two four-character (Quad WORD) data
  • Ma -- 64 ASCII characters
  • Mu -- 2-byte UNICODE Character

Tip 17: Pause the system DLL call.

Sometimes it is useful to pause a function of a DLL when it is called, especially system DLL (such as kernel32.dll and user32.dll ). To implement this pause, you must use the context operator provided by native debugger. You can set the breakpoint location, variable name, or expression:

  • {[Function], [Source Code], [module]} breakpoint location
  • {[Function], [Source Code], [module]} variable name
  • {[Function], [Source Code], [module]} expressions

The braces can be any combination of the function name, source code, and module, but the comma cannot be omitted.

For example, if we need to pause the CreateThread function call. This function is exported from kernel32.dll, so the context operator should be like this: {, kernel32.dll} CreateThread. However, this is not the case because the operator requires the name after CreateThread. You can use DBH.exe to get the modifier of a specific function (compiled by the compiler ).

The following describes how to get the CreateThread modifier:

C:\Program Files (x86)\Debugging Tools for Windows (x86)>dbh.exe -s:srv*C:\Symbols*http://msdl.microsoft.com/Download/Symbols -d C:\Windows\SysWOW64\kernel32.dll enum *CreateThread*Symbol Search Path: srv*C:\Symbols*http://msdl.microsoft.com/Download/Symbols  index      address   name   1      10b4f65 :  _BaseCreateThreadPoolThread@12   2      102e6b7 :  _CreateThreadpoolWork@12   3      103234c :  _CreateThreadpoolStub@4   4      1011ea8 :  _CreateThreadStub@24   5      1019d40 :  _NtWow64CsrBasepCreateThread@12   6      1019464 :  ??_C@_0BC@PKLIFPAJ@SHCreateThreadRef?$AA@   7      107309c :  ??_C@_0BD@CIEDBPNA@TF_CreateThreadMgr?$AA@   8      102ce87 :  _CreateThreadpoolCleanupGroupStub@0   9      1038fe3 :  _CreateThreadpoolIoStub@16   a      102e6f0 :  _CreateThreadpoolTimer@12   b      102e759 :  _CreateThreadpoolWaitStub@12   c      102ce8e :  _CreateThreadpoolCleanupGroup@0   d      102e6e3 :  _CreateThreadpoolTimerStub@12   e      1038ff0 :  _CreateThreadpoolIo@16   f      102e766 :  _CreateThreadpoolWait@12  10      102e6aa :  _CreateThreadpoolWorkStub@12  11      1032359 :  _CreateThreadpool@4

It looks like the real name is _ CreateThreadStub @ 24. Therefore, we can create a breakpoint, {, kernel32.dll} _ CreateThreadStub @ 24.

When a program is paused, the message about no source code at the breakpoint is directly ignored.

Use the call Stack window to view the code for calling this function.

Tip 18: Load symbols

When you debug a program, the call Stack window may not display all call stacks, ignoring the information of system DLL (such as kernel32.dll and user32.dll.

By loading the DLL symbolic information, you can obtain all call stack information. In the call Stack window, you can use the context menu (right-click menu) to directly set this effect. You can download these symbols from a predefined symbolic path or Microsoft's symbolic server (for system DLL. After these symbols are downloaded and imported to the debugger, the call stack is updated as follows:

These symbols can also be imported from the Module window.

Once loaded, these Symbols are saved in the cache and can be configured in Tools> Options> Debugging> Symbols.

Tip 19: Report Memory leakage in MFC

If you want to monitor memory leakage in the MFC application, you can use the macro DEBUG_NEW to redefine the new operator, which is a modified version of the new operator, you can record the file name and number of rows for the allocated memory. The DEBUG_NEW constructed in Release is parsed into the original new operator.

In the source code generated by the MFC wizard, the # include post-mina contains the following pre-processing commands:

#ifdef _DEBUG#define new DEBUG_NEW#endif

The code above is how to redefine the new operator.

Many STL header files are incompatible with the new operator defined here. If you include header files such as <map> <vector> <list> <string> after the new operator, the following error occurs (take <vector> as an example ):

1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(43) : error C2665: 'operator new' : none of the 5 overloads could convert all the argument types1>    c:\program files\microsoft visual studio 9.0\vc\include\new.h(85): could be 'void *operator new(size_t,const std::nothrow_t &) throw()'1>    c:\program files\microsoft visual studio 9.0\vc\include\new.h(93): or    'void *operator new(size_t,void *)'1>    while trying to match the argument list '(const char [70], int)'1>    c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(145) : see reference to function template instantiation '_Ty *std::_Allocate<char>(size_t,_Ty *)' being compiled1>    with1>    [1>      _Ty=char1>    ]1>    c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(144) : while compiling class template member function 'char *std::allocator<_Ty>::allocate(std::allocator<_Ty>::size_type)'1>    with1>    [1>      _Ty=char1>    ]1>    c:\program files (x86)\microsoft visual studio 9.0\vc\include\xstring(2216) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled1>    with1>    [1>      _Ty=char1>    ]

SolutionDEBUG_NEW is used to re-define the new operator after including these STL files.

Tip 20: Debug ATL

When developing the atl com component, you can view the QueryInterface, AddRef, and Release calls of the COM object in the debugger. By default, these calls are not supported. You need to define two Macros in the pre-processing definition or pre-compilation header file. After these two macros are defined, the call to these functions will be displayed in the Output window.

The two macros are:

_ ATL_DEBUG_QITo display the name of each interface to be queried. It must be defined before the atlcom. h header file is included.
_ ATL_DEBUG_INTERFACESDisplays the number of times the current interface is referenced, the class name, the interface name, and other information when AddRef or Release is called. It must be defined before atlbase. h is included.

The above is all the content of this article. I hope you can learn from the articles you have shared before and master Visual Studio debugging skills.

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.