diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-06-07 22:00:37 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-06-07 22:56:33 +0400 |
commit | 1de90aeb38a078550f9b22a5900f959e6dcbd37b (patch) | |
tree | 52aa63e26fd3ae741bfa1a530397e1105d8cdfef | |
parent | a237b23befdb0dd75dff2727a2a5c0d66bc96f04 (diff) | |
download | bdwgc-1de90aeb38a078550f9b22a5900f959e6dcbd37b.tar.gz |
Fix GC_scratch_alloc and GC_get_maps invocations to prevent SEGV
(if out of memory)
* dyn_load.c (GC_register_dynamic_libraries): If GC_scratch_alloc
fails (returns null) then abort (with the appropriate message) instead
of causing SEGV.
* os_dep.c (GC_dirty_init): Likewise.
* headers.c (GC_init_headers): Report error and exit if
GC_scratch_alloc fails.
* include/private/gc_priv.h (GC_scratch_alloc): Improve comment.
* os_dep.c (GC_print_address_map): If GC_get_maps return null then
print the appropriate message (instead of passing null to GC_err_puts
thus causing SEGV).
-rw-r--r-- | dyn_load.c | 2 | ||||
-rw-r--r-- | headers.c | 4 | ||||
-rw-r--r-- | include/private/gc_priv.h | 2 | ||||
-rw-r--r-- | os_dep.c | 7 |
4 files changed, 13 insertions, 2 deletions
@@ -760,6 +760,8 @@ GC_INNER void GC_register_dynamic_libraries(void) /* Expansion, plus room for 0 record */ addr_map = (prmap_t *)GC_scratch_alloc( (word)current_sz * sizeof(prmap_t)); + if (addr_map == NULL) + ABORT("Insufficient memory for address map"); } if (ioctl(fd, PIOCMAP, addr_map) < 0) { GC_err_printf("fd = %d, errno = %d, needed_sz = %d, addr_map = %p\n", @@ -196,6 +196,10 @@ GC_INNER void GC_init_headers(void) register unsigned i; GC_all_nils = (bottom_index *)GC_scratch_alloc((word)sizeof(bottom_index)); + if (GC_all_nils == NULL) { + GC_err_printf("Insufficient memory for GC_all_nils\n"); + EXIT(); + } BZERO(GC_all_nils, sizeof(bottom_index)); for (i = 0; i < TOP_SZ; i++) { GC_top_index[i] = GC_all_nils; diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 9d728a9a..b44347fe 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1589,7 +1589,7 @@ GC_INNER void GC_unpromote_black_lists(void); GC_INNER ptr_t GC_scratch_alloc(size_t bytes); /* GC internal memory allocation for */ /* small objects. Deallocation is not */ - /* possible. */ + /* possible. May return NULL. */ /* Heap block layout maps: */ GC_INNER GC_bool GC_add_map_entry(size_t sz); @@ -3641,6 +3641,8 @@ GC_INNER void GC_dirty_init(void) GC_dirty_maintained = TRUE; GC_proc_buf = GC_scratch_alloc(GC_proc_buf_size); + if (GC_proc_buf == NULL) + ABORT("Insufficient space for /proc read"); } # define READ read @@ -4724,8 +4726,11 @@ GC_INNER void GC_print_callers(struct callinfo info[NFRAMES]) /* addresses in FIND_LEAK output. */ void GC_print_address_map(void) { + char *maps; + GC_err_printf("---------- Begin address map ----------\n"); - GC_err_puts(GC_get_maps()); + maps = GC_get_maps(); + GC_err_puts(maps != NULL ? maps : "Failed to get map!\n"); GC_err_printf("---------- End address map ----------\n"); } #endif /* LINUX && ELF */ |