summaryrefslogtreecommitdiff
path: root/malloc.c
diff options
context:
space:
mode:
authorHans Boehm <boehm@acm.org>2018-02-26 23:45:24 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-02-26 23:45:24 +0300
commitf9c5815c132223139fc348166d861403e2196f47 (patch)
treee7d4631d3555c611acf5709389b1d1cb2a90dccf /malloc.c
parent16c55506c5222ef40eba1e4aedf200358421080d (diff)
downloadbdwgc-f9c5815c132223139fc348166d861403e2196f47.tar.gz
Avoid potential race when accessing size_map table
There is again a data race between GC_extend_size_map and GC_size_map[] readers, though it is again not likely to fail in practice. It is feasible to just move all of the GC_size_map accesses under the lock, and this does not look to incur a substantial penalty. * gcj_mlc.c (GC_gcj_malloc, GC_gcj_malloc_ignore_off_page): Move lg=GC_size_map[lb] to be right after LOCK() instead of preceding it. * malloc.c (GC_malloc_kind_global, GC_generic_malloc_uncollectable): Likewise. * typd_mlc.c (GC_malloc_explicitly_typed_ignore_off_page): Likewise. * include/gc.h (GC_get_size_map_at): Update comment to note that the client should use synchronization when calling the function. * include/private/gc_priv.h (_GC_arrays._size_map): Add comment about synchronization.
Diffstat (limited to 'malloc.c')
-rw-r--r--malloc.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/malloc.c b/malloc.c
index 25ca72f7..0155fa5a 100644
--- a/malloc.c
+++ b/malloc.c
@@ -300,11 +300,12 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_kind_global(size_t lb, int k)
if (SMALL_OBJ(lb)) {
void *op;
void **opp;
- size_t lg = GC_size_map[lb];
+ size_t lg;
DCL_LOCK_STATE;
GC_DBG_COLLECT_AT_MALLOC(lb);
LOCK();
+ lg = GC_size_map[lb];
opp = &GC_obj_kinds[k].ok_freelist[lg];
op = *opp;
if (EXPECT(op != NULL, TRUE)) {
@@ -365,8 +366,8 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc_uncollectable(
if (EXTRA_BYTES != 0 && lb != 0) lb--;
/* We don't need the extra byte, since this won't be */
/* collected anyway. */
- lg = GC_size_map[lb];
LOCK();
+ lg = GC_size_map[lb];
opp = &GC_obj_kinds[k].ok_freelist[lg];
op = *opp;
if (EXPECT(op != NULL, TRUE)) {