Elusive Bugs: “ScratchSurface was already borrowed…”

As the author of something like Paint.NET, I often get bugs reported that I simply don’t understand. Ever since before Paint.NET 3.0 went into beta, I’ve been getting crash reports like the following:

System.InvalidOperationException: ScratchSurface already borrowed: ‘PaintDotNet.DocumentWorkspace.DoSaveAs() handing off scratch surface to DoSaveAsDialog()’ (trying to borrow for: ‘PaintBucketTool: Tool.Activate()’)

This tells me that the Paint Bucket tool was trying to activate, but it couldn’t get the scratch surface (this is an internal Paint.NET object) because the Save As dialog already had it. Unfortunately, the stack trace didn’t help. All my powers of analysis were for naught, as I could not discern a way that the scratch surface was in use twice. One part of the crash log was pointing a finger at the Save As dialog, but that code was nowhere to be seen in the stack trace!

The number of reports of this particular crash were not alarming, nor were they causing any bad press or user sentiment. So, for months I just accepted the bug and hoped that a future version would work around it accidentally. As a software developer, you quickly learn that software has bugs. And you will ship with some. It’s just the way the world works outside of ivory towers.

See, the problem was that I was trying to use logic to figure out a repro for the bug (“a repro” is just the term for having a set of instructions to reproduce the issue). I looked at the callstack and did not see any of the Save As dialog’s functions, so I concluded that the Save As dialog was not active at the time of the crash. I thought that, somehow, the Save As dialog had closed but for some reason it had not returned the “Scratch Surface”. I probably have spent several hours over the last few months just trying to repro this one specific crash. I looked everywhere except that Save As dialog itself

Well, I was wrong. Yesterday the light bulb went on over my head and I decided I would try to do the following:

  1. Start Paint.NET
  2. Go to File -> Save As
  3. Click on a tool in the Tools window (this should be impossible! The “Save As” dialog is modal! The other windows should just go “beep” if you try to click on them!)

Guess what? Not only was (3) possible, it crashed the program! I finally had a repro! You can try it for yourself right now in the latest 3.08 release. For some reason, the Save As dialog is modal with respect to the main Paint.NET window, but it isn’t preventing clicks from being processed in the four “floating windows” (Tools, History, Layers, Colors). My knowledge of WinForms and Win32 doesn’t give me a way for this to be possible, but a workaround that produces the effect I need should be straight forward.

So, there you go. This will be fixed in the next release of Paint.NET of course.


14 thoughts on “Elusive Bugs: “ScratchSurface was already borrowed…”

  1. Atreyu says:

    Hmm…I’m not able to reproduce that bug. I check to be sure it is 3.08, which it is. As you stated the other windows just go “beep” when I try to click them.

  2. Rick Brewster says:

    Atreyu — hmm, it might only happen in Vista. That’s the OS listed in the last crash log sent to me. The Save/Open dialogs are different in Vista, in fact it’s a completely separate code path, so that could be it. The workaround should still be relatively easy 🙂

  3. Dean Harding says:

    Yeah, I can confirm it happens on Vista but not XP.

    However, in XP it’s still slightly funny. When I click the main toolbar, the “Save As…” dialog flashes. But when I click one of the floating windows, it does not flash (though the click is still not registered). I don’t have sound on this box so I can’t tell you if it beeps 🙂

  4. Francis Gagné says:

    I’m on Windows XP too and I can’t reproduce it either. Clicking on the Tools window doesn’t flash the Save As dialog (as mentioned by Dean Harding) but it still beeps.

  5. Tillerman says:

    I have tried to reoproduce this bug on Windows Vista but, it would not work…

  6. Rick Brewster says:

    David, well this is actually with an OS-supplied modal dialog, not another WinForms dialog. Which makes it even weirder 🙂 In any event, I have a solution in place, which is good news.

  7. joey says:

    There is a similar behavior in 3.10 (beta) on XP SP2. With the “save as” window open, I can hover over the color picker, history, & layers palettes and they unfade. Shouldn’t they remain in their faded state?

  8. Rick Brewster says:

    joey — Yeah I just received a crash report on that earlier today. I was surprised because it was in XP. I’ll make sure this is patched up in the XP codepath as well.

  9. don2712 says:

    I installed version 3.05 about 8 months ago and it worked fine on the rare occasions that I used it but now, when I try to open it, I am getting the message “CLR error: 80004005 the programme will now terminate.”

    When I try to repair or uninstall for a new installation I get the message “there is a problem with the installer package and that a fatal error occured during installation”

    The process cannot be completed so the only option seems to be manual removal.

    Before i go down that route I would appreciate any assistance from anyone

    Thank you


  10. Hi don says:

    Hey Don,
    Have you tried deleting the paint.net folder instead of uninstalling it then installing the new version?

Comments are closed.