Oct 212014
 

Introduction

I had a customer who was seeing several invalid handle exceptions in his application. These exceptions were thrown during finalization of  SafeProcessHandle objects. In their code they had a big collection of SafeProcessHandle objects hence too many objects in Finalization queue as well which means too many Invalid Handle exceptions as well.

What’s an Invalid Handle exception?

Invalid handle exceptions basically means the handle being closed has gone bad or has already been closed. In this case the second reason looked more valid to me as the exceptions were happening during finalization. There was a good chance that these handles got closed pretty early.

What’s the reason for these Invalid Handle exceptions?

Lots of Invalid handle exceptions were happening in his code while disposing a SafeProcessHandle object. This was because he’s was not properly serializing the process handles or SafeProcessHandle’s across app domain calls. We enabled MDA – ReleaseHandleFailed. This setting is also reporting something similar.

ReleaseHandleFailed was detected:
Message: A SafeHandle or CriticalHandle of type SafeProcessHandle failed to properly release the handle with value 0x00000000000020F0. This usually indicates that the handle was released incorrectly via another means (such as extracting the handle using DangerousGetHandle and closing it directly or building another SafeHandle around it.)

How to fix these Invalid Handle exceptions?

The only way to fix this invalid handle issue is to manage serialization of SafeProcessHandle objects across app domains. As of now its just a bitwise copy which results in two SafeProcessHandle’s owning a non-ref counted process handle. When either of these SafeProcessHandle objects are destroyed the second instance of SafeProcessHandle is bound to fail as the handle has already been destroyed/closed by the first instance.

Handle’s are indexes into a process handle table which in turn points to the real Kernel Object. This basically means we’ll have to duplicate this handle via DuplicateHandle API and which tells Kernel this object is still alive and not to destroy this Kernel Object. The duplicate handle refers to the same object as the original handle. Therefore, any changes to the object are reflected through both handles. For example, if you duplicate a file handle, the current file position is always the same for both handles.

SafeSerializableProcessHandle to fix Invalid Handle exceptions

Hence SafeSerializableProcessHandle is born. I wrote a dedicated class to manage this serialization. Made this class serializable as well. This class will automatically create a duplicate handle when serialized. For duplicating process handles we’re using the Windows API DuplicateHandle. Here’s how the code looks like…

using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.Win32.SafeHandles;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Diagnostics;

namespace NativeHandleWrappers
{
    [System.Security.SecurityCritical]
    [Serializable()]
    public class SafeSerializableProcessHandle : SafeHandleZeroOrMinusOneIsInvalid, ISerializable
    {
        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true, EntryPoint = "CloseHandle", CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandleImport(IntPtr hObject);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true, EntryPoint = "DuplicateHandle", CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DuplicateHandleImport(IntPtr hSourceProcessHandle,
                                           IntPtr hSourceHandle,
                                           IntPtr hTargetProcessHandle,
                                           out SafeSerializableProcessHandle lpTargetHandle,
                                           uint dwDesiredAccess,
                                           [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
                                           uint dwOptions);

        [Flags]
        public enum DuplicateOptions : uint
        {
            DUPLICATE_CLOSE_SOURCE = (0x00000001),// Closes the source handle. This occurs regardless of any error status returned.
            DUPLICATE_SAME_ACCESS = (0x00000002), //Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.
        }

        // Constructors //
        private SafeSerializableProcessHandle()
            : base(true)
        {
            handle = IntPtr.Zero;
        }

        // Constructor that is called automatically during deserialization.
        // Reconstructs the object from the information in SerializationInfo info
        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        private SafeSerializableProcessHandle(SerializationInfo Info, StreamingContext Context)
            : base(true)
        {
            handle = ((IntPtr)Info.GetInt64("handle"));
        }

        public SafeSerializableProcessHandle(IntPtr handle)
            : base(true)
        {
            SetHandle(handle);
        }
        // End constructors //

        // 0 is an Invalid Handle
        internal static SafeSerializableProcessHandle InvalidHandle
        {
            get { return new SafeSerializableProcessHandle(IntPtr.Zero); }
        }

        [System.Security.SecurityCritical]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        override protected bool ReleaseHandle()
        {
            bool Status = true;

            if (!SuppressRelease)
            {
                Status = CloseHandleImport(handle);
                if (!Status)
                {
                    DebugOutLastError();
                }
            }

            return Status;
        }

        void DebugOutLastError()
        {
            System.ComponentModel.Win32Exception we = new System.ComponentModel.Win32Exception();
            Debug.WriteLine("\n------------------------------------------\nLast error: " + we.Message + "\n------------------------------------------\n");
        }

        private bool _suppressRelease = false;
        protected bool SuppressRelease
        {
            get
            {
                return _suppressRelease;
            }

            set
            {
                _suppressRelease = value;
            }
        }

        // Serializes the object.
        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            SafeSerializableProcessHandle hDupHandle = DuplicateHandlePrivate(handle);
            info.AddValue("handle", hDupHandle.handle.ToInt64());

            // Suppress close handle as the handle will be closed by the instance that's deserializing
            hDupHandle.SuppressRelease = true;
            hDupHandle.Close();
        }

        private SafeSerializableProcessHandle DuplicateHandlePrivate(IntPtr Handle)
        {
            SafeSerializableProcessHandle hDupHandle;
            bool Status = DuplicateHandleImport(Process.GetCurrentProcess().Handle,
                                                Handle,
                                                Process.GetCurrentProcess().Handle,
                                                out hDupHandle,
                                                0,
                                                true,
                                                (uint)DuplicateOptions.DUPLICATE_SAME_ACCESS);
            if (hDupHandle == null || !Status)
            {
                Debug.Assert(false);
                DebugOutLastError();
            }

            return hDupHandle;
        }
    }
}

//Function to test SafeSerializableProcessHandle class. This function also demonstrates usage of SafeSerializableProcessHandle
void Serialize()
{
    FileStream fs = new FileStream("DataFile.dat", FileMode.Create|FileMode.CreateNew);

    try
    {
        // Construct a BinaryFormatter and use it to serialize the data to the stream.
        BinaryFormatter formatter = new BinaryFormatter();

        // Serialize
        Process [] Proc = Process.GetProcessesByName("Explorer");
        SafeSerializableProcessHandle ssph = OpenProcess(ProcessAccessFlags.DupHandle | ProcessAccessFlags.Terminate, true, Proc[0].Id);
        formatter.Serialize(fs, ssph);

        //Deserialize.
        fs.Position = 0;
        SafeSerializableProcessHandle newssph = (SafeSerializableProcessHandle)formatter.Deserialize(fs);

        // Close both, this should work
        ssph.Close();
        newssph.Close();
    }
    catch (SerializationException e)
    {
        Console.WriteLine("Failed to serialize. Reason: " + e.Message);
        throw;
    }
    finally
    {
        fs.Close();
    }
}

Usage of SafeSerializableProcessHandle

Replace instances of SafeProcessHandle, which will be cross domained or serialized, with SafeSerializableProcessHandle. No other change will be needed. The effect is magical, no invalid handle exceptions any more. :)

Caveats/Disclaimer

Please note this class is not extensively tested. I did some basic tests and so far looks like this is working for our customer as well. So I guess this is pretty solid. If you run into issues you can let me know via a comment to this post but this post is given as is without any sort of support. You’re going to use this at your own risk.

Oct 212014
 

What’s Fsutil?

It’s a Windows command line utility to help manage FAT and NTFS file systems. Common uses of this command is to…

  • Manage 8dot3name filenames, remove all short names in a folder.
  • View disk details
  • Query file system parameters
  • Dismounting volumes
  • Turning on last access time stamp on NTFS volumes
  • Figuring out file links
  • etc

I’ll be showing you few sample commands using Fsutil.

How to manage 8dot3name filenames using Fsutil?
Query 8dot3name filename status…

C:\>Fsutil 8dot3name query
The registry state is: 1 (Disable 8dot3 name creation on all volumes).

Scan registry to figure impact if 8dot3name filenames were removed from a directory

C:\>Fsutil 8dot3name scan /s c:\users\username\documents
Scanning registry…
<snip>

Enable or Disable 8dot3name file creation

C:\>Fsutil 8dot3name set
usage : set [0 through 3] | [<Volume Path> 1 | 0]

