Archive for the 'Geek Stuff' Category

Curiosity killed the task by e

I was reminded today why two of the traits of a great tester are curiosity and a willingness to share information

We run test cases we run after every build to confirm that the build is good enough for deeper testing. This “Build Verification Test” failed in the lab, and I had already verified that the issue didn’t occur in my local VMWare Workstation image, so it seemed likely that there was something different in how I was testing and the BVT. I went upstairs to the lab to dig into why a particular service couldn’t be removed.

I sat down and got my bearings and was looking over the logs and current state of the machine when Robert, a tester I’d worked with when we were defining and implementing DCOM security settings compatible with Microsoft Windows Server 2003 SP1. He doesn’t usually see me in the lab, and asked what was going on. After a very brief conversation, Robert mentioned that the problem might be related to another issue he’d reported in the same build in which a process sometimes hangs. The two seemed likely to be related since the most common reason that a service won’t uninstall is that it cannot be stopped, and his process and my service are related.

Sure ’nuff, after some quick tests, I was able to confirm that my issue was a side-effect of his issue.

An insecure tester would have declined to offer any information in order to avoid being incorrect or rebuffed.

A merely competent tester would have ignored me and efficiently gone about his or her duties, effectively quelling any curiosity.

Robert saved me several hours of research because he was curious and because he was willing to share information. He not only earned his pay today, he also helped me earn mine, and that’s what teamwork is all about.

June 03 2005 | Geek Stuff | No Comments »

NMAKE – Reversing the error code from findstr or grep by e

If you’re using nmake, you’ll be familiar with this problem… I have logged some process, now I want to check for an error string in the log and terminate my build if it appears, and I don’t want to have to create a .CMD file to do it. The problem is that tools like grep and findstr return a success code when they find something, and that’s the opposite of what we want.

Here’s a quick way to reverse the error code: @findstr “$(TheErrorString)” “$(TheFile)” && exit /b 1 || exit /b 0

This works because. . . && means – Run this command if the previous command completed successfully

|| means – Run this command if the previous command did not complete successfully

June 03 2005 | Geek Stuff | No Comments »

Don’t fix that, I’m using it! by e

Today, a coworker and I were in the restroom washing up after lunch. We were irritated to find that the roll of paper towels was not in the usual place on the shelf. To our chagrin, we discovered that the roll was missing from its familiar place on the shelf because the dispenser was fixed.

People quickly adapt to the situation as it exists. In many cases, we come to prefer the existing, “wrong” state of affairs to the “right” state if the “right” state requires a change in our habits. In religion, we prefer darkness to light (John 3:19-22). Psychology and cultural anthropology students learn about Stockholm Syndrome, and the power of habit. In politics, we continue to elect the same leaders despite our incessant complaints about those same leaders.

The tyranny of the familiar also plays a role in software development and in the paradigm conflict between Open Source Software (OSS) and Commercial Off-The-Shelf Software (COTS).

As Rich Kulawiec said, “Any sufficiently advanced bug is indistinguishable from a feature.” It is not uncommon for the alpha-geek to fix a long-standing bug only to have customers frustrated and annoyed because their business processes had to change or their mission-critical custom feature no longer works.

OSS projects introduce another dynamic. In addition to the up-front impact of implementing a new software package, the very nature of OSS tends to make the software more volatile. As geeks tweak OSS solutions, we break the products’ perceived affordances.The new and improved version may indeed be better, but it is also different. The hallmarks of a successful OSS project, ongoing development and wide-spread adoption, compete against one another. The same buzz of activity that makes the project attractive to geeks can make it unpalatable to the average user.

Product teams without a good understanding of the end-user, a clear vision, and good leadership will be particularly prone to forgetting (or deliberately ignoring) that old and familiar trumps new and different for many users. A good product manager or customer advocate helps to balance “better” against “familiar”, but, ultimately, geeks must become more active participants in this process.

One of the hallmarks of a geek is a love of things that are new and different, but we also display a counterintuitive love of things old and arcane. We find pleasure in the familiar tools, toys, and technologies of yesteryear. We like command-line interfaces, classic arcade game emulators, and stories half a century old. Perhaps we are more like “them” than we would like to think; perhaps there is hope that we may yet learn to relate to our users.

