22 October 2010

Edit.ConvertTabsToSpaces

Visual Studio has a command on the default Edit menu - Edit | Advanced | Untabify Selected Lines - which one would think allows you to, you know, untabify the selected lines by converting *all* tabs in the selection to spaces.

However, this command only converts leading and trailing tabs to spaces: not adequate.

It turns out - as documented on Sara Ford's excellent blog of Visual Studio tips and tricks - there is a command which does exactly what I want: Edit.ConvertTabsToSpaces.

I bound this command to a toolbar button as well as a keyboard shortcut - - and all is right with the world again.

03 February 2010

Service debugging and development

I came across two good posts from Larry Osterman on service debugging:
I also found a great reference on services in an older book by Jeffrey Richter and D. Jason Clark:

08 December 2009

Figuring out what's running in all those svchost instances

tasklist /svc /fo list

If you're using Sysinternals's Process Explorer, just hover over a svchost instance to see what it's hosting.

You can't drill down into the individual services, but that should help track down errant services which are consuming lots of CPU and/or memory.

Taken from this CodeProject thread in The Lounge.

01 December 2009

Handling meetings

Business meetings are almost always a waste of time, and this is usually because like so many other business activities, there is no process, no structure. However, we are engineers and we can fix things and make them better, so let's see what we can do with meetings.

Every meeting must have an agenda. Seems like a simple enough idea, but most meeting notices consist of a subject, a time, a place, and a list of attendees. An agenda is usually absent. Although you might be tempted to simply turn down agenda-less meeting requests with a curt "No agenda." response - as I have done on occasion - it is usually better to tentatively accept the meeting and send a polite response asking about the agenda. Eventually, people will get the idea.

Every meeting must have a scribe. Again, this seems obvious, but what usually happens is everyone takes their own notes (if they take notes at all; more on this below) and everyone has a Rashomon-like perspective on what was discussed and what decisions were made. The scribe should mail out meeting minutes (or email a link to their location in the wiki or SharePoint) as soon as possible once the meeting ends.

Every meeting should result in one or more action items. The purpose of a meeting is usually to resolve issues or bring all the attendees into alignment on a particular topic. If the meeting is purely informational, you probably shouldn't have it: instead, email a link to a document or video containing the information you would have shared. If the meeting is to resolve issues, every issue should have one or more action items, and each action item must have an attendee's name attached to it. You can't assign action items to people who didn't attend, and you can't assign action items to a group of people.

A digression on "we": I read something recently where someone outlawed the use of "we" in meetings, because "we" never get anything done.

20 November 2009

Checking in code

Good practices when checking code into version control:
  • integrate before you check in to minimize the possibility of breaking the build. A frequent mistake is forgetting to add new files, so having a second workspace just for verifying changelists might help you catch the files you need to add for the build to succeed.
  • minimize the number of files which go into each change list. Small changes are easier to understand, merge, and roll back if necessary. Also, each change list should correspond to a single item in the issue tracking system. You are using an issue tracking system, right?
  • diff each file to make sure you're checking in only what you want to. You don't want that test code you added while debugging creeping into the source. Give yourself a gold star if your process includes code review before new code is added to the baseline.
  • provide check-in comments which actually describe the change(s). That is, instead of a useless comment like "Fixed crash", provide a comment like "Fixed the Foobar ctor to check the spizzbot pointer."
  • if the check-in is a bug fix, make sure you check in a test. You are using a unit test framework, right?
  • do not leave your workplace right after you check in code. Hang around long enough to verify you haven't broken the build and all the tests pass.
Addendum: a good practice every once in a while is to rename your local copy of the source, get a fresh tree, and "build the world" to make sure you have everything.

In fact, this is exactly what your build server or continuous integration server should be doing: no build should implicitly depend on artifacts from another build.

10 October 2009

Setting up the debug memory allocator for native code

This post covers how to set up the debug memory allocator for native code. After following these steps, you will be able to see all your memory leaks tagged with a filename and line number, allowing you to double-click on the error message in the output window and go directly to the spot where the leaking memory was allocated.

First, you need to turn on the debug memory allocator to catch all calls to malloc(), free(), etc. C++ requires a little extra work to catch all calls to operator new, which I'll explain in a bit.

Place the following block in "stdafx.h" or a similar file included by all modules in your project or solution:



#ifdef
_DEBUG

    // Turn on the debug memory allocator with filename and line number trace.

    // This catches all memory leaked via malloc() et al.

    #define _CRTDBG_MAP_ALLOC

    #include <stdlib.h>

    #include <crtdbg.h>

 

    // Map operator new into the debug memory allocator. This requires all

    // modules to define THIS_FILE, which is a good thing because it lets us

    // know when we have a module which is *not* being tracked by the debug

    // memory allocator.

    #define DEBUG_NEW new(_NORMAL_BLOCK, THIS_FILE, __LINE__)

#endif

 


The standard debug memory allocator only tracks calls to malloc(), free(), etc., so you need an extra step to track calls to operator new. In each C++ module, add the following block of code:


#ifdef _DEBUG

    #define new DEBUG_NEW

    static char THIS_FILE[] = __FILE__;

#endif


Finally, in your main() or WinMain(), add the following line of code as near the beginning as possible:


    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


Please comment if you have any questions.

27 July 2009

Building and running ActiveX Control Test Container on x64

I'm currently running Windows 7 x64 Ultimate RC* on my notebook, and I needed to build an ActiveX control for a prototype at work.

Using ATL and the wizards in Visual Studio 2008 to generate the initial control took about a minute, but then I realized I didn't have the ActiveX Control Test Container in the list of external tools in my tools menu.

I searched my system for tstcon*.* but found nothing.

After a brief search, I turned up a thread at Channel 9 discussing this very issue, and it turns out the source for the ActiveX Control Test Container is in a zip file.

On my system, the zip file is

C:\Program Files (x86)\Microsoft Visual Studio 9.0\Samples\1033\AllVCLanguageSamples.zip

and the source for the ActiveX Control Test Container is in

C++\MFC\ole\TstCon

inside the Zip file.

I extracted and built the code (Release x64) but the application wouldn't run, failing with a SideBySide error in the Application log in Event Viewer.

A further search turned up a solution: disable the Enable User Account Control (UAC) linker flag for both the support DLL and the application.

I updated the thread at Channel 9 with this information as well.

I'm going to experiment a little bit and see if I can run both 32- and 64-bit versions of controls in 32- and 64-bit containers, respectively: I may need to do a little reading up on WoW64 to see what the issues are.

* 10 days to RTM!