When a volume is not specified the operation updates the registry value:

0 – Enable 8dot3 name creation on all volumes on the system
1 – Disable 8dot3 name creation on all volumes on the system
2 – Set 8dot3 name creation on a per volume basis
3 – Disable 8dot3 name creation on all volumes except the
system volume

When a volume is specified the operation updates the individual
volume’s on disk flag.  This operation is only meaningful
if the registry value is set to 2.

0 – Enable 8dot3 name creation on this volume
1 – Disable 8dot3 name creation on this volume

This operation takes effect immediately (no reboot required).

Sample commands:
“Fsutil 8dot3name set 1”      – disable 8dot3 name creation on all volumes
“Fsutil 8dot3name set C: 1”   – disable 8dot3 name creation on c:

Strip a folder of 8dot3name file names

C:\>Fsutil 8dot3name strip
Usage : Fsutil 8dot3name strip </t> </s> </f> </l log file> </v> DirectoryPath

This command permanently removes 8dot3 file names from your volume. It will
list the registry keys pointing to the stripped 8dot3names but will not modify
the affected registry keys. Stripping will not be performed on files with full
path names longer than the maximum path length of 260 characters.

***WARNING***
If there are affected registry keys and you decide to use the override
switch /f, it is recommended that you backup your volume as it may lead to
unexpected application failures, including the inability to uninstall.

/t – Test mode – specifies that all operations should be performed
except the actual stripping of the file names.
/s – Recurse mode – specifies that this operation should also be
applied to subdirectories.
/f – Force mode – specifies that the directory should be stripped even
if there are registry conflicts.
/v – Verbose mode – specifies that all information logged should also
be printed out to the console.
/l – Specifies a log file to write to.  This must be followed by a path to the
log file.  If this option is not specified the log file will be:
“%temp%\8dot3_removal_log@(GMT YYYY-MM-DD HH-MM-SS).log”

Sample command:
Fsutil 8dot3name strip /l mylogfile.log /s D:\MyData

Modifying filesystem behavior using Fsutil

Queries or sets NTFS volume behavior, which includes:

  • The last access time stamp on NTFS volumes
  • How often quota events are written to the system log
  • The internal cache levels of NTFS paged pool and NTFS non-paged pool memory
  • The amount of disk space reserved for the master file table (MFT) Zone
  • The silent deletion of data when the system encounters corruption on an NTFS volume.
Disable8dot3 file system behavior using Fsutil

Sample commands…

C:\>Fsutil behavior set Disable8dot3 1
The registry state is now: 1 (Disable 8dot3 name creation on all volumes).

C:\>Fsutil behavior set Disable8dot3 0
The registry state is now: 0 (Enable 8dot3 name creation on all volumes).

Disable or Enable LastAccess timestamps on files using Fsutil

Sample commands…

C:\>Fsutil behavior set DisableLastAccess 1
DisableLastAccess = 1

You should now see LastAccess timestamp enabled on your files

C:\>Fsutil behavior set DisableLastAccess 0
DisableLastAccess = 0

LastAccess timestamp is now disabled for your files.

Sample SymlinkEvaluation command using Fsutil

C:\>Fsutil behavior set SymlinkEvaluation L2L:1 L2R:0
– Will enable local to local symbolic links and disable local to
remote symbolic links. It will not change the state of remote to
remote links or remote to local links.
– This operation takes effect immediately (no reboot required)

Using Fsutil to manage volumes

C:\>Fsutil volume
—- VOLUME Commands Supported —-

diskfree            Query the free space of a volume
dismount            Dismount a volume
querycluster        Query which file is using a particular cluster
filelayout          Query all the information available about the file
allocationreport    Allocated clusters report

How to view free disk space using Fsutil

C:\>Fsutil volume diskfree
Usage : Fsutil volume diskfree <volume pathname>
Eg : Fsutil volume diskfree C:

File usage on clusters using Fsutil

To find the file(s) that are using the clusters, specified by the logical cluster numbers 200 and 0x1000, on drive C, type:

C:\>Fsutil volume querycluster C: 200 0x10000
Cluster 0x0000000000010000 used by —-D \Users\nthomas\AppData\Local\Microsoft\Windows\INetCache\IE\Microsoft.VisualStudio.Data.Tools.Package.resourcesT8HR0EQA.HTM::$DATA
Cluster 0x00000000000000c8 used by —-D \Windows\WinSxS\ia64_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_2a4c9d845558f4b7\msvcr90d.dll::$DATA

Using Fsutil to manage files

Usage…

fsutil file [createnew] <FileName> <Length>
fsutil file [findbysid] <UserName> <Directory>
fsutil file [queryallocranges] offset=<Offset> length=<Length> <FileName>
fsutil file [quaeryfileid] <FileName>
fsutil file [queryfilenamebyid] <Volume> <Fileid>
fsutil file [setshortname] <FileName> <ShortName>
fsutil file [setvaliddata] <FileName> <DataLength>
fsutil file [setzerodata] offset=<Offset> length=<Length> <FileName>

More on Fsutil can found on TechNet: http://technet.microsoft.com/en-us/library/cc753059.aspx

Oct 142014
 

Introduction to MiniDumpWriteDump

In this post, let me show you some sample code to create a full memory dump of any given process using the Windows API MiniDumpWriteDump.

Creating Full Memory Dumps using MiniDumpWriteDump

Here’s some sample code to create a full memory dump of any given process. Just call WriteFullDump(hProcessHandle). This process handle must have PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access to the process. If handle information is to be collected then PROCESS_DUP_HANDLE access is also required.

Please test out before production use. Just some quick code that I was writing up for a customer.

#include <tchar.h>
#include <windows.h>
#include <DbgHelp.h>

using namespace std;

#pragma comment (lib, "dbghelp.lib")

