[IO] Dump handle when we run out of them
authorLudovic Henry <ludovic@xamarin.com>
Thu, 12 Nov 2015 18:49:43 +0000 (18:49 +0000)
committerLudovic Henry <ludovic@xamarin.com>
Fri, 13 Nov 2015 11:59:54 +0000 (11:59 +0000)
When running out of handle, it's hard to know exactly why. Dumping them
will help troubleshoot handle leaks.

mcs/class/corlib/System.IO/MonoIO.cs
mono/metadata/file-io.c
mono/metadata/file-io.h
mono/metadata/icall-def.h

index a15c475bbaa88aab7ec9854f900dd4bf16215afa..994358c86bec2aff6ec7373da50dcd0ee17d515a 100644 (file)
@@ -51,6 +51,8 @@ namespace System.IO
                public static readonly IntPtr
                        InvalidHandle = (IntPtr)(-1L);
 
+               static bool dump_handles = Environment.GetEnvironmentVariable ("MONO_DUMP_HANDLES_ON_ERROR_TOO_MANY_OPEN_FILES") != null;
+
                // error methods
                public static Exception GetException (MonoIOError error)
                {
@@ -89,6 +91,8 @@ namespace System.IO
                                return new FileNotFoundException (message, path);
 
                        case MonoIOError.ERROR_TOO_MANY_OPEN_FILES:
+                               if (dump_handles)
+                                       DumpHandles ();
                                return new IOException ("Too many open files", unchecked((int)0x80070000) | (int)error);
                                
                        case MonoIOError.ERROR_PATH_NOT_FOUND:
@@ -599,6 +603,9 @@ namespace System.IO
                        [MethodImplAttribute (MethodImplOptions.InternalCall)]
                        get;
                }
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static void DumpHandles ();
        }
 }
 
index b193e0a54945d373379c6dc1c990ea4855eaf8b6..c4364a11437fa501fb27911e64084e090b3c3a8f 100644 (file)
@@ -1252,3 +1252,12 @@ mono_filesize_from_fd (int fd)
 }
 
 #endif
+
+void _wapi_handle_dump (void);
+
+void ves_icall_System_IO_MonoIO_DumpHandles (void)
+{
+#ifndef HOST_WIN32
+       _wapi_handle_dump ();
+#endif
+}
index 271bc58af7785a76521b9307e35a89ed24ecf10b..2974bd49949ecdd27de60df557c33ee102df61e4 100644 (file)
@@ -253,6 +253,9 @@ mono_filesize_from_path (MonoString *path);
 extern gint64
 mono_filesize_from_fd (int fd);
 
+void
+ves_icall_System_IO_MonoIO_DumpHandles (void);
+
 G_END_DECLS
 
 #endif /* _MONO_METADATA_FILEIO_H_ */
index 2d2e405c368e88d2b241965c73f15731246c7384..489b5ded65b19fcf2edf5080854849470530a86d 100644 (file)
@@ -325,6 +325,7 @@ ICALL(MONOIO_3, "CreateDirectory(string,System.IO.MonoIOError&)", ves_icall_Syst
 ICALL(MONOIO_4, "CreatePipe", ves_icall_System_IO_MonoIO_CreatePipe)
 ICALL(MONOIO_5, "DeleteFile(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_DeleteFile)
 #endif /* !PLATFORM_RO_FS */
+ICALL(MONOIO_38, "DumpHandles", ves_icall_System_IO_MonoIO_DumpHandles)
 ICALL(MONOIO_34, "DuplicateHandle", ves_icall_System_IO_MonoIO_DuplicateHandle)
 ICALL(MONOIO_37, "FindClose", ves_icall_System_IO_MonoIO_FindClose)
 ICALL(MONOIO_35, "FindFirst", ves_icall_System_IO_MonoIO_FindFirst)