The source code for my Pointless Minesweeper Clone can be found here. Enjoy it.
The license is BSD (you may know this as the "hey, go nuts" license).
The source code for my Pointless Minesweeper Clone can be found here. Enjoy it.
The license is BSD (you may know this as the "hey, go nuts" license).
This is a straightforward fix, but I couldn't find anything about it anywhere else. I have a handful of old ATL projects that have been upgraded over the years from Visual C++ 6.0, through VS2003 and are now being built using Visual C++ 8. I was trying to add them to a deployment project today, and kept running into this error:
Two or more objects have the same target location
('[targetdir]\regsvr32.trg').

The issue is that the way libraries are registered has changed over the various incarnations of Visual Studio. My old projects were still using a post-build step to perform registration:

This apparently can create the output file that the deployment package is complaining about. The fix is to delete the post build steps and enable the modern registration option on the Linker's General tab.

The worst possible way to "handle" exceptions is to show the user a message box with __FILE__ as the text. This is extremely poor form.

Apparently, Intel did not get the memo. Worse, this happens as many as ten times when I open Visual Studio. Why do I feel like I was mistakenly given a debug build of VTune?
I googled around, and couldn't find a generic singleton implementation that was 1) correct and 2) met all of my needs. This is a clever approach, but unfortunately it is limited to objects that are created by calls to constructors.
So I went ahead and wrote the singleton generic that I fully expect to be included in the next BCL. (Not really. It's completely straightforward. However, the Steelers won the super bowl yesterday, so I'm not really in a modest mood.)
I started out defining a class factory type, which is responsible for creating the an instance in a purposefully vague way. I also wrote the default version which just calls new().

/// <summary>
/// Interface for objects that create instances of
/// another type.
/// </summary>
public interface IClassFactory<T> where T : class
{
T CreateInstance();
}
/// <summary>
/// A default <see cref="IClassFactory"/> implementation,
/// which uses a parameterless constructor to create the
/// instance.
/// </summary>
public class DefaultClassFactory<T> : IClassFactory<T>
where T : class, new()
{
public T CreateInstance()
{
return new T();
}
}
From there, I went for the slam dunk in writing both a singleton class with a class factory and a default version that doesn't require one.

/// <summary>
/// A base (or helper) singleton class. Defines the
/// singleton instance.
/// </summary>
/// <typeparam name="T">
/// The type of the singleton object.
/// </typeparam>
/// <typeparam name="class_factory">
/// The type of the class factory to use to create an
/// instance of type <typeparamref name="T"/>.
/// </typeparam>
public class Singleton<T, class_factory>
where T : class
where class_factory : IClassFactory<T>, new()
{
private static object _sync = new object();
private static T _default;
/// <summary>
/// Gets the singleton instance.
/// </summary>
public static T Default
{
get
{
EnsureDefault();
return _default;
}
}
/// <summary>
/// Ensures that the singleton has been created.
/// </summary>
private static void EnsureDefault()
{
if (_default == null)
{
lock (_sync)
{
if (_default == null)
{
CreateDefault();
}
}
}
}
/// <summary>
/// Uses the class factory to create the instance.
/// </summary>
private static void CreateDefault()
{
class_factory cf = new class_factory();
T value = cf.CreateInstance();
// This ensures that writes in the creation of
// the default instance won't be shuffled beyond
// the write to _default. Only matters on multiproc
// machines where the hardware allows this. Does
// nothing on an x86.
Thread.MemoryBarrier();
_default = value;
}
}
/// <summary>
/// A basic singleton type that can be used with objects
/// that are created with a parameterless constructor.
/// </summary>
public class Singleton<T> :
Singleton<T, DefaultClassFactory<T>>
where T : class, new()
{
}
(For more on why I added that call to Thread.MemoryBarrier(), see this writeup.)
Here's a really simple example that does not take advantage of the customizability:
public class Foo : Singleton<Foo>
{
}
If you can't use Singleton as a base class, you have to write a little more code.
public class Foo : Bar
{
public static Foo Default
{
get { return Singleton<Foo>.Default; }
}
}
Recently, Firefox has been maxing out my CPU "when I have more than three tabs open." As is typical with bug reports from users, this one is very poorly worded and essentially useless. It turns out that that was not a good explanation of what was going on. I messed around a little more and figured out that the problem had these characteristics:

I'm not sure if this is some strange interaction of my specific combination of extensions and settings, or if this happens for all Firefox users. This seems like a possible security vulnerability, but I can't say one way or the other.
I suppose I could have downloaded and compiled the source code for Firefox to figure things out, but that was way more effort than I felt like giving. I did managed to debug and fix this issue for myself–without source or symbols–which I think makes for an interesting writeup.
Since the problem was on every page on the website, and continued after the page finished loading, I assumed it had to be a javascript or Flash problem (both of which are abused by ESPN to an irritating degree). I don't even have the Flash plugin for Firefox installed, so that narrowed the scope of my investigation.
The first thing I did was try to debug the Javascript normally; this was hampered by several factors:
To summarize the story to this point, I had a (likely) javascript problem on a page I visit very frequently, coupled with a browser bug that maxed the CPU and made the issue difficult to diagnose through normal means.
I attached to Firefox.exe in Windbg and started randomly breaking in and checking on thread zero while the spike was in progress. Sometimes, frames in the js3250 module were on the stack:
0:009> ~0k ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 0012f97c 6009db8b js3250!JSLL_MinInt+0x45e2 0012f9c8 6009cdd9 js3250!js_GetSrcNoteOffset+0x5358 0012f9f0 600c7c01 js3250!js_GetSrcNoteOffset+0x45a6 0012fa08 600856b5 js3250!js_GetScriptLineExtent+0x39e6 0012fa28 600b036f js3250!JS_NewStringCopyZ+0x44 0012fa40 600b3e93 js3250!js_FindProperty+0x26c5
The information for js3250 confirms (if the module name and the names of the export functions weren't enough for you) that it is the Mozilla Javascript implementation.
0:009> lmv m js3250
start end module name
60080000 600e9000 js3250 (export symbols)
C:\Program Files\Mozilla Firefox\js3250.dll
Loaded symbol image file:
C:\Program Files\Mozilla Firefox\js3250.dll
Image path: C:\Program Files\Mozilla Firefox\js3250.dll
Image name: js3250.dll
Timestamp: Fri Nov 11 20:05:34 2005 (43753FDE)
CheckSum: 00073A1C
ImageSize: 00069000
File version: 4.0.0.0
Product version: 4.0.0.0
File flags: 0 (Mask 3F)
File OS: 10004 DOS Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0409.04e4
CompanyName: Netscape Communications Corporation
ProductName: NETSCAPE
InternalName: JS3240
OriginalFilename: js3240.dll
ProductVersion: 4.0
FileVersion: 4.0
FileDescription: Netscape 32-bit JavaScript Module
LegalCopyright: Copyright Netscape Communications. 1994-96
LegalTrademarks: Netscape, Mozilla
All of this is reasonably good evidence that javascript is the right place to start. I took a look at the exports for js3250 ("x js3250!*" in Windbg) — it appeared as though this module was implemented as a few dozen C-style exports.
I thought that a logical thing to look for was an "execute a javascript function" function of some kind, and there were a few exports named some variation of "Call function."
0:009> x js3250!*Call*Function* 6008541f js3250!JS_CallFunction (<no parameter info>) 60085464 js3250!JS_CallFunctionName (<no parameter info>) 600854ff js3250!JS_CallFunctionValue (<no parameter info>)
I set a breakpoint on all of these.
0:009> bm js3250!*Call*Function* 1: 6008541f @!"js3250!JS_CallFunction" 2: 60085464 @!"js3250!JS_CallFunctionName" 3: 600854ff @!"js3250!JS_CallFunctionValue"
After resuming the program, I started hitting these breakpoints constantly. I did a sanity check and made sure that this didn't occur on a cleaner site (google), and this was the case. I didn't have any immediate success figuring out what script functions were being called. You can dig up the source for these API's if you like, but I'm guessing that the script is already processed into different data structures by the time the javascript engine gets here.
I looked at some of the stacks when these functions were called, and I noticed this pretty far down:
0012fc7c 00534e18 js3250!JS_EvaluateUCScriptForPrincipals+0x70
I hoped this would lead me to some bits of javascript pointed to from nearby locations on the stack, so I set a breakpoint there. When it was hit, I started dumping out strings (using "dda @esp" and and "ddu @esp") and found this:
http://espn-att.starwave.com/motion/fsp/fsp.js
As an only slightly educated guess, I used the Adblock extension to block this script.

After reloading the page, the problem was gone! There don't seem to be any site-breaking problems associated with turning this script off. This is all or part of the "ESPN Motion" business that tries to display sound and video on the site. Hey, ESPN: this is a terrible idea in the first place. Your website shouldn't start yelling at me when I visit it. It's no excuse for Firefox to A/V, but I thought everyone with a three-digit IQ stopped doing this in 1996.
If you find yourself struggling with the following error message in SQL Server Management Studio 2005:
Database diagram support objects cannot be installed because this database does not have a valid owner. To continue, first use the Files page of the Database Properties dialog box or the ALTER AUTHORIZATION statement to set the database owner to a valid login, then add the database diagram support objects.
And you are sure that the database does in fact have a valid owner, check the "Compatibility Level" on the Options page. Make sure this is set to "SQL Server 2005."
alt="SQL Server 2005 compatibility level"/>
Despite some initial bad press, my impression so far is that Visual Studio 2005 is a pretty nice product. I would qualify that by saying that I haven't yet used it to work on a massive web project, and as we all know web projects were definitely Visual Studio 2003 at its worst. (After two years, I will NOT use Visual Studio 2003 for web projects. I refuse. They were broken. I'm 100% text editor and NAnt from the command line now.)
I am loathe to be seen as a cheerleader, and rest assured I could point to many things about Visual Studio in general and VS2005 specifically that I can't stand. But somebody out there deserves some credit for the fact that startup performance seems to have been drastically improved. In my informal test ("One Mississippi .. two Mississippi"), VS 2005 outperforms 2003's startup by an order of magnitude. Two seconds compared to thirty seconds on the same machine. That's certainly nothing to sneeze at.
You click on the icon, it opens. All software should work this way. I'm looking directly at you, OpenOffice, Trillian, and every single product developed by Adobe. While I'm on the subject, never allowing your program to close is not an acceptable solution to this problem.
I am also a fan of this:

