perf maps: Add maps__refcnt() accessor to allow checking maps pointer

To remove one more direct access to 'struct maps' so that we can
intercept accesses to its instantiations and refcount check it to catch
use after free, etc.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 3ad1be6f
...@@ -43,7 +43,7 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s ...@@ -43,7 +43,7 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s
leader && t1 && t2 && t3 && other); leader && t1 && t2 && t3 && other);
maps = leader->maps; maps = leader->maps;
TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 4);
/* test the maps pointer is shared */ /* test the maps pointer is shared */
TEST_ASSERT_VAL("maps don't match", maps == t1->maps); TEST_ASSERT_VAL("maps don't match", maps == t1->maps);
...@@ -71,25 +71,25 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s ...@@ -71,25 +71,25 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s
machine__remove_thread(machine, other_leader); machine__remove_thread(machine, other_leader);
other_maps = other->maps; other_maps = other->maps;
TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 2);
TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps); TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps);
/* release thread group */ /* release thread group */
thread__put(leader); thread__put(leader);
TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 3);
thread__put(t1); thread__put(t1);
TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 2);
thread__put(t2); thread__put(t2);
TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 1);
thread__put(t3); thread__put(t3);
/* release other group */ /* release other group */
thread__put(other_leader); thread__put(other_leader);
TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 1);
thread__put(other); thread__put(other);
......
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
static void maps__init(struct maps *maps, struct machine *machine) static void maps__init(struct maps *maps, struct machine *machine)
{ {
refcount_set(maps__refcnt(maps), 1);
maps->entries = RB_ROOT; maps->entries = RB_ROOT;
init_rwsem(maps__lock(maps)); init_rwsem(maps__lock(maps));
maps->machine = machine; maps->machine = machine;
maps->last_search_by_name = NULL; maps->last_search_by_name = NULL;
maps->nr_maps = 0; maps->nr_maps = 0;
maps->maps_by_name = NULL; maps->maps_by_name = NULL;
refcount_set(&maps->refcnt, 1);
} }
static void __maps__free_maps_by_name(struct maps *maps) static void __maps__free_maps_by_name(struct maps *maps)
...@@ -180,14 +180,14 @@ void maps__delete(struct maps *maps) ...@@ -180,14 +180,14 @@ void maps__delete(struct maps *maps)
struct maps *maps__get(struct maps *maps) struct maps *maps__get(struct maps *maps)
{ {
if (maps) if (maps)
refcount_inc(&maps->refcnt); refcount_inc(maps__refcnt(maps));
return maps; return maps;
} }
void maps__put(struct maps *maps) void maps__put(struct maps *maps)
{ {
if (maps && refcount_dec_and_test(&maps->refcnt)) if (maps && refcount_dec_and_test(maps__refcnt(maps)))
maps__delete(maps); maps__delete(maps);
} }
......
...@@ -88,6 +88,11 @@ static inline unsigned int maps__nr_maps(const struct maps *maps) ...@@ -88,6 +88,11 @@ static inline unsigned int maps__nr_maps(const struct maps *maps)
return maps->nr_maps; return maps->nr_maps;
} }
static inline refcount_t *maps__refcnt(struct maps *maps)
{
return &maps->refcnt;
}
#ifdef HAVE_LIBUNWIND_SUPPORT #ifdef HAVE_LIBUNWIND_SUPPORT
static inline void *maps__addr_space(struct maps *maps) static inline void *maps__addr_space(struct maps *maps)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment