dotnet, ndepend comments edit

NDepend is awesome and I use it to analyze all sorts of different projects.

One of the nice things in NDepend is you can define queries that help qualify what is your code (JustMyCode) and what isn’t (notmycode).

I’ve seen two challenges lately that make rule analysis a bit tricky.

  • async and await: These generate state machines on the back end and NDepend always flags the generated code as complex (because it is). However, you can’t just exclude the code because basically the generated state machine moves your code in there, so excluding the state machine will exclude some of your code.
  • Anonymous types: I see these a lot in MVC code, for example, where the anonymous type is being used as a dictionary of values to truck around.

I haven’t figured out the async and await thing yet… but here’s how to exclude anonymous types from the JustMyCode set of code:

First, in the “Queries and Rules Explorer” window in your project, go to the “Defining JustMyCode” group.

Defining JustMyCode

In there, create a query like this:

// <Name>Discard anonymous types from JustMyCode</Name>
notmycode
from t in Application.Types where
t.Name.Contains("<>f__AnonymousType")
select new { t, t.NbLinesOfCode }

Save that query.

Now when you run your code analysis, you won’t see anonymous types causing any violations in queries.

windows comments edit

I develop using an account that is not an administrator because I want to make sure the stuff I’m working on will work without extra privileges. I have a separate local machine administrator account I can use when I need to install something or change settings.

To make my experience a little easier, I add my user account to a few items in Local Security Policy to allow me to do things like restart the machine, debug things, and use the performance monitoring tools.

In setting up a new Windows 2012 dev machine, I found that the domain Group Policy had the “Shut down the machine” policy locked down so there was no way to allow my developer account to shut down or restart. Painful.

To work around this, I created a shortcut on my Start menu that prompts me for the local machine administrator password and restarts using elevated credentials.

Here’s how:

Create a small batch file in your Documents folder or some other accessible location. I called mine restart-elevated.bat. Inside it, use the runas and shutdown commands to prompt for credentials and restart the machine:

runas /user:YOURMACHINE\administrator "shutdown -r -f -d up:0:0 -t 5"

The shutdown command I’ve specified there will…

  • Restart the computer.
  • Force running applications to close.
  • Alert the currently logged-in user and wait five seconds before doing the restart.
  • Set the shutdown reason code as “user code, planned shutdown, major reason ‘other,’ minor reason ‘other.’”

Now that you have the batch file, throw it on your Start menu. Open up C:\Users\yourusername\AppData\Roaming\Microsoft\Windows\Start Menu and make a shortcut to the batch file. It’s easy if you just right-drag the script in there and select “Create shortcut.”

Give the shortcut a nice name. I called mine “Restart Computer (Elevated)” so it’s easy to know what’s going to happen.

I also changed the icon so it’s not the default batch file icon:

  • Right-click the shortcut and select “Properties.”
  • On the “Shortcut” tab, select “Change Icon…”
  • Browse to %SystemRoot%\System32\imageres.dll and select an icon. I selected the multi-colored shield icon that indicates an administrative action.

Change the icon to something neat

Finally, hit the Start button and go to the list of applications installed. Right-click on the new shortcut and select “Pin to Start.”

Restart shortcut pinned to Start menu

That’s it - now when you need to restart as a non-admin, click that and enter the password for the local administrator account.

windows comments edit

I was setting up a new dev machine the other day and whilst attempting to install TestDriven I got a popup complaining about a BEX event.

Looking in the event log, I saw this:

Faulting application name: TestDriven.NET-3.8.2860_Enterprise_Beta.exe, version: 0.0.0.0, time stamp: 0x53e4d386
Faulting module name: TestDriven.NET-3.8.2860_Enterprise_Beta.exe, version: 0.0.0.0, time stamp: 0x53e4d386
Exception code: 0xc0000005
Fault offset: 0x003f78ae
Faulting process id: 0xe84
Faulting application start time: 0x01cfe410a15884fe
Faulting application path: E:\Installers\TestDriven.NET-3.8.2860_Enterprise_Beta.exe
Faulting module path: E:\Installers\TestDriven.NET-3.8.2860_Enterprise_Beta.exe
Report Id: df1b87dd-5003-11e4-80cd-3417ebb288e7

Nothing about a BEX error, but… odd.

Doing a little searching yielded this forum post which led me to disable the Data Execution Prevention settings for the installer.

  • Open Control Panel.
  • Go to the “System and Security” section.
  • Open the “System” option.
  • Open “Advanced System Settings.”
  • On the “Advanced” tab, click the “Settings…” button under “Performance.”
  • On the “Data Execution Prevention” tab you can either turn DEP off entirely or specifically exclude the installer using the whitelist box provided. (DEP is there to help protect you so it’s probably better to just exclude the installer unless you’re having other issues.)

vs, sublime comments edit

As developers, we’ve all argued over tabs vs. spaces, indentation size, how line endings should be, and so on.

And, of course, each project you work on has different standards for these things. Because why not.

What really kills me about these different settings, and what probably kills you, is remembering to reconfigure all your editors to match the project settings. Then when you switch, reconfigure again.

The open source project EditorConfig aims to rescue you from this nightmare. Simply place an .editorconfig file in your project and your editor can pick up the settings from there. Move to the next project (which also uses .editorconfig) and everything dynamically updates.

I don’t know why this isn’t the most popular Visual Studio add-in ever.

Here’s the deal:

Here’s the .editorconfig I use. I like tab indentation except in view markup. We’re a Windows shop, so lines end in CRLF. I hate trailing whitespace. I also like to keep the default settings for some project/VS files.

root = true

[*]
end_of_line = CRLF
indent_style = tab
trim_trailing_whitespace = true

[*.ascx]
indent_style = space
indent_size = 4

[*.aspx]
indent_style = space
indent_size = 4

[*.config]
indent_style = space
indent_size = 4

[*.cshtml]
indent_style = space
indent_size = 4

[*.csproj]
indent_style = space
indent_size = 2

[*.html]
indent_style = space
indent_size = 4

[*.resx]
indent_style = space
indent_size = 2

[*.wxi]
indent_style = space
indent_size = 4

[*.wxl]
indent_style = space
indent_size = 4

[*.wxs]
indent_style = space
indent_size = 4

Note there’s a recent update to the EditorConfig format that supports multiple matching, like:

[{*.wxl,*.wxs}]
indent_style = space
indent_size = 4

…but there’s a bug in the Sublime Text plugin around this so I’ve expanded those for now to maintain maximum compatibility.

I’ve added one of these to Autofac to help our contributors and us. It makes it really easy to switch from my (preferred) tab settings to use the spaces Autofac likes. No more debate, no more forgetting.

Now, get out there and standardize your editor settings!

testing, vs comments edit

I get a lot of questions from people both at work and online asking for help in troubleshooting issues during development. I’m more than happy to help folks out because I feel successful if I help others to be successful.

That said, there’s a limited amount of time in the day, and, you know, I have to get stuff done, too. Plus, I’d much rather teach a person to fish than just hand them the fish repeatedly and I don’t want to be the roadblock stopping folks from getting things done, so I figured it’d be good to write up the basic steps I go through when troubleshooting stuff as a .NET developer in the hope it will help others.

Plus - if you ever do ask for help, this is the sort of stuff I’d ask you for, sort of along the lines of calling tech support and them asking you to reboot your computer first. Is it plugged in? That’s this sort of thing.

Soooo… assuming you’re developing an app, not trying to do some crazy debug-in-production scenario…

Change Your Thinking and Recognize Patterns

This is more of a “preparation for debugging” thing. It is very easy to get intimidated when working with new technology or on something with which you’re not familiar. It’s also easy to think there’s no way the error you’re seeing is something you can handle or that it’s so unique there’s no way to figure it out.

  • Don’t get overwhelmed. Stop and take a breath. You will figure it out.
  • Don’t raise the red flag. Along with not getting overwhelmed… unless you’re five minutes from having to ship and your laptop just lit on fire, consider not sending out the all-hands ‘I NEED HELP ASAP’ email with screen shots and angry red arrows wondering what this issue means.
  • Realize you are not a special snowflake. That sounds mean, but think about it - even if you’re working on the newest, coolest thing ever built, you’re building that with components that other people have used. Other folks may not have received literally exactly the same error in literally exactly the same circumstances but there’s a pretty high probability you’re not the first to run into the issue you’re seeing.
  • Don’t blame the compiler. Sure, software is buggy, and as we use NuGet to pull in third-party dependencies it means there are a lot of bits out of your control that you didn’t write… and sure, they might be the cause of the issue. But most likely it’s your stuff, so look there first.
  • Use your experience. You may not have seen this exact error in this exact spot, but have you seen it elsewhere? Have you seen other errors in code similar to the code with the error? Do you recognize any patterns (or anti-patterns) in the code that might clue you in?