The "close all but this" button replaces these steps:
This is a partial debugger trace of an extremely popular and widespread application, used in commercial software by thousands of developers at hundreds of companies including Microsoft. This was happening when the program was functioning normally.
(1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) ModLoad: 5c060000 5c072000 C:\WINDOWS\system32\SRCLIENT.DLL ModLoad: 692c0000 692ee000 C:\WINDOWS\System32\Wbem\framedyn.dll (1230.1234): Unknown exception - code 80010105 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): Unknown exception - code 80010105 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1254): Unknown exception - code 80010108 (first chance) ModLoad: 76bb0000 76bb4000 C:\WINDOWS\System32\SFC.DLL (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): Unknown exception - code 8001010e (first chance) ModLoad: 76bb0000 76bb4000 C:\WINDOWS\System32\SFC.DLL ModLoad: 5c060000 5c072000 C:\WINDOWS\system32\SRCLIENT.DLL ModLoad: 692c0000 692ee000 C:\WINDOWS\System32\Wbem\framedyn.dll (1230.1234): C++ EH exception - code e06d7363 (first chance) (1230.1234): Unknown exception - code 80010012 (first chance)
I had an A/V problem with this utility that I was trying to debug - this was made basically impossible by the fact that the program was continuing after dozens of other access violations. People, you really are not supposed to do this. I won't say what application this is, but I will say that I am not going to be using it in the future.
I came across a JavaScript error today in just about the last place I expected to find one.

I closed the window and reran the wizard a few times, thinking it was a website in another window acting up. Luckily, it appears to only be infecting makefile projects.