summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-06-26 16:55:42 +0400
committerIvan Maidanski <ivmai@mail.ru>2012-06-26 16:55:42 +0400
commit94199d1d94e535c1770ce97c73e62107405f9085 (patch)
treea294f9435b05c010146e2b8b1a4f0a240ef382e4
parentf055ed20942e8ab3a9d101d6d77470d54ae968a0 (diff)
parent98176e156503cc43cb9a5ff6d252fff0bdbf7995 (diff)
downloadbdwgc-94199d1d94e535c1770ce97c73e62107405f9085.tar.gz
Merge branch 'gc-7_2-hotfix-2'
-rw-r--r--ChangeLog43
-rw-r--r--cord/cordbscs.c1
-rw-r--r--dyn_load.c10
-rw-r--r--headers.c4
-rw-r--r--include/private/gc_priv.h16
-rw-r--r--mark.c8
-rw-r--r--os_dep.c11
7 files changed, 79 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 0e6c8db8..e6f3b14a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+2012-06-08 Ivan Maidanski <ivmai@mail.ru>
+
+ * cordbscs.c (CORD_cat_char_star): Check GC_MALLOC_ATOMIC result for
+ NULL (do OUT_OF_MEMORY in such case) to prevent SEGV.
+
+2012-06-07 Ivan Maidanski <ivmai@mail.ru>
+
+ * 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).
+
+2012-06-02 Ivan Maidanski <ivmai@mail.ru>
+
+ * include/private/gc_priv.h (GC_push_all, GC_push_other_roots):
+ Declare as GC_API_PRIV (instead of GC_INNER) to make the symbol
+ externally visible to some well-known 3rd-party software (e.g., ECL).
+ * include/private/gc_priv.h (GC_push_conditional): Declare as
+ GC_API_PRIV (only if GC_DISABLE_INCREMENTAL is undefined).
+ * mark.c (GC_push_all, GC_push_conditional): Remove GC_INNER (to match
+ the declaration).
+ * os_dep.c (GC_push_other_roots): Likewise.
+
+2012-06-02 Ivan Maidanski <ivmai@mail.ru>
+
+ * include/private/gc_priv.h (GC_clear_mark_bit, GC_set_mark_bit):
+ Declare as GC_API_PRIV (instead of GC_INNER) to make the symbol
+ externally visible to 3rd-party software (e.g., ECL).
+ * mark.c (GC_set_mark_bit, GC_clear_mark_bit): Remove GC_INNER (to
+ match the declaration).
+
+2012-06-01 Tsugutomo Enami <tsugutomo.enami@jp.sony.com>
+
+ * dyn_load.c: Include sys/param.h and dlfcn.h on NetBSD.
+ * dyn_load.c (GC_FirstDLOpenedLinkMap): Obtain link map using dlinfo()
+ on NetBSD if RTLD_DI_LINKMAP feature present (defined).
+
[7.2b]
2012-05-23 Ivan Maidanski <ivmai@mail.ru>
diff --git a/cord/cordbscs.c b/cord/cordbscs.c
index 924bf445..5128daf5 100644
--- a/cord/cordbscs.c
+++ b/cord/cordbscs.c
@@ -188,6 +188,7 @@ CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
result_len = right_len + leny; /* length of new_right */
if (result_len <= SHORT_LIMIT) {
new_right = GC_MALLOC_ATOMIC(result_len + 1);
+ if (new_right == 0) OUT_OF_MEMORY;
memcpy(new_right, right, right_len);
memcpy(new_right + right_len, y, leny);
new_right[result_len] = '\0';
diff --git a/dyn_load.c b/dyn_load.c
index ce45ee27..39efc9b2 100644
--- a/dyn_load.c
+++ b/dyn_load.c
@@ -77,6 +77,8 @@ STATIC GC_has_static_roots_func GC_has_static_roots = 0;
#endif
#if defined(NETBSD)
+# include <sys/param.h>
+# include <dlfcn.h>
# include <machine/elf_machdep.h>
# define ELFSIZE ARCH_ELFSIZE
#endif
@@ -644,6 +646,11 @@ GC_FirstDLOpenedLinkMap(void)
return(0);
}
if( cachedResult == 0 ) {
+# if defined(NETBSD) && defined(RTLD_DI_LINKMAP)
+ struct link_map *lm = NULL;
+ if (!dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm))
+ cachedResult = lm;
+# else
int tag;
for( dp = _DYNAMIC; (tag = dp->d_tag) != 0; dp++ ) {
if( tag == DT_DEBUG ) {
@@ -653,6 +660,7 @@ GC_FirstDLOpenedLinkMap(void)
break;
}
}
+# endif /* !NETBSD || !RTLD_DI_LINKMAP */
}
return cachedResult;
}
@@ -752,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",
diff --git a/headers.c b/headers.c
index de82c204..eac3e9f0 100644
--- a/headers.c
+++ b/headers.c
@@ -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 8eefb70e..b44347fe 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -1428,11 +1428,11 @@ GC_INNER void GC_initiate_gc(void);
GC_INNER GC_bool GC_collection_in_progress(void);
/* Collection is in progress, or was abandoned. */
-GC_INNER void GC_push_all(ptr_t bottom, ptr_t top);
+GC_API_PRIV void GC_push_all(ptr_t bottom, ptr_t top);
/* Push everything in a range */
/* onto mark stack. */
#ifndef GC_DISABLE_INCREMENTAL
- GC_INNER void GC_push_conditional(ptr_t b, ptr_t t, GC_bool all);
+ GC_API_PRIV void GC_push_conditional(ptr_t b, ptr_t t, GC_bool all);
#else
# define GC_push_conditional(b, t, all) GC_push_all(b, t)
#endif
@@ -1456,13 +1456,15 @@ GC_INNER void GC_push_all_eager(ptr_t b, ptr_t t);
GC_INNER void GC_push_roots(GC_bool all, ptr_t cold_gc_frame);
/* Push all or dirty roots. */
-GC_EXTERN void (*GC_push_other_roots)(void);
+GC_API_PRIV void (*GC_push_other_roots)(void);
/* Push system or application specific roots */
/* onto the mark stack. In some environments */
/* (e.g. threads environments) this is */
/* predefined to be non-zero. A client */
/* supplied replacement should also call the */
- /* original function. */
+ /* original function. Remains externally */
+ /* visible as used by some well-known 3rd-party */
+ /* software (e.g., ECL) currently. */
GC_INNER void GC_push_finalizer_structures(void);
#ifdef THREADS
@@ -1587,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);
@@ -1905,8 +1907,8 @@ GC_EXTERN GC_bool GC_print_back_height;
/* Slow/general mark bit manipulation: */
GC_API_PRIV GC_bool GC_is_marked(ptr_t p);
-GC_INNER void GC_clear_mark_bit(ptr_t p);
-GC_INNER void GC_set_mark_bit(ptr_t p);
+GC_API_PRIV void GC_clear_mark_bit(ptr_t p);
+GC_API_PRIV void GC_set_mark_bit(ptr_t p);
/* Stubborn objects: */
void GC_read_changed(void); /* Analogous to GC_read_dirty */
diff --git a/mark.c b/mark.c
index 41a7af52..cc8dfde9 100644
--- a/mark.c
+++ b/mark.c
@@ -187,7 +187,7 @@ static void clear_marks_for_block(struct hblk *h, word dummy)
}
/* Slow but general routines for setting/clearing/asking about mark bits */
-GC_INNER void GC_set_mark_bit(ptr_t p)
+void GC_set_mark_bit(ptr_t p)
{
struct hblk *h = HBLKPTR(p);
hdr * hhdr = HDR(h);
@@ -199,7 +199,7 @@ GC_INNER void GC_set_mark_bit(ptr_t p)
}
}
-GC_INNER void GC_clear_mark_bit(ptr_t p)
+void GC_clear_mark_bit(ptr_t p)
{
struct hblk *h = HBLKPTR(p);
hdr * hhdr = HDR(h);
@@ -1259,7 +1259,7 @@ GC_INNER void GC_mark_init(void)
* Should only be used if there is no possibility of mark stack
* overflow.
*/
-GC_INNER void GC_push_all(ptr_t bottom, ptr_t top)
+void GC_push_all(ptr_t bottom, ptr_t top)
{
register word length;
@@ -1332,7 +1332,7 @@ GC_INNER void GC_push_all(ptr_t bottom, ptr_t top)
}
}
- GC_INNER void GC_push_conditional(ptr_t bottom, ptr_t top, GC_bool all)
+ void GC_push_conditional(ptr_t bottom, ptr_t top, GC_bool all)
{
if (!all) {
GC_push_selected(bottom, top, GC_page_was_dirty);
diff --git a/os_dep.c b/os_dep.c
index 17dabcdd..333421d4 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -2523,7 +2523,7 @@ GC_INNER void GC_unmap_gap(ptr_t start1, size_t bytes1, ptr_t start2,
/* environment, this is also responsible for marking from */
/* thread stacks. */
#ifndef THREADS
- GC_INNER void (*GC_push_other_roots)(void) = 0;
+ void (*GC_push_other_roots)(void) = 0;
#else /* THREADS */
# ifdef PCR
@@ -2587,7 +2587,7 @@ STATIC void GC_default_push_other_roots(void)
}
# endif /* SN_TARGET_PS3 */
- GC_INNER void (*GC_push_other_roots)(void) = GC_default_push_other_roots;
+ void (*GC_push_other_roots)(void) = GC_default_push_other_roots;
#endif /* THREADS */
/*
@@ -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 */