Personal tools
User menu

Knowledge Base/Tools/Microsoft Visual Studio

From Thalesians

Jump to: navigation, search

Contents

Enabling guides

This advice comes from Ilya Ryzhenkov's blog.

Many IDEs, such as Eclipse, enable you to visualise the right margin, so that you know when your code lines are becoming too long. In Visual Studio this feature is hidden and you have to use regedit to edit the registry to enable the so-called guides.

  • Start > Run > regedit.
  • Open the HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Text Editor key (or HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Text Editor, depending on your version of Visual Studio).
  • Create a new String Value and name it "Guides" (no quotes).
  • Set its value to something like "RGB(192, 192, 192) 75" (no quotes). Here the triple (192, 192, 192) specifies the colour of the guide, 75 specifies that the guide will appear after column.
  • Restart Visual Studio.

You should see something like this:

Guides in Visual Studio 2005

Note. You can enable more than one guide. You should use commas as separators, e.g. "RGB(192, 192, 192) 45, RGB(192, 192, 192) 75, RGB(192, 192, 192) 80".

Enabling detailed compiler logging

Visual Studio 2005

The build process produces a log file, BuildLog.htm, normally under the Output Directory. It is possible to change the level of detail that it contains. In the menu select Tools > Options > Projects and Solutions > Build and Run. Set the "MSBuild project build output verbosity options" to the verbosity level of your preference ("Quiet", "Minimal", "Normal", "Detailed", or "Diagnostic"). I usually set this option to "Diagnostic".

Visual Studio 6.0

In the menu select Settings > Compiler and Debugger > Other and adjust "Compiler Logging".

Checking which symbols a DLL exports

There is a useful utility

"C:\Program Files\Microsoft Visual Studio 8\VC\bin\dumpbin.exe"

which may be located elsewhere, depending on where your Visual Studio is installed. If you see the following message when you try to run it:

This application has failed to start because mspdb80.dll was not found. Re-installing the application may fix this problem.

then you may have to set your working directory to

"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\"

where mspdb80.dll resides (or change your PATH accordingly) and run dumpbin.exe again.

Typically, you would run dumpbin.exe like this:

dumpbin /exports vssln.dll

And the output will look something like this:

Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file vssln.dll

File Type: DLL

  Section contains the following exports for vssln.dll

    00000000 characteristics
    4571405B time date stamp Sat Dec 02 08:59:07 2006
        0.00 version
           5 ordinal base
           7 number of functions
           7 number of names

    ordinal hint RVA      name

          7    0 0000D2E5 CreateStructuredFileIO
          8    1 0000A638 DllCanUnloadNow
          9    2 0000A644 DllGetClassObject
         10    3 0000A649 DllRegisterServer
         11    4 0000A64E DllUnregisterServer
          5    5 0000A656 VSDllRegisterServer
          6    6 0000A667 VSDllUnregisterServer

  Summary

        1000 .data
        2000 .reloc
        3000 .rsrc
       18000 .text

Thus we know, for example, that vssln.dll is exporting a symbol (a function in this case) called CreateStructuredFileIO.

Ensuring that your DLLs export the right symbols

We have already discussed dumpbin.exe. You can use it to check that the DLLs that you have authored export the right symbols.

But if try

dumpbin /exports C:\path\to\My.dll

and see something like this:

Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\path\to\My.dll

File Type: DLL

  Summary

        1000 .data
        1000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text

then you know you are not doing anything in terms of exporting.

Here is a way to fix this.

Make sure that your DLL project has a *.def file. If not, File > New > File and add something like My.def.

This file should look like this:

LIBRARY	"My"

EXPORTS
    MyExportedFunction1
    MyExportedFunction2

and so on.

Also don't forger to tell your linker about the My.def. Go to Project > Properties. Select Configuration Properties > Linker > Input and set "Module Definition File" to "My.def" (unless the IDE has already done this for you). Rebuild.