Read the Exception Message

This is an extension of RTFM - RTFEM. I recognize that there are times when exception messages are somewhat unclear, but in most cases it actually does tell you what happened with enough detail to start fixing the issue.

And don’t forget to look at the stack trace. That can be just as helpful as the message itself.

Look at the Inner Exception

Exceptions don’t always just stop with a message and a stack trace. Sometimes one error happens, which then causes a sort of “secondary” error that can seem misleading. Why did you get that weird exception? You’re not calling anything in there! Look for an inner exception - particularly if you’re unclear on the main exception you’re seeing, the inner exception may help you make sense of it.

And don’t forget to follow the inner exception chain - each inner exception can have its own inner exception. Look at the whole chain and their inner messages/stack traces. This can really help you pinpoint where the problem is.

Boogle the Message

You know, “Bing/Google” == “Boogle” right? Seriously, though, put the exception message(s) into your favorite search engine of choice and see what comes up.

  • Remove application-specific values - stuff like variable names or literal string values. You’re probably more interested in places that type of exception happened rather than literally the exact same exception.
  • Add “hint words” - like if it happened in an MVC application, throw “MVC” in the query. It can help narrow down the scope of the search.
  • Don’t give up after the first search - just because the first hit isn’t exactly the answer doesn’t mean the answer isn’t out there. Modify the query to see if you can get some different results.

Ask a Rubber Duck

Rubber duck debugging is a pretty well-known strategy where you pretend to ask a rubber duck your question and, as you are forced to slow down and ask the duck… you end up answering your own question.

Seriously, though, step back from the keyboard for a second and think about the error you’re seeing. Run back through your mind and think about the error and what might be causing it. It’s easy to get mental blinders on; take ‘em off!

Break in a Debugger

Put a breakpoint on the line of code throwing the exception. Use the various debugging windows in Visual Studio to look at the values of the variables in the vicinity. Especially if you’re getting something like a NullReferenceException you can pretty quickly figure out what’s null and what might be causing trouble.

Step Into Third-Party Code

Many popular NuGet packages put symbol/source packages up on SymbolSource.org. If you configure Visual Studio to use these packages you can step into the source for these. You can also step into Microsoft .NET framework source (the SymbolSource setup enables both scenarios).

Do this!

If you don’t know what’s going on, try stepping into the code. Figure out why the error is happening, then follow it back to figure out the root cause.

Use a Decompiler

If you can’t step into the third-party source, try looking at the third-party stuff in a decompiler like Reflector, JustDecompile, dotPeek, or ILSpy.

You can use the stack trace to narrow down where the issue might be going on and try tracing back the root cause. You might not get an exact line, but it’ll narrow it down for you a lot.

Create a Reproduction

Usually crazy hard-to-debug stuff happens in a large, complex system and figuring out why that’s happening can feel overwhelming. Try creating a reproduction in a smaller, standalone project. Doing this is a lot like the rubber duck debugging, but it tells you a little more in the way of concrete information.

  • As you work through creating the reproduction, the number of moving pieces becomes easier to visualize.
  • If you can easily reproduce the issue in a smaller environment, you can troubleshoot with many fewer moving pieces and that’s easier than doing it in the complex environment. Then you can take that info to the larger system.
  • If you can’t easily reproduce the issue then at least you know where the problem isn’t. That can sometimes be just as helpful as knowing where the issue is.

Next Steps

Once you’ve gotten this far, you probably have a lot of really great information with which you can ask a very clear, very smart question. You’ve probably also learned a ton along the way that you can take with you on your next troubleshooting expedition, making you that much better at what you do. When you do ask your question (e.g., on StackOverflow) be sure to include all the information you’ve gathered so people can dive right into answering your question.

Good luck troubleshooting!