aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32heap.c
diff options
context:
space:
mode:
authorEli Zaretskii2014-05-30 12:02:55 +0300
committerEli Zaretskii2014-05-30 12:02:55 +0300
commit6c572f9ab3d028dbc399fc97ff8d8a9835be20fe (patch)
tree4d6846e1dddd574a1b890c6ffd424a0424270ae6 /src/w32heap.c
parent8d3103b1efd32a2faf257e26a5474e12543ce798 (diff)
downloademacs-6c572f9ab3d028dbc399fc97ff8d8a9835be20fe.tar.gz
emacs-6c572f9ab3d028dbc399fc97ff8d8a9835be20fe.zip
Enhance error checking in heap allocation routines on MS-Windows.
src/w32heap.c (malloc_before_dump, malloc_after_dump) (malloc_before_dump, realloc_after_dump, realloc_before_dump) (mmap_alloc, mmap_realloc): Check for errors more thoroughly and set errno where appropriate to emulate CRT functions.
Diffstat (limited to 'src/w32heap.c')
-rw-r--r--src/w32heap.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/src/w32heap.c b/src/w32heap.c
index be097901747..cc08dc37219 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -47,6 +47,7 @@
47 47
48#include <config.h> 48#include <config.h>
49#include <stdio.h> 49#include <stdio.h>
50#include <errno.h>
50 51
51#include <sys/mman.h> 52#include <sys/mman.h>
52#include "w32common.h" 53#include "w32common.h"
@@ -241,7 +242,8 @@ init_heap (void)
241 if (s_pfn_Heap_Set_Information ((PVOID) heap, 242 if (s_pfn_Heap_Set_Information ((PVOID) heap,
242 HeapCompatibilityInformation, 243 HeapCompatibilityInformation,
243 &enable_lfh, sizeof(enable_lfh)) == 0) 244 &enable_lfh, sizeof(enable_lfh)) == 0)
244 DebPrint (("Enabling Low Fragmentation Heap failed\n")); 245 DebPrint (("Enabling Low Fragmentation Heap failed: error %ld\n",
246 GetLastError ()));
245#endif 247#endif
246 248
247 the_malloc_fn = malloc_after_dump; 249 the_malloc_fn = malloc_after_dump;
@@ -298,7 +300,10 @@ malloc_after_dump (size_t size)
298 void *p = HeapAlloc (heap, 0, size); 300 void *p = HeapAlloc (heap, 0, size);
299 301
300 /* After dump, keep track of the last allocated byte for sbrk(0). */ 302 /* After dump, keep track of the last allocated byte for sbrk(0). */
301 data_region_end = p + size - 1; 303 if (p)
304 data_region_end = p + size - 1;
305 else
306 errno = ENOMEM;
302 return p; 307 return p;
303} 308}
304 309
@@ -313,6 +318,8 @@ malloc_before_dump (size_t size)
313 { 318 {
314 /* Use the private heap if possible. */ 319 /* Use the private heap if possible. */
315 p = HeapAlloc (heap, 0, size); 320 p = HeapAlloc (heap, 0, size);
321 if (!p)
322 errno = ENOMEM;
316 } 323 }
317 else 324 else
318 { 325 {
@@ -371,16 +378,22 @@ realloc_after_dump (void *ptr, size_t size)
371 { 378 {
372 /* Reallocate the block since it lies in the new heap. */ 379 /* Reallocate the block since it lies in the new heap. */
373 p = HeapReAlloc (heap, 0, ptr, size); 380 p = HeapReAlloc (heap, 0, ptr, size);
381 if (!p)
382 errno = ENOMEM;
374 } 383 }
375 else 384 else
376 { 385 {
377 /* If the block lies in the dumped data, do not free it. Only 386 /* If the block lies in the dumped data, do not free it. Only
378 allocate a new one. */ 387 allocate a new one. */
379 p = HeapAlloc (heap, 0, size); 388 p = HeapAlloc (heap, 0, size);
380 CopyMemory (p, ptr, size); 389 if (p)
390 CopyMemory (p, ptr, size);
391 else
392 errno = ENOMEM;
381 } 393 }
382 /* After dump, keep track of the last allocated byte for sbrk(0). */ 394 /* After dump, keep track of the last allocated byte for sbrk(0). */
383 data_region_end = p + size - 1; 395 if (p)
396 data_region_end = p + size - 1;
384 return p; 397 return p;
385} 398}
386 399
@@ -392,7 +405,11 @@ realloc_before_dump (void *ptr, size_t size)
392 /* Before dumping. */ 405 /* Before dumping. */
393 if (dumped_data < (unsigned char *)ptr 406 if (dumped_data < (unsigned char *)ptr
394 && (unsigned char *)ptr < bc_limit && size <= MaxBlockSize) 407 && (unsigned char *)ptr < bc_limit && size <= MaxBlockSize)
395 p = HeapReAlloc (heap, 0, ptr, size); 408 {
409 p = HeapReAlloc (heap, 0, ptr, size);
410 if (!p)
411 errno = ENOMEM;
412 }
396 else 413 else
397 { 414 {
398 /* In this case, either the new block is too large for the heap, 415 /* In this case, either the new block is too large for the heap,
@@ -400,8 +417,11 @@ realloc_before_dump (void *ptr, size_t size)
400 malloc_before_dump() and free_before_dump() will take care of 417 malloc_before_dump() and free_before_dump() will take care of
401 reallocation. */ 418 reallocation. */
402 p = malloc_before_dump (size); 419 p = malloc_before_dump (size);
403 CopyMemory (p, ptr, size); 420 if (p)
404 free_before_dump (ptr); 421 {
422 CopyMemory (p, ptr, size);
423 free_before_dump (ptr);
424 }
405 } 425 }
406 return p; 426 return p;
407} 427}
@@ -508,8 +528,16 @@ mmap_alloc (void **var, size_t nbytes)
508 *var = VirtualAlloc (p, nbytes, MEM_COMMIT, PAGE_READWRITE); 528 *var = VirtualAlloc (p, nbytes, MEM_COMMIT, PAGE_READWRITE);
509 } 529 }
510 530
511 if (!p && GetLastError () != ERROR_NOT_ENOUGH_MEMORY) 531 if (!p)
512 DebPrint (("mmap_alloc: error %ld\n", GetLastError())); 532 {
533 if (GetLastError () == ERROR_NOT_ENOUGH_MEMORY)
534 errno = ENOMEM;
535 else
536 {
537 DebPrint (("mmap_alloc: error %ld\n", GetLastError ()));
538 errno = EINVAL;
539 }
540 }
513 541
514 return *var = p; 542 return *var = p;
515} 543}
@@ -520,7 +548,7 @@ mmap_free (void **var)
520 if (*var) 548 if (*var)
521 { 549 {
522 if (VirtualFree (*var, 0, MEM_RELEASE) == 0) 550 if (VirtualFree (*var, 0, MEM_RELEASE) == 0)
523 DebPrint (("mmap_free: error %ld\n", GetLastError())); 551 DebPrint (("mmap_free: error %ld\n", GetLastError ()));
524 *var = NULL; 552 *var = NULL;
525 } 553 }
526} 554}
@@ -541,13 +569,14 @@ mmap_realloc (void **var, size_t nbytes)
541 } 569 }
542 570
543 if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0) 571 if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0)
544 DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError())); 572 DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ()));
545 573
546 /* We need to enlarge the block. */ 574 /* We need to enlarge the block. */
547 if (memInfo.RegionSize < nbytes) 575 if (memInfo.RegionSize < nbytes)
548 { 576 {
549 if (VirtualQuery (*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0) 577 if (VirtualQuery (*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0)
550 DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError())); 578 DebPrint (("mmap_realloc: VirtualQuery error = %ld\n",
579 GetLastError ()));
551 /* If there is enough room in the current reserved area, then 580 /* If there is enough room in the current reserved area, then
552 commit more pages as needed. */ 581 commit more pages as needed. */
553 if (m2.State == MEM_RESERVE 582 if (m2.State == MEM_RESERVE
@@ -559,8 +588,11 @@ mmap_realloc (void **var, size_t nbytes)
559 nbytes - memInfo.RegionSize, 588 nbytes - memInfo.RegionSize,
560 MEM_COMMIT, PAGE_READWRITE); 589 MEM_COMMIT, PAGE_READWRITE);
561 if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */) 590 if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */)
562 DebPrint (("realloc enlarge: VirtualAlloc error %ld\n", 591 {
563 GetLastError())); 592 DebPrint (("realloc enlarge: VirtualAlloc error %ld\n",
593 GetLastError ()));
594 errno = ENOMEM;
595 }
564 return *var; 596 return *var;
565 } 597 }
566 else 598 else
@@ -615,7 +647,7 @@ mmap_realloc (void **var, size_t nbytes)
615 if (VirtualFree (*var + nbytes + get_page_size(), 647 if (VirtualFree (*var + nbytes + get_page_size(),
616 memInfo.RegionSize - nbytes - get_page_size(), 648 memInfo.RegionSize - nbytes - get_page_size(),
617 MEM_DECOMMIT) == 0) 649 MEM_DECOMMIT) == 0)
618 DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError())); 650 DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError ()));
619 return *var; 651 return *var;
620 } 652 }
621 653