Next time you run dumpbin.exe on that DLL you should see something slightly more meaningful, like

Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\dev\fx\ReorderReportsFix\CFXAnalytics\Release\CFXDebugVisualStud
ioAddin.dll

File Type: DLL

  Section contains the following exports for CFXDebugVisualStudioAddin.dll

    00000000 characteristics
    4A802D25 time date stamp Mon Aug 10 15:22:29 2009
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001060 MyExportedFunction1 = ?AddIn_SystemTime@@YGJKPAUtagDEBUGH
ELPER@@HHPADIK@Z (long __stdcall AddIn_SystemTime(unsigned long,struct tagDEBUGH
ELPER *,int,int,char *,unsigned int,unsigned long))

  Summary

        1000 .data
        1000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text

Jumping to the next statement to be executed when debugging

Very often you end up looking at other source files when debugging only to return to the statement to be executed next. You can either right-click on the editor window and select "Show Next Statement" in the pop-up window or, which is quicker, press [Alt]+[Num *].

Going to definition — and back

Thanks to LukeH for posting this on his blog: http://blogs.msdn.com/lukeh/archive/2007/06/04/f12-go-to-definition.aspx

[F12] is an extremely useful key in Visual Studio. It invokes the "Go To Definition" (GTD) command, which works on types, members, locals, range variables, etc. It uses the compiler's external understanding of the code to make sure that it takes you to the right line, even when there are many overloads or if your code is using a lot of type inference.

Very often you may feel like going back to the place where you pressed [F12]. In this case you should use [Ctrl]+[Shift]+[8].

Apparently, in Visual Studio 2008, this has become [Ctrl]+[Shift]+[F12].

Alternatively, you can use the navigate buttons, which you may or may not be able to see on the toolbars. We discuss them next.

Discovering the "Navigate" buttons and keyboard shortcuts

Screenshots VisualStudio NavigateButtons.jpg

These buttons help you jump to the previous or next location in the code that you have visited, very useful in conjunction with [F12].

It may well be the case that your Visual Studio is configured in such a way that these buttons are missing.

Click on the little arrow to the right of the toolbar that you are using. Then select Toolbar Options > Add or Remove Buttons > Customise. In the resulting window select the "Commands" tab and from the "Categories" list select "View". Drag "Navigate Backward" and "Navigate Forward" from the Commands list onto your toolbar.

The keyboard shortcut for Navigate Backward is [Ctrl]+[-]; the shortcut for Navigate Forward is [Ctrl]+[Shift]+[-].

For more information, see Coding Horror: Programming and Human Factors by Jeff Atwood: http://www.codinghorror.com/blog/archives/000315.html

Reappearing breakpoints in Visual Studio: pending breakpoints versus bound breakpoints

This is based on the explanation given by Andrew Hall: http://207.46.153.62/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=476744

You may have encountered the situation when you remove a breakpoint in Visual Studio 2005 by clicking on the red circle on the left margin only to see it reappear in your debugging session.

There is a difference between the so-called bound breakpoints and pending breakpoints. When your shared code is accessed from more than one piece of generated code the breakpoint you initially set in the code editor is a pending breakpoint. Once you begin execution, everywhere that line of code is loaded the debugger creates a bound breakpoint. The top level breakpoint you see in the breakpoints window (Debug > Windows > Breakpoints) is the pending breakpoint and its children in the tree view are the bound breakpoints. You should not see multiple breakpoints when you are in edit (not debug) mode. If the debugging session has not terminated you will delete the bound breakpoints by clicking on the circles in the left margin; you won't delete the pending breakpoints. To delete the pending breakpoints either wait for the debugging session to terminate or use the breakpoints window.

Linking in and using DLLs

These instructions apply to Visual Studio 2005 but they should be applicable to many other versions with minor modifications.