June 01 2005 | Geek Stuff | No Comments »

What Video Game Character Are You? by e

What Video Game Character Are You? I am Kong.I am Kong.

Strong and passionate, I tend to be misunderstood, sometimes even feared. I don’t want to fight, I don’t want to cause trouble, all I ask is a little love, and a little peace. If I don’t get what I want, I get angry, and throw barrels and flaming oil at whatever’s stopping me. What Video Game Character Are You?

May 27 2005 | Geek Stuff | No Comments »

Want to learn CSharp and dotNET? by e

Check out http://www.microsoft.com/events/series/msdnvideodev.mspx, where you can learn C# by writing a game. There are more painful ways to learn a language…

Language is good, but understanding the framework is where it’s at for .NET. Mitch Denny just started a series called “A Class A Day” where he’s going to walk through the .NET Framework 2.0 Classes. Catch up with him (you’re only 4 days behind) and it will be like having a study partner! The first two he comments upon are A Class A Day: System.AccessViolationException and A Class A Day: System.ApplicationContext.

And, of course, you don’t want to forget https://www.microsoftelearning.com/default.aspx, where you can get free access to the US$349 eLearning course “Developing Microsoft ASP.NET Web Applications Using Visual Studio.NET”.

May 27 2005 | Geek Stuff | No Comments »

Best Practices for API Design by e

If your API is insufficient or non-existent then your application data and metadata will become part of your de-facto API. You don’t want that. . . really.

 

Here are some points to consider when designing an API or SDK:

 

  1. Get to know your users. Remember that you are an expert, but you are designing for non-experts. The goal is to make things easy for the user, not to impress them with how smart you are. Simple is king except when it violates the principle of least astonishment.
  2. Get to know your users. Write applications like those your users will create. What do you need from an API in order to implement these applications? Once your API is released, ask for copies of applications your users have created. 
  3. Make common things easy and unusual things possible, but do not allow users to do evil things. Verify preconditions and inputs.
  4. Design for subclassing or prevent it.
  5. Accessor methods, not direct access to data, and Factories, not Constructors.
  6. Define, test, and measure usability.
  7. Get to know your users.

 

Some References: 

May 25 2005 | Geek Stuff | No Comments »

Changing the World for Better and for Worse by e

Who doesn’t love this (unsourced) quote from Margaret Mead: “Never doubt that a small group of thoughtful, committed citizens can change the world. Indeed, it is the only thing that ever has.” It sounds so right, certainly something that we desire to be true, or is it?

Margaret Mead is certainly one of the most influential voices in 20th century American culture. Her “work”, along with the Bloomsbury Group’s ideas and Kinsey’s ”research”, ignited the sexual revolution. (Yes, those are sneer-quotes.) Unfortunately, like Kinsey, Mead’s ground-breaking study has been determined to be not only incorrect, but fraudulent.

The frightening thing is not that a researcher would come to wrong conclusions or tweak results to match a preconceived conclusion. The frightening thing is that our media, with liberty consisting of the right to speak freely and the responsibility to report the truth, was not only eager to swallow their lies, but that even now they cling to them and to the values they espoused. Dr. Martin Orans, Professor Emeritus at the University of California, opens his book “Not Even Wrong” (Harvard University Press, 1983) with the sentence “Occasionally, a message carried by the media finds an audience so eager to receive it that it is willing to suspend all critical judgment and adopt the message as its own.”

In this case, a small group of thoughtful, committed citizens has indeed changed the world. Too bad it wasn’t for the better.

Consider, the impact of Martin Luther, Thomas Paine’s “Common Sense”, Martin Luther King Jr. and the Freedom Marchers, Gates and Allen’s “Microsoft”. Consider the impact of Jesus and His small group of thoughtful, committed citizens upon our world.

For better and for worse, this blade has two edges.

May 14 2005 | Geek Stuff and Jesus Stuff and Leadership and Management | No Comments »

RegEnumKeyEx and RegDeleteKeyEx, Or: Why reading all the documentation for a function is a good idea by e

RegEnumKeyEx seems simple enough. Open the parent key, call RegEnumKeyEx specifying dwIndex=0, then increment dwIndex and call RegEnumKeyEx until you get ERROR_NO_MORE_ITEMS.

