Thank you for this patch. It has been applied to the 21.1 branch of
XEmacs and will appear in XEmacs 21.1.12.
- vin
>>>>> On Thu, 27 Jul 2000, "Alastair J. Houghton" <ajhoughton(a)lineone.net> said:
Alastair> Here's a patch that reindents some of ntheap.c (it seems
Alastair> some horrible oik decided to use Visual C's internal
Alastair> editor or something) and adds a call to GetModuleFileName
Alastair> to the code that gets run when XEmacs can't allocate its
Alastair> heap; the idea is that instead of
Alastair> XEmacs cannot start because the memory region required
Alastair> by the heap is not available
Alastair> (BaseAddress = 0x12345678, AllocationBase = 0x12345678,
Alastair> Size = 0x12345678, State = COMMITED, Type = IMAGE)
Alastair> you actually get told which image is responsible:
Alastair> XEmacs cannot start because the memory region required
Alastair> by the heap is not available
Alastair> (BaseAddress = 0x12345678, Allocationbase = 0x12345678,
Alastair> Size = 0x12345678, State = COMMITED, Type = IMAGE,
Alastair> ModuleName = "AWKWARD.DLL")
Alastair> Could someone with a test setup that does break in this
Alastair> fashion please verify that this works correctly *before*
Alastair> anyone applies it? I don't have any easy way of breaking
Alastair> it like this.
Alastair> Kind regards,
Alastair> Alastair.
Alastair> --- ntheap.c Tue May 9 10:18:48 2000
Alastair> +++ xemacs-21.2/src/ntheap.c Thu Jul 27 10:34:09 2000
Alastair> @@ -228,8 +228,8 @@
Alastair> recreate_heap (char *executable_path)
Alastair> {
Alastair> /* First reserve the upper part of our heap. (We reserve first
Alastair> - because there have been problems in the past where doing the
Alastair> - mapping first has loaded DLLs into the VA space of our heap.) */
Alastair> + because there have been problems in the past where doing the
Alastair> + mapping first has loaded DLLs into the VA space of our heap.) */
Alastair> /* Query the region at the end of the committed heap */
Alastair> void *tmp;
Alastair> @@ -239,32 +239,48 @@
Alastair> unsigned char* end = base + get_reserved_heap_size () -
Alastair> get_committed_heap_size ();
Alastair> VirtualQuery (base, &info, sizeof info);
Alastair> if (info.State != MEM_FREE)
Alastair> - {
Alastair> - /* Oops, something has already reserved or commited it, nothing we can
Alastair> do but exit */
Alastair> - char buf[256];
Alastair> - wsprintf(buf,
Alastair> - "XEmacs cannot start because the memory region required by the heap
Alastair> is not available.\n"
Alastair> - "(BaseAddress = 0x%lx, AllocationBase = 0x%lx, Size = 0x%lx, State =
Alastair> %s, Type = %s)",
Alastair> - info.BaseAddress, info.AllocationBase, info.RegionSize,
Alastair> - info.State == MEM_COMMIT ? "COMMITED" : "RESERVED",
Alastair> - info.Type == MEM_IMAGE ? "IMAGE" : info.Type == MEM_MAPPED ? "MAPPED"
Alastair> : "PRIVATE");
Alastair> - MessageBox(NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP);
Alastair> - exit(1);
Alastair> - }
Alastair> + {
Alastair> + /* Oops, something has already reserved or commited it, nothing we
Alastair> can do but exit */
Alastair> + char buf[256];
Alastair> + char modnambuf[80];
Alastair> +
Alastair> + /* Find the filename of any DLL mapped at that address. This is a bit
Alastair> + of a hack in that it relies on HMODULEs being pointers to the image
Alastair> + base. However, this will almost certainly be the case for the
Alastair> + forseeable future in MS operating systems.
Alastair> +
Alastair> + Note that we don't check for MEM_IMAGE first because it doesn't
Alastair> + exist on Win95 AFAIK - ajh */
Alastair> + if (!GetModuleFileName ((HMODULE) info.AllocationBase,
Alastair> + modnambuf,
Alastair> + sizeof (modnambuf)))
Alastair> + strcpy (modnambuf, "<unknown>");
Alastair> +
Alastair> + wsprintf(buf,
Alastair> + "XEmacs cannot start because the memory region required by the heap
Alastair> is not available.\n"
Alastair> + "(BaseAddress = 0x%lx, AllocationBase = 0x%lx, Size = 0x%lx, State
Alastair> = %s, Type = %s, ModuleName = \"%s\")",
Alastair> + info.BaseAddress, info.AllocationBase, info.RegionSize,
Alastair> + info.State == MEM_COMMIT ? "COMMITED" : "RESERVED",
Alastair> + info.Type == MEM_IMAGE ? "IMAGE" : info.Type == MEM_MAPPED ?
Alastair> "MAPPED" : "PRIVATE",
Alastair> + modnambuf);
Alastair> +
Alastair> + MessageBox(NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP);
Alastair> + exit(1);
Alastair> + }
Alastair> /* Now try and reserve as much as possible */
Alastair> size = min (info.RegionSize, end - base);
Alastair> tmp = VirtualAlloc (base, size, MEM_RESERVE, PAGE_NOACCESS);
Alastair> if (!tmp)
Alastair> - {
Alastair> - /* Can't reserve it, nothing we can do but exit */
Alastair> - char buf[256];
Alastair> - wsprintf(buf,
Alastair> - "XEmacs cannot start because it couldn't reserve space required for
Alastair> the heap.\n"
Alastair> - "(VirtualAlloc at 0x%lx of 0x%lx failed (%d))", base, size,
Alastair> GetLastError());
Alastair> - MessageBox(NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP);
Alastair> - exit (1);
Alastair> - }
Alastair> + {
Alastair> + /* Can't reserve it, nothing we can do but exit */
Alastair> + char buf[256];
Alastair> + wsprintf(buf,
Alastair> + "XEmacs cannot start because it couldn't reserve space required for
Alastair> the heap.\n"
Alastair> + "(VirtualAlloc at 0x%lx of 0x%lx failed (%d))", base, size,
Alastair> GetLastError());
Alastair> + MessageBox(NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP);
Alastair> + exit (1);
Alastair> + }
Alastair> /* We read in the data for the .bss section from the executable
Alastair> first and map in the heap from the executable second to prevent
Alastair> --
Alastair> ____________________________________________________________
Alastair> Alastair Houghton ajhoughton(a)lineone.net