First, DLLs rarely come on their own. They come with *.h headers. So if you are using them, you must tell your C++ compiler about these headers. Right-click on the project in Solution Explorer, select "All Configurations" from the "Configuration:" drop-down list. Go to Configuration Properties > C/C++ > General. Edit the Additional Include Directories. You can click on the "..." button to edit the list of Additional Include Directories, one path per line. In our case, we had to add

  • "I:\dev\apache-log4cxx-0.10.0\src\main\include\"

to this list.

Say you want to link in a DLL into your project, such as log4cxx.dll. Typically, the DLLs are supplied in two flavours: the Debug configuration flavour and the Release configuration flavour. Your project settings also come (typically) in two flavours, Debug and Release.

So you should use the Debug DLLs with your Debug configuration and the Release DLLs with your Release configuration.

Now, what are the steps?

Right-click on the project in Solution Explorer, select Properties. From the "Configuration:" drop-down list select "Debug".

Under Configuration Properties > Linker > Input edit the Additional Dependencies. You can click on the "..." button to edit the list of Additional Dependencies, one path per line.

We added the following line:

  • I:\dev\apache-log4cxx-0.10.0\projects\Debug\log4cxx.lib

Notice that we added a *.lib, not a *.dll. And that's correct. When you create a DLL, a small static import library is created which contains the functions that you have exported. You have to add this *.lib to the link command. Adding it to Additional Dependencies will do the trick.

Don't close the Property Pages dialog box just yet. From the "Configuration:" drop-down list select "Release". Repeat the above steps only specifying the Release version of the lib-file this time, in our case

  • I:\dev\apache-log4cxx-0.10.0\projects\Release\log4cxx.lib

Now click "OK".

You can now try running your project that uses log4cxx.dll. From the menu, select Debug > Start Without Debugging.

Chances are you will see a dialog box with title like "proto-log4cxx.exe - Entry Point Not Found" and a message "The procedure entry point ??1?$ObjectPtrT@VLogger@log4cxx@@@helpers@log4cxx@@UAE@XZ could not be located in the dynamic link library log4cxx.dll".

The reason for this is that you have told the linker about the lib-file, but at runtime the DLL cannot be found. This is easily resolved by copying the Debug version of the DLL, in our case,

  • I:\dev\apache-log4cxx-0.10.0\projects\Debug\log4cxx.dll

to

  • I:\dev\proto-log4cxx\proto-log4cxx\Debug\

and the Release version of the DLL

  • I:\dev\apache-log4cxx-0.10.0\projects\Release\log4cxx.dll

to

  • I:\dev\proto-log4cxx\proto-log4cxx\Release\

Alternatively, the DLL can be added to your PATH.

Note

Rather than telling the linker the full path to the lib such as I:\dev\apache-log4cxx-0.10.0\projects\Debug\log4cxx.lib, we could have split it up.

We could have added I:\dev\apache-log4cxx-0.10.0\projects\Debug under Configuration Properties > Linker > General > Additional Library Dependencies while specifying log4cxx.lib under Configuration Properties > Linker > Input > Additional Dependencies.

Note that in this case we could have used the same setting for Configuration Properties > Linker > General > Additional Library Dependencies in both the Debug and Release modes.

Debug Assertion Failed! _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

In some circumstances, particularly when you delete[] memory, you may face

Debug Assertion Failed!
Error: dbgdel.cpp
Line 52

Error: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

This problem affects both Visual Studio .NET 2003 and Visual Studio .NET 2005.

Here is, in our experience, the most common reason for this: you are mixing /MD and /MDd libraries.

Also, if you are using DLLs, make sure that your Debug configuration is running with Debug DLLs and your Release Configuration is running with Release DLLs (you may need to register them manually).

Why does this happen? When you build your application for the Debug configuration (more specifically, when you have _DEBUG defined), the compiler uses a debug version of the memory allocation and deallocation functions. You cannot allocate memory with the release version and deallocate this memory with the debug version.

See http://msdn.microsoft.com/en-us/library/974tc9t1%28VS.71%29.aspx for more information.

  • This page was last modified on 16 September 2009, at 13:59.
  • This page has been accessed 33,101 times.