Monday, June 25, 2007

Microsoft patent (un)happiness

Microsoft is out to make money. As are most businesses. Money is required for the basic essentials of life and I personally believe Open Source cuts into that. Until food, clean water, shelter, and clothing are free for everyone, Open Source is a great idea in principle but a bad idea in practice. The only thing you can do to make money off of Open Source is to turn it into SaaS...but how long can that model _really_ hold up? Making Linux and Linux-based products easier and easier to install (e.g. Ubuntu, OpenOffice) makes it more available to the masses and IT folk to do it themselves but if a person can't eat, drink, sleep, and they can't afford clothes (naked?) it worth it?

I don't have the answer to the question. Most programmers don't think about what effect their software will have on other people. Will developing for Open Source eventually cause all software developers everywhere to eventually lose their jobs? That's a loaded question but one that crosses my mind often. I use Open Source projects under Windows: FileZilla, TortoiseSVN, Subversion, Thunderbird, Firefox, and others. There are non-free products out there as well. Am I contributing to someone losing their job because I'm using Open Source?

Until someone figures out how to eliminate money from being required for the basic necessities of life, developing for Open Source, as a business model, is not viable. Microsoft is trying to kill off Open Source because they realize this and are trying to save millions of jobs in the process. The way they are executing it isn't exactly kosher, but can you blame them? I can't and I usually have something bad to say about Microsoft.

If you want your comment to get through on this post, it needs to contain the solution to the problem of money. Eliminate money (and all forms of trade) and Open Source becomes viable. I already know the solution but executing it is going to require 2,000 people, 5 years, and (ironically) $42 billion (US).

Tuesday, June 19, 2007

How to get squish just like grape

When the other shoe drops... is going to hurt. A lot.

So this guy wrote a pretty popular add-in for Visual Studio .NET called TestDriven.NET. I've actually heard about this add-in prior to the whole mess he has currently got himself into so it is definitely popular.

Summary of how it has gone down thus far:

1) Developer creates add-in for VS.NET via COM because a VSIP license is expensive. Nothing in the EULA explicitly prohibits it.
2) People like the add-in and it becomes popular.
3) Microsoft gives him MVP status and then discovers the add-in works for VS.NET Express and asks author to remove support for Express.
4) Author refuses.
5) MVP status is revoked.
6) Author adds support for VS.NET "Orcas" Express.
7) Microsoft legal makes its move.

Frankly, VS is Microsoft's intellectual property, not the developer's. However, there are two parties at fault here:

1) Microsoft is at fault for leaving add-in COM support enabled in VS.NET Express. By doing so they left the door wide open for add-ins to function even though that wasn't their intention.
2) However, the developer is also at fault for not removing Express support from his product when Microsoft requested it. Microsoft only turned nasty after the developer refused.

The author shot himself in any legal foot he potentially had when he specifically added support for "Orcas" Express - a version of VS that isn't even out yet. To say publically that he had to add support means it wasn't working for some reason. That's all Microsoft legal needs to squash him like a bug. Or a grape.

Microsoft is out to make a profit. Anything that reduces sales for them is a thorn in their side to be removed. Going against Microsoft without billions of dollars in backing is about the stupidest thing anyone can do. Standing on principles alone is dumb - sure people are cheering, egging him on to go up against the software giant. But David was a slingshot expert when he went up against Goliath. That developer is winging it with almost no knowledge of the law - he'll have to be the luckiest person alive to just survive the onslaught that is coming let alone have any hope of winning. There is no backing out now either...he ensured himself of that when he included support for "Orcas" Express.

Let this be a lesson to all of you developers out there. Be smart. Don't do stupid stuff. Don't become the grape. Or if you do, figure out the fastest way to roll down the nearest storm drain to avoid being squished.

Why Windows Error Reporting (WER) does not work

If you are reading this, you are probably coming from the CubicleSoft website to learn more about Windows Error Reporting. This blog entry will thus be a little more professional as a result.

Windows Error Reporting, or WER for short, is a set of technologies Microsoft put together for Windows XP and expanded upon for Windows Vista:

To summarize the Wikipedia article, WER gathers error reports in a central location (Microsoft servers) and developers of software then can log into the system and retrieve those error reports and thus fix bugs. End-users of Windows see something like this when the application crashes:

The user clicks the "Send Error Report" and the bugs get fixed.

The official website of Windows Error Reporting (WER):

All that sounds good in writing until developers start reading the "fine print" on what is required. By default, applications are not WER enabled. That means the WER data sent by the user is completely ignored by the WER system (i.e. information about the crash simply gets thrown out). One would think every software author would be on board with this WER thing.

So, what exactly does it take to integrate WER? First and foremost, to just gain access to the system requires a Verisign Class 3 Digital ID. That costs $400 [US] per year. That staggering pricetag alone causes most developers to be unable to join the WER program in the first place.

Secondly, once a developer gains access to the system, they discover they have to modify their source code. Significantly. Windows Error Reporting requires integration with various Windows APIs and many of them are quite difficult to use correctly. When used incorrectly (easy enough to do so), wrong information about the crash can be sent, or in the worst case, cause a second crash to occur.

Lastly, the developer has to create two installers: One being the usual release. The other containing the release plus the release's PDB files. A PDB file is used by a debugger to tell where in the original source code the program is at when debugging the program. Without the proper PDB files, the developer can't use any crash reports.

Those are just the steps to integrate WER. It is a huge undertaking and quite expensive. But that's just the start. Just integrating WER isn't enough. The developer has to "baby-sit" WER. Here's why: The WER system only tallies crashes until it is told to start collecting data for a specific crash. Only once WER has been to start collecting data does it do so. Until it is told to collect data, when the user hits the "Send Error Report" button, the error data is simply ignored.

Once the developer finally retrieves data from WER, the data is just a stack/variable dump and whatever information they put into their software to pass onto WER. There is a very good chance that the data will be completely useless. Could be anything from a bad PDB/EXE matchup, to a bad stack dump, to threading issues, to not having the necessary symbols for some system binary not available to the developer, to not knowing what the user was doing at the time, etc. Probably something along the lines of a 75% failure rate.

Despite these huge hurdles, some non-Microsoft companies DO use WER. Off the top of my head, Valve Corporation uses it in their Steam client. Their games still crash and, well, the bugs haven't been fixed yet. Microsoft uses WER for their own products and actually fix bugs, but that's about the only exception.

The end result is that no one sends error reports to the Microsoft WER server mostly because people have figured out that doing so is a waste of time. Now you know why it is a waste of time.

Hopefully I didn't go too far over your head with this blog entry. I did get kind of technical but if you came here from CubicleSoft, you wanted to learn more about WER. The Crash Reporting Support Tool that is used by CubicleSoft bypasses WER and sends error reports directly to my inbox. It is an elegant solution that does not have the problems WER has and it actually works!

Wednesday, June 13, 2007

And out of the blue...a job offer...

