Archive for the ‘Programming’ Category

Read it. Now read it again.

Wednesday, April 25th, 2018

This is a reminder to myself, really.

Hello, me. When you get a bug report, please read it. All the way through. Then read it again.

I caught myself out again this morning, diving in with a preconceived idea of what the problem was, and spending an age slowly stepping through the code before noticing the code I was looking at was working exactly as it should. What I thought the bug report said was “When you early exit combat under a winning condition, you are shown the combat lost summary screen”. What the bug report actually said was “When you early exit combat under a winning condition, the confirmation dialog will warn you of a loss, but then you are shown the combat won summary screen”.

More haste, less speed. Who’d have thought?

C#/WinForms: Binding a SortedList to a DataGridView

Friday, April 4th, 2014

I ran into an issue the other day, and I didn’t find a suitable answer online. Maybe my google-fu was weak that day. Regardless, I thought I’d add my workaround here, in case anyone else runs into the same problem and wanders this way.

(more…)

Missing MSVCR80.DLL, MSVCM80.DLL, MSVCP80.DLL

Thursday, May 27th, 2010

I ran into a problem yesterday that took a few hours to decipher. I thought I’d share it here, in case Google manages to lead someone with a similar problem this way.

I made a minor change to a DLL in a program I’ve been working on and distributed it to the end users. The user that had requested the fix was happy with the result, and everything was fine for a couple of hours. Then I received an email from another user complaining the program was failing to load, reporting the error

System.IO.FileLoadException: Could not load file or assembly 'MyLIB, Version=1.0.3798.19982, Culture=neutral, PublicKeyToken=null' or one of its dependencies. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)

I’d seen this type of error before; typically it means MyLIB.dll requires another DLL that isn’t present. I checked his program folder, but everything was present – no missing DLLs. Tried re-patching and tried re-installing, and still no luck. I ran the dependency walker to see exactly what it was that it was missing. Turns out to be MSVCR80.DLL, MSVCM80.DLL and MSVCP80.DLL – the MS Visual C++ runtime.

Wait, what?

That didn’t make any sense, as he’d had the program running happily a few hours before. I tried re-installing the runtime, but that didn’t seem to help. Much scratching of heads and gnashing of teeth followed.

It turns out that the new build of MyLIB.DLL that I’d built had tied itself to the specific runtime version I had on my PC – 8.0.50727.4053. These runtime DLLs were installing into C:\Windows\WinSxS, where different versions of the same DLLs live side by side in an uneasy truce. I don’t pretend to fully understand what’s going on in there, but anyway. The different versions of runtimes were in different subfolders, the names of which contained the version number. When we checked the machine that the program was failing to run on, the .4053 version wasn’t there. We had to find that specific C++ redistributable version on microsoft.com as install it, which fixed the problem. The version of the runtime I had tried reinstalling earlier was an older version. It was then I realized that I have a new PC, and this is the first time I’ve rebuilt that particular DLL on this machine. Those with older machines were less likely to have the newer runtime installed.

Many sources on the interwebbings were simply saying “get the dll from here, and stick it in your Windows\System32 directory”. This is exactly wrong in this instance.

It would be nice if I could find an option in the project build configuration that says “Use runtime version X or later”, rather than it requiring the specific version it finds on my machine.

ImageList and .NET leaks

Wednesday, April 14th, 2010

Even with garbage-collected managed memory systems like those found in C#/.NET applications still suffer from leaks.

Most of the time, the “leak” is an object that has a reference to it being held by a static object. These can be a pain to identify, and near impossible in a large application without the aid of additional memory tracking tools. SciTech’s .NET Memory Profiler software is such a tool, and has proven itself invaluable in detecting these problems.

It surprises me how often leaks come back to (mis)use of the innocent looking ImageList object. For example, I have an ImageList object that contains a set of icons for different document types, and use it for ListViews, TreeViews, and anywhere else in the UI where I’m presenting collections of documents. It’s all too easy to set the image list:

myListView.SmallImageList = MyApp.DocumentIcons;

…then assume that when this particular UI goes away, all the contents go away too.

Under the surface, pointing a ListView control at an ImageList also causes the ImageList to store a reference back to the ListView. This way, if an icon is modified in the ImageList, all the ListViews and other controls that are using it can be updated too. The downside is when you forget to reset the SmallImageList property in the ListView control when the control containing the ListView is being disposed. Because the ImageList refers to the ListView, the ListView won’t go away. The ListView refers to the parent UI, the parent UI refers to the document, the document refers to the data, and so on. So when we set our document reference to null, while we might expect the whole lot to be disposed, they continue to persist in memory,  accessible only through the ImageList object.

SciTech’s tool allows me to take snapshots before and after opening and closing a document or particular UI, and compare them to see what objects have been created but not freed. I’ve been using it for a few days and have already found a couple of commonly used UserControls in a UI-heavy application that weren’t being disposed of correctly.