diff src/ntheap.c @ 361:7347b34c275b r21-1-10

Import from CVS: tag r21-1-10
author cvs
date Mon, 13 Aug 2007 10:58:40 +0200
parents 8e84bee8ddd0
children 30d2cfa1092a
line wrap: on
line diff
--- a/src/ntheap.c	Mon Aug 13 10:57:57 2007 +0200
+++ b/src/ntheap.c	Mon Aug 13 10:58:40 2007 +0200
@@ -269,17 +269,44 @@
 void
 recreate_heap (char *executable_path)
 {
-  unsigned char *tmp;
+  /* First reserve the upper part of our heap.  (We reserve first
+	 because there have been problems in the past where doing the
+	 mapping first has loaded DLLs into the VA space of our heap.)  */
 
-  /* First reserve the upper part of our heap.  (We reserve first
-     because there have been problems in the past where doing the
-     mapping first has loaded DLLs into the VA space of our heap.)  */
-  tmp = VirtualAlloc ((void *) get_heap_end (),
-		      get_reserved_heap_size () - get_committed_heap_size (),
-		      MEM_RESERVE,
-		      PAGE_NOACCESS);
+  /* Query the region at the end of the committed heap */
+  void *tmp;
+  MEMORY_BASIC_INFORMATION info;
+  SIZE_T size;
+  unsigned char* base = get_heap_end ();
+  unsigned char* end  = base + get_reserved_heap_size () - get_committed_heap_size ();
+  VirtualQuery (base, &info, sizeof info);
+  if (info.State != MEM_FREE)
+	{
+	  /* Oops, something has already reserved or commited it, nothing we can do but exit */
+	  char buf[256];
+	  wsprintf(buf,
+			   "XEmacs cannot start because the memory region required by the heap is not available.\n"
+			   "(BaseAddress = 0x%lx, AllocationBase = 0x%lx, Size = 0x%lx, State = %s, Type = %s)",
+			   info.BaseAddress, info.AllocationBase, info.RegionSize,
+			   info.State == MEM_COMMIT ? "COMMITED" : "RESERVED",
+			   info.Type == MEM_IMAGE ? "IMAGE" : info.Type == MEM_MAPPED ? "MAPPED" : "PRIVATE");
+	  MessageBox(NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP);
+	  exit(1);
+	}
+
+  /* Now try and reserve as much as possible */
+  size = min (info.RegionSize, end - base);
+  tmp = VirtualAlloc (base, size, MEM_RESERVE, PAGE_NOACCESS);
   if (!tmp)
-    exit (1);
+	{
+	  /* Can't reserve it, nothing we can do but exit */
+	  char buf[256];
+	  wsprintf(buf,
+			   "XEmacs cannot start because it couldn't reserve space required for the heap.\n"
+			   "(VirtualAlloc at 0x%lx of 0x%lx failed (%d))", base, size, GetLastError());
+	  MessageBox(NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP);
+	  exit (1);
+	}
 
   /* We read in the data for the .bss section from the executable
      first and map in the heap from the executable second to prevent