Out of the blue I received today in my in-box (just now checking my e-mail - yes I'm still running on empty in terms of sleep) a job offer from Google. Well, not an offer per se, but somehow, somewhere I made a significant impression.

The amazing thing is that I haven't sent my resume anywhere. In fact, it is sorely out of date - been busy with the whole CubicleSoft thing. A Google Internet recruiter came to me. Could have been the article I just put up on CodeProject, but who knows? (Maybe I'm more important than I think I am...don't let that go to my head now :P ).

I'm not going to do anything about it today. I'm too tired. And likely to royally mess up something I'd be smacking my head against a brick wall over for the next 10 years. Best to get some sleep first before doing or saying anything I'll regret. Amazingly enough, I'm still pretty lucid.

UAC: The Definitive Guide

I'm operating on zero sleep in the last 24 hours as I write this. So I'm going to keep this short. I just finished publishing a new article on on Vista UAC. I call it the definitive guide because it combines every last bit of knowledge I've got on Vista UAC elevation, provides a really cool package called Elevate, and, well, it is everything a software developer needs to know about UAC and its quirks and workarounds...without having to spend weeks on hunting down the information:

Plus it is by an author of a book called Safe C++ Design Principles. Oh wait. That's me. I must be tired.

While you are reading the above article, be sure to listen to:

Saturday, June 09, 2007

Solving pesky LNK2005 errors...

For those who read this blog and aren't technically inclined or simply don't use Microsoft Visual Studio (e.g. you use a different compiler suite), this entry isn't for you.

One of most annoying things to run into in Visual C++ are linker errors. They are obtuse, poorly documented, and double-clicking them doesn't take you to the source code (or the part of the object file) where the problem is occurring. One of the most confounding error messages is the LNK2005 error message. Usually something like this shows up:

nafxcwd.lib(afxmem.obj) : error LNK2005 ...something about operator new/delete goes here...

If you search Google, a Microsoft Knowledgebase (KB) article pops up (KB148652):

A lot of people run into LNK2005 errors, find the above article, try out what it says, and discover the "solution" makes the problem worse, not better. That is the only KB article I've ever seen that provides an incorrect solution for a problem...usually Microsoft is pretty good about giving right answers.

There are four causes of LNK2005 errors that I've run into and actually fixed:

1) A bad build. For some reason or other VS just occasionally barfs. The solution in this case is to close down VS, wipe all the temporary files (e.g. .obj, .dll, .exe, autogenerated MIDL .c files, etc.), load up VS, and do a Build->Clean Solution, Build->Rebuild Solution. Depending on the size of your solution, this can take a while - go grab a coffee.

2) If it still fails with LNK2005 errors, then something is mismatched. Right-click on each of the projects and select "Properties...". Then make sure the "'C++'->Code Generation->Runtime Library" all say the exact same thing. If you attempt to use different runtime libraries, it may or may not link properly. The reason it will not link is if you allocate memory in one project and then pass it to another project and free it there (sort of like DLLs but weirder). If you are like me and have projects shared between solutions, you will want multiple project compilation types so that you don't have problems with linker errors (I have 6 of 8 possible for my base library - the base library is multi-threaded - I say 8 possible because you have /MD[d] with MFC, which is different than /MD[d]). Once you have types matching (don't forget to match the "use MFC" option if you use MFC!), make sure both debug and release mode are configured correctly with the configuration manager (Right-click on "Solution 'solutionname' (x projects)" and select "Configuration manager..."). Also, make sure the dependencies and build order are correct (same right-click menu but "Project dependencies..." and "Project build order..." instead).

3) If you've done all that and still get LNK2005 errors, then you've hit a scenario I like to call the "duh" scenario. An incorrect entry point for the subsystem selected will raise a LNK2005 error message. So, if you defined main() and don't use /SUBSYSTEM:CONSOLE, you'll get a LNK2005 error. Or if you defined WinMain() and don't use /SUBSYSTEM:WINDOWS, you'll get a LNK2005 error. Again, this doesn't always happen, but when it does it is weird (usually complains about new/delete duplications across object files instead of main()/WinMain()). To change the subsystem, right-click on the startup project and select "Properties...". Then go to Linker->System->SubSystem. Change accordingly to the entry point used.

4) If, even after all that you still get LNK2005 errors, then it is time to scratch your head and think, "Gee, did I or any third party put in any include files that force .lib files to be included in the linking stage?" Start scouring that source code for any #pragma comment(lib, ...) statements. This happens particularly with MFC libraries since there is code floating around out there that forces the MFC libraries to be linked in at link time first and then forces the other libraries to be excluded - including such code with a non-MFC project causes all sorts of headaches since the other libraries are loaded first and thus can't be excluded by the #pragma and then the MFC libraries attempt to get linked in and fail. But it can happen in other cases as well - even indirectly via a third-party library.

I've never experienced this, but according to what people say on the Internet, when they run into LNK2005 errors, they completely rebuild all of the projects in their solution from scratch (i.e. brand new .sln and .vcproj files). It would take me several days to do that, so that is not an option for me. But apparently it can work. My guess: They implicitly did #1 and #2 by taking that approach - only it took way longer than necessary.

A lot of people suggest turning on /VERBOSE in the linker options. In my experience, that rarely helps to do anything but create more confusion. The option exists, so it is probably useful in some cases.