void WriteFullDump(HANDLE hProc)
{
   const DWORD Flags = MiniDumpWithFullMemory |
   MiniDumpWithFullMemoryInfo |
   MiniDumpWithHandleData |
   MiniDumpWithUnloadedModules |
   MiniDumpWithThreadInfo;

   HANDLE hFile = CreateFile(_T("F:\\main.dmp"), GENERIC_ALL, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
   if (!hFile)
   {
     std::cerr << _T("Failed to write dump: Invalid dump file");
   }
   else
   {
     BOOL Result = MiniDumpWriteDump( hProc,
                                      GetProcessId(hProc),
                                      hFile,
                                      (MINIDUMP_TYPE)Flags,
                                      nullptr,
                                      nullptr,
                                      nullptr );

     CloseHandle(hFile);

     if (!Result)
     {
        std::cerr << _T("Looks like an error: MiniDumpWriteDump failed") ;
     }
   }// End if

   return;
}

Significance of MiniDumpWriteDump flags

What gets into a process’ memory dump is determined by the flags we pass in to MiniDumpWriteDump API. The code that I’ve given produces the biggest dumps possible for a process. The output dump file in this case will have the entire process’ memory, modules, registers, thread information, unloaded module information, and process handle related information.

For our case we’ve given these five flags, this will just basically copy everything from a process’ virtual address space into a dump. Comment out any flags if you’re not interested in that information, for e.g. if you don’t need information on the handles in a process just comment out: MiniDumpWithHandleData.

MiniDumpWithFullMemory |
MiniDumpWithFullMemoryInfo |
MiniDumpWithHandleData |
MiniDumpWithUnloadedModules |
MiniDumpWithThreadInfo;

References

http://msdn.microsoft.com/en-us/library/windows/desktop/ms680360(v=vs.85).aspx

Oct 072014
 

Introduction

There are several known folders in Windows. They are as follows…

  • Desktop
  • Documents
  • Pictures
  • Videos
  • Music
  • Downloads

Below screenshot will demonstrate these folders further…

image

By default these folders are put in under the users directory, for e.g.

  • Desktop: c:\users\<username>\Desktop\
  • Documents: c:\users\<username>\Documents\
  • Pictures: c:\users\<username>\Pictures\
  • Music: c:\users\<username>\Music
  • etc

So why should we change this path?

In my case I had a need to put all these folders under my root folder, i.e. I normally keep a folder structure like D:\NibuRoot\. This helps me to…

  • Put all my files under one folder so that they’re not scattered around.
  • Ease of access
  • Easy to backup, I use beyond compare for backing up.
  • Data stays intact in case of OS corruption as mostly this folder will be in a different partition
  • Ease of use from Explorer and Run dialog. Explorer follows suit.
  • All your Visual Studio Projects are moved to this location as well. All future projects are now created under this folder as well. One primary reason I change the default location.

How to Change the Default Location of the Documents folder?

So I’ll show you a demo for the Documents folder. You can follow the same process for other folders as well…

  1. Open Windows Explorer (Windows Key + E) or just open up any folder.
  2. You should see following list of folders in the left hand side Navigation Pane of Windows Explorer
    image
  3. Right click on the Documents folder, select ‘Properties’.
  4. The folder property dialog pops up, please select ‘Location’ tab as shown below…
    image
  5. Click the ‘Move’ button.
  6. Select/Create a new folder.
  7. Your selection should show up in the ‘Location’ tab. Please verify it indeed does.
    image
  8. Anytime to revert back to the original folder location select ‘Restore Default’.
  9. Please note, once you click ‘Apply’, following dialog pops up. Prompts you to move all the data in the existing ‘Documents’ folder to your new ‘Documents’ folder. Cool isn’t it?
    image
  10. Follow the recommendation.
  11. Yep, that’s it. Now the default path of ‘Documents’ folder has changed to your selection. So now if you type in ‘Documents’ in the Windows run dialog, your new ‘Documents’ folder will open up. Similarly from explorer as well.

Conclusion

This is how we change the default folder path of ‘Documents’ folder. Steps are identical for other folders as well.

Oct 032014
 

Introduction

In this post we will talk about some apparent changes in Windows 10.

New Start Menu

Phew what a RELIEF! We finally got our start menu back and its much better as well. Few options that stares at you straightaway…

  • Shutdown button at the top of the start menu
  • Live Tiles (you can decide what you want on the start menu)
  • Search toolbar
  • All Apps button (quite similar to windows 7)
  • So far my Windows 8 apps (like Visual Studio) continue to work on Windows 10. Relieved!
  • Resize start menu. Adding live tiles could automatically increase the size of your start menu.

Windows 10 Start Menu

Customizing Start Menu Live Tiles

Just right click on a tile and you will see following menu of options come up. The options names are self explanatory.

Windows 10 Start Menu Live Tile Customization

Change color of Start Menu

To personalize your start menu, task bar, window title bars etc. Just right click on an empty area on the start menu. You’ll following see following menu popup. Select a color and click “Save Changes’’ on the resultant color chooser dialog and you’re good to go. I changed to Pink and you’ll see the effect in this clipped shot: background is pink.

image

Start Menu/Screen

Goto taskbar properties and select “Start Menu” tab.

image

Multiple Desktops (Tasks View)

Press Window Key + Tab, You should see following…

image

Multiple desktops

image

How to Close a Desktop

Just hover your mouse a desktop after pressing Windows Key + Tab. You’ll get red close button on the top of that desktop preview.image

Another alternative to show up multiple desktops is to click the Task View button on the Windows TaskBar. See highlighted shot…

image

TaskBar pins Apps across Desktops

If apps are displayed on other desktops then the icon for that will remain across desktops. You will get a small rectangle towards the left of that icon as highlighted below. Just hover your mouse over there and it will show up a list of apps running. Hover over there and then click on respective thumbnail that pops up and it will take you to the desktop where the app is running.

image

Move Apps to another Desktop

In task view, right click on an application main window and, you’ll get following options. Move apps to different desktops…

image

Changes to Windows Explorer

Obvious changes are the name: “Home”. You can play around. You’ll also see a “Share” button as well. There’s a recent folder under favorites which is quite useful as well.

imageimage

Snap Applications to Four Corners of Desktop

This isn’t playing well so far but mostly if you drag an application window to a corner you’ll see a ghost outline which indicates how it’s going to snap, release mouse cursor and the application with snap in place. Alternatively window taskbar provides a way as well, which I’ve been using for long time now. This is there in Windows 8 as well.

image

Sep 172014
 

Issue

You get CannotUnloadAppDomainException when trying to unload an AppDomain on which a WPF window has been displayed. This is how the exception looks like…

---------------------------
AppDomainUnload
---------------------------
Error while unloading appdomain. (Exception from HRESULT: 0x80131015)
---------------------------
OK
---------------------------

The callstack associated with this exception is not at all informative. This is all that I have for this exception…

System.CannotUnloadAppDomainException occurred
_HResult=-2146234347
_message=Error while unloading appdomain. (Exception from HRESULT: 0x80131015)
HResult=-2146234347
IsTransient=false
Message=Error while unloading appdomain. (Exception from HRESULT: 0x80131015)
Source=mscorlib
StackTrace:
at System.AppDomain.nUnload(Int32 domainInternal)
at System.AppDomain.Unload(AppDomain domain)
InnerException:

Repro

This was the code that was shared by the customer which demonstrates the issue. Nothing proprietary hence sharing this out…

Private Sub Button_Click(sender As Object, e As RoutedEventArgs) Handles btn1.Click
    Try
        btn1.IsEnabled = False

        ‘Create a new AppDomain
        Dim ad As AppDomain = AppDomain.CreateDomain("ad2")
        Dim exeAssembly As String = [Assembly].GetEntryAssembly().FullName

        Dim newDomain As NewAppDomain = DirectCast(ad.CreateInstanceAndUnwrap(Assembly.GetEntryAssembly.FullName, GetType(NewAppDomain).FullName), NewAppDomain)

        'Call a subroutine to show a WPF window
        newDomain.ShowWPFWindow()
        AppDomain.Unload(ad)

        MsgBox("New AppDomain unloaded successfully")

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        btn1.IsEnabled = True
    End Try
End Sub

So in above code we’re creating an object in a new app domain (“ad2”) and we then call ShowWPFWindow on this new object which will show up the window in a new app domain. Once ShowWPFWindow returns we unload this AppDomain and this where CannotUnloadAppDomainException happens. We do see the application going unresponsive before this CannotUnloadAppDomainException.

Why does a CannotUnloadAppDomainException occur?

The million dollar question is why does this happen? Well from what we’ve found when a WPF Window is showed for the first time on a new app domain a Stylus input thread gets attached to this window for touch input events on touch enabled devices or at least on devices which such components installed.

When AppDomain.Unload call is made this thread fails to shutdown. We do see a thread abort request already sent to this stylus input thread but we don’t see a response yet.

Exception on top of the stack…

0:009> !pe
Exception object: 028280c4
Exception type:   System.CannotUnloadAppDomainException
Message:          Error while unloading appdomain. (Exception from HRESULT: 0x80131015)
InnerException:   <none>
StackTrace (generated):
SP       IP       Function
00000000 00000001 mscorlib_ni!System.AppDomain.nUnload(Int32)+0x2
07D3E320 793DCDE9 mscorlib_ni!System.AppDomain.Unload(System.AppDomain)+0x41

StackTraceString: <none>
HResult: 80131015

0:009> !threads
ThreadCount:      14
UnstartedThread:  0
BackgroundThread: 9
PendingThread:    0
DeadThread:       3
Hosted Runtime:   no
Lock
ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
0    1  e10 00b63f40   203a228 Preemptive  025EA018:00000000 00b573b8 0     MTA
2    2  a44 00b65bf0     2b228 Preemptive  0282A108:00000000 00b573b8 0     MTA (Finalizer)
XXXX    3    0 00bf2b18     30820 Preemptive  00000000:00000000 00b573b8 0     Ukn
XXXX    4    0 00c00a20     39820 Preemptive  00000000:00000000 00b573b8 0     MTA
XXXX    5    0 00c09b10     39820 Preemptive  00000000:00000000 00b573b8 0     MTA
5    6 1ec8 00c06d08   10b9228 Preemptive  0280C960:00000000 00b573b8 0     Ukn (Threadpool Worker)
7    7 2388 00c22128     ab028 Preemptive  02600420:00000000 00b573b8 0     MTA
8    8 20e4 00c2b2a8     ab228 Preemptive  025FA3DC:00000000 00b573b8 0     MTA
9    9 22b0 06ff0a58     a7028 Preemptive  0282CAF4:00000000 00b573b8 0     STA System.CannotUnloadAppDomainException 028280c4
11   10 1848 07098f78     2b228 Preemptive  026CE7D8:00000000 00b573b8 0     MTA
16   11 1e74 09e984c8     21228 Preemptive  00000000:00000000 00b573b8 0     Ukn
17   12 22b8 07087b90   102a228 Preemptive  00000000:00000000 00b573b8 0     MTA (Threadpool Worker)
  18   13 14f4 0702d878     2b229 Preemptive  027827CC:00000000 09e047a0 0     MTA <<<<--- Stylus input thread
19   14  a6c 07090058   10b9228 Preemptive  00000000:00000000 00b573b8 0     Ukn (Threadpool Worker)

The only thread in that domain is #18, a stylus input thread. A thread abort has already been posted and a debug suspend is pending as well…

0:018> !ThreadState 2b229
    Thread Abort Requested  <<<- Thread abort requested but yet to shutdown
Debug Suspend Pending
Legal to Join
Background
CLR Owns
CoInitialized
In Multi Threaded Apartment
Fully initialized

Please note this is the only thread on this AppDomain now that’s left to exit. Since it fails to exit we get a CannotUnloadAppDomainException.

Workaround for this CannotUnloadAppDomainException?

Only workaround is to move AppDomain+Window creation to a separate thread and then forcefully shutdown the Dispatcher thread (via calls to Dispatcher.CurrentDispatcher.InvokeShutdown()). InvokeShutdown alone can fail unless a GC is forced. Please see below code. I’ve added a new thread worker function called ‘DoWork’ which does the work of creating and displaying the AppDomain window…

‘Thread proc
Public Shared Sub DoWork()
    'Create a new AppDomain
    Dim ad As AppDomain = AppDomain.CreateDomain("ad2")
    Dim exeAssembly As String = [Assembly].GetEntryAssembly().FullName

    Dim newDomain As NewAppDomain = DirectCast(ad.CreateInstanceAndUnwrap(Assembly.GetEntryAssembly.FullName, GetType(NewAppDomain).FullName), NewAppDomain)

    'Call a subroutine to show a WPF window
    newDomain.ShowWPFWindow()
    Dispatcher.CurrentDispatcher.InvokeShutdown()  <<<--- Workaround
    GC.Collect() <<<—Workaround
    AppDomain.Unload(ad)

    MsgBox("New AppDomain unloaded successfully")
End Sub

Private Sub Button_Click(sender As Object, e As RoutedEventArgs) Handles btn1.Click
    '
    Try
        btn1.IsEnabled = False

        Dim ts As New ThreadStart(AddressOf DoWork)
        Dim WorkerThread As New System.Threading.Thread(ts)
        WorkerThread.SetApartmentState(ApartmentState.STA)
        WorkerThread.Start()
        WorkerThread.Join()

        MsgBox("New AppDomain unloaded successfully")

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        btn1.IsEnabled = True
    End Try
End Sub

Please note where we’re calling (workaround) InvokeShutdown.

Dispatcher.CurrentDispatcher.InvokeShutdown()
GC.Collect()

GC.Collect is important just to make sure the Pen/Stylus objects are cleared out from memory. Alternatively you can also write above code in a Window’s closing event so that the stylus input thread is detached from this window and the objects associated with it are cleared from memory.

Sep 132014
 

Issue

Today had a customer who was facing warning: RC4005/C4005 after installing VS2013 Update 3. They also had installed the Windows 8.1 SDK. Any new project created in the IDE showed these symptoms so this was not caused by existing code.

Cause

It turned out that his include file settings in project properties was causing this. It was missing a critical include…

$(WindowsSDK_IncludePath)

We added above include as illustrated below and the warnings (RC4005/C4005) went away…

image

Hope this helps save your time. Smile

Sep 102014
 

Issue

Recently a colleague asked this question. They had a customer who was experiencing a heap corruption so as expected we enabled PageHeap but there was a catch. The application had to run for a long time (around 30 days) in order to reproduce the crash and we had no idea what’s causing the crash.

How do we enable PageHeap?

We can enable standard PageHeap using following command run from an admin command prompt: gflags /p /enable ImageFileName
To enable full PageHeap use the following: gflags /p /enable ImageFileName /full 

(MSDN) Use care in interpreting the Enable page heap check box for an image file in the GFlags dialog box. It indicates that page heap verification is enabled for an image file, but it does not indicate whether it is full or standard page heap verification. If the check results from selecting the check box, then full page heap verification is enabled for the image file. However, if the check results from use of the command-line interface, then the check can represent the enabling of either full or standard page heap verification for the image file.

Why application hung?

So customer enabled PageHeap and went home. Came back next day to see that the application has stopped responding and is hung. The application hung apparently after enabling PageHeap and as we know of PageHeap: every allocation is paged to the page file. So guess why would the hang take place? PageFile size!

Resolution

The customer had set PageFile to its default size which apparently was not enough in this case. We suggested to increase the PageFile size and the hang went away. This resolved the issue. Note that if you enable PageHeap and then go home no matter what’s the PageFile size eventually the result will be unpredictable as the PageFile size is finite. You might need to tweak your PageHeap settings and make it per module or non-full standard page heap.

Conclusion

Please note there are different variants of PageHeap. In this case we needed a full PageHeap so please note this will be pretty heavy on the PageFile.

Sep 032014
 

Issue

Recently had a customer who was facing this issue. His code looked as follows (assuming COM’s initialized) which apparently is trying to setup an ActiveX control…

HWND hWnd = CreateWindow(_T(ATLAXWIN_CLASS),
_T(“SysMon”),
WS_CHILD,
0, 10, 100, 200,
hwndParent,
NULL,
hInstance,
NULL);

As soon as above code executes the application crashes.

image

Why loading ActiveX failed?

Callstack for the crash looks as follows…

ConsoleApplication1.exe!ATL::CComPolyObject<ATL::CAxHostWindow>::CComPolyObject<ATL::CAxHostWindow>
ConsoleApplication1.exe!ATL::CComCreator<ATL::CComPolyObject<ATL::CAxHostWindow> >::CreateInstance
ConsoleApplication1.exe!AtlAxCreateControlLicEx
ConsoleApplication1.exe!AtlAxCreateControlLic
ConsoleApplication1.exe!ATL::AtlAxWindowProc
user32.dll!UserCallWinProcCheckWow
user32.dll!DispatchClientMessage
user32.dll!__fnINLPCREATESTRUCT
ntdll.dll!KiUserCallbackDispatch    Unknown
user32.dll!ZwUserCreateWindowEx    Unknown
user32.dll!VerNtUserCreateWindowEx
user32.dll!CreateWindowInternal
user32.dll!CreateWindowExW
ConsoleApplication1.exe!wmain
ConsoleApplication1.exe!__tmainCRTStartup
ConsoleApplication1.exe!wmainCRTStartup
kernel32.dll!BaseThreadInitThunk
ntdll.dll!RtlUserThreadStart

 

Autos debug window showed following…

image

Resolution

The highlighted elements gave ample hint. This is a console application with no ATL boilerplate code generated by project wizard for this project. Ideally ATL requires a global CComModule instance to initialize itself. This is how the CComModule constructor looks like…

CComModule()
{
// Should have only one instance of a class
// derived from CComModule in a project.
ATLASSERT(_pModule == NULL);
<span style="background-color: #ffff00;">_pModule = this;</span>
#if !defined(_ATL_NATIVE_INITIALIZATION)
#pragma warning(push)  // disable 4483
#pragma warning(disable:4483)
using namespace __identifier("<AtlImplementationDetails>");
#pragma warning(pop)  // disable 4483
ATLASSERT(ComModuleInitialized == false);
// If ComModuleHelper.Module == NULL it mean that DllMain has not been called, so we assume CComModule lives in
// an exe and not in a dll
if (ComModuleHelper.Module != NULL)
{
ATLASSERT(ComModuleHelper.Module == this);
_DllMain(ComModuleHelper.Instance, DLL_PROCESS_ATTACH, NULL, ComModuleHelper.ObjectMap, ComModuleHelper.LibraryId);
}
ComModuleInitialized = true;
#endif
}

This function further initializes _pModule instance to point to this global instance of ours eventually. So after we declare CComModule global instance this is how _pAtlModule (it points to our  global instance) will look after instantiation of our global CComModule…

image

Crash resolved.