Knowledge Base/Tools/Microsoft Visual Studio
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:
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.
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.