There are, however, two caveats in the documentation that are easy to overlook.

Did you notice that the documentation says “Because subkeys are not ordered, any new subkey will have an arbitrary index. This means that the function may return subkeys in any order”? That’s not so bad; we don’t generally need subkeys in any particular order.

Did also you scroll down far enough to catch the caveat “While an application is using the RegEnumKeyEx function, it should not make calls to any registration functions that might change the key being enumerated”? Ohh… now that is annoying. If we’re reading only, things aren’t too bad; the odds of another process or thread getting in our way are pretty slim. It could be unpleasant if another thread or process mucks with one of “our” key’s subkeys. (I haven’t confirmed this… there may be magic that stops a subkey from being deleted while the parent is being enumerated, but I’m only aware of “open” keys being protected.) If we want to delete subkeys, this becomes important.

Say we have this…

HKLM\SOFTWARE\Test
HKLM\SOFTWARE\Test\Sub1\\Data=”Good”
HKLM\SOFTWARE\Test\Sub2\\Data=”Bad”
HKLM\SOFTWARE\Test\Sub3\\Data=”Good”
HKLM\SOFTWARE\Test\Sub4\\Data=”Bad”

And we want to remove all of the Subkeys of HKLM\SOFTWARE\Test that have the string “Bad” in the REG_SZ value “Data”.

We RegOpenKeyEx HKLM\SOFTWARE\Test with KEY_ALL_ACCESS|DELETE rights and use the handle to the open key to start enumerating happily along. We get to Sub2, and realize that it needs to be deleted. Easy enough, call RegDeleteKeyEx(hKey, _T(“Sub2″), KEY_WOW64_32KEY, 0), and continue iterating. Uh oh…

Sometimes we get lucky, but this is where the combination of “the function may return subkeys in any order” and we “should not make calls to any registration functions that might change the key being enumerated” becomes important. The key returned by the next call to RegEnumKeyEx may be the next key in the list, but it is just as likely that we will skip a key or even get the name of the key that we just deleted.

So, to enumerate and delete some subkeys, here are two options.
1. As soon as you find a key that needs to be deleted, set dwIndex back to 0 and re-enumerate all of the subkeys. This is lame and inefficient, but it may also be the best solution in some cases.
2. Build a list of the subkeys that need to be deleted while enumerating, then iterate through that list and delete each subkey by name.

Not rocket science, clearly documented, but still annoying and easy to overlook.

April 22 2005 | Geek Stuff | No Comments »

HRESULTs and Win32 Error Codes Introduction by e

Here’s a quick introduction to HRESULTS and Win32 Error Codes. There are essentially three steps. Get the error, Convert the error, and Look up the error.

Get the error:

  • Read it off the error message (someone else’s code)
  • Read the error from the Event Log (someone else’s code)
  • Call GetLastError() in your code.
  • Add @ERR pseudoregister to your Watch/QuickWatch Window. It will show the value you’d get if you called GetLastError() in your code from this thread.

Convert the error to the right format:

  • Many errors are displayed as decimals, and Win32 Error codes will be reported as a negative number. Drop the negative sign if present, then  convert the number to a DWORD.
  • It can be a bit tricky when the error is displayed as a DWORD. If the code doesn’t return anything helpful look for an 0x80XXYYYY value), try converting the DWORD to Decimal, making the Decimal negative, then converting the negative value back to DWORD
  • Some examples:
    • If our error code is 0×80070005 we’re already in a good format, and can simply look up the error.
    • If our error code is -2147024891, drop the negative and convert to Hexadecimal 0×80070005
    • If our error code  0x7FF8FFFB is reported, convert it to Decimal 2147024891, make that negative (-2147024891), then convert to DWORD 0×80070005

Look up the error:

Once you’ve got the error code, there are a number of methods available to convert that cryptic DWORD to a meaningful string.

  • Use Microsoft Error Lookup. Visual C++ Error Lookup (ERRLOOK.exe) is part of the Visual Studio .NET Tools, and has been included with Visual C++ installations “forever”. If the error code is not a system message, ERRLOOK provides the option of specifying a specific EXE or DLL module to translate the code to a message.
  • From within Visual Studio, type <errorcode>,hr in the Watch or Quickwatch window. This will format the error message as an HRESULT, and display the “friendly” error (e.g. 0×80070002,hr). This same formatting works with the @ERR pseudoregister, so @ERR,hr will format the error code as an error message, killing two birds with one stone by both capturing and translating the result code.
  • To routinely handle errors at runtime in your C++ code, see the MSDN topic.
  • If you’re doing COM Interop with Managed code then you better not need this introduction, but just in case, check out Adam Nathan’s comments and a FormatMessage shortcut tip from shawnfa on the .NET Security Blog.
  • I’m no VB expert, but I understand that if you’re using VB (classic), the LastDLLError property of the Err object is more reliable due to the nature of most VB applications. Francesco Balena implies that LastDLLError may have a significant performance impact.
  • Finally, if you really want to do it the hard way, you can translate it manually. In general, you’re going to get a number like this 0x80XXYYYY. Ignore the 0×80 part for now. What you care about is XXYYYY.
  • XX indicates the system this came from. See WINERROR.H for a complete list, but here are a few common system codes:
    • 8 Windows
    • 7 Win32 (non-Windows Microsoft stuff)
    • 25 HTTP
  • Look up the specific error value (YYYY) in MSDN’s list of system error codesWINERROR.H or your local copy of WINERROR.H. Here are a few of the more common error codes:
    •   0 ERROR_SUCCESS (aka NO_ERROR)
    • 2 ERROR_FILE_NOT_FOUND (err..the file is not present with that name)
    • 5 ERROR_ACCESS_DENIED (insufficient rights)
    • 6 ERROR_INVALID_HANDLE (are you sure that previous call succeeded?)

That’s a wrap, with two final caveats:

  • GetLastError can return unexpected values if system calls are being executed behind the scenes. If the error looks wrong… it might be.
  • Win32 Error Codes aren’t really HRESULTS, so be careful about using macros to check for success or failure. Know your return types and handle them appropriately.

April 18 2005 | Geek Stuff | No Comments »

What is MSPDBSRV.exe, and why is it (not) running? by e

I may be slightly off base here, but here’s what it looks like from my chair…

When you build a binary with Microsoft Visual Studio .NET 2003 and select to generate a program database, a MSPDBSRV.exe process is spawned. MSPDBSRV generates the PDB (and copies it to the output folder?), then stays running until it is explicitly terminated or the system shuts down. In most cases, you can completely ignore MSPDBSRV.exe and MSPDB80.dll and MSPDBCORE.dll that support it.

If you routinely use multiple versions of the Visual Studio compiler, you may run into occasional difficulties with MSPDBSRV. The error condition is usually accompanied by a “Fatal Error C1902″. A quick search of the MSDN Library indicates that this error means “A program database file (.pdb) was created using a newer version of DBI.dll than the one found while compiling. Install the latest version of DBI.dll on your system.” Unfortunately, that isn’t terribly helpful since DBI.dll appears to have been deprecated.

The two errors I have encountered are:

ERROR: MSPDB80.DLL: unable to connect: unable to spawn mspdbsrv.exe (0×80070002)<C:\Projects\foo\foo.cpp> : fatal error C1902: Program database manager mismatch; please check your installation

This may indicate that MSPDBSRV.exe is missing, corrupt or not in the same path as MSPDB80.DLL (which apparently launches mspdbsrv.exe). Look up the error code (that’s the 0×80070002 in this example) to see what’s going on here.

Fatal Error C1902 program database manager mismatch; please check your installation

This may indicate that your PDB was created using a newer version of MSPDBSRV.

  • In most cases, a full rebuild (clean and build) will resolve this.
  • Occasionally (ok, once), I had to manually stop the MSPDBSRV.exe that was running, then rebuild.
  • If you’re pulling multiple versions of the VC compiler out of a source control depot or from an archive (you do archive your tools along with your source code when you escrow your code, right?) and are re-using the same location, or if you recently updated the VC compiler you are using, it is possible that MSPDBSRV.exe was running at the time you did the copy. Kill the MSPDBSRV.exe process, re-copy MSPDB*.*, and try again.

April 18 2005 | Geek Stuff | 1 Comment »

« Prev - Next »