From: John L. <mov...@us...> - 2006-03-19 18:58:30
|
Update of /cvsroot/oprofile/oprofile/daemon In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16468/daemon Modified Files: opd_anon.c opd_sfile.c opd_sfile.h Log Message: anon double free fix Index: opd_anon.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/daemon/opd_anon.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -p -d -r1.3 -r1.4 --- opd_anon.c 9 Aug 2005 12:49:06 -0000 1.3 +++ opd_anon.c 19 Mar 2006 18:58:22 -0000 1.4 @@ -36,10 +36,6 @@ static struct list_head hashes[HASH_SIZE static struct list_head lru; static size_t nr_lru; -/* never called in buffer-processing context, so we don't need - * to update struct transient. Note the 'U' of LRU is based on - * parsing time, not actual use. - */ static void do_lru(struct transient * trans) { size_t nr_to_kill = LRU_AMOUNT; @@ -55,13 +51,12 @@ static void do_lru(struct transient * tr clear_trans_last(trans); list_del(&entry->list); list_del(&entry->lru_list); + sfile_clear_anon(entry); --nr_lru; free(entry); if (nr_to_kill-- == 0) break; } - - sfile_clear_anon(); } @@ -87,6 +82,7 @@ static void clear_anon_maps(struct trans if (entry->tgid == tgid && entry->app_cookie == app) { if (trans->last_anon == entry) clear_trans_last(trans); + sfile_clear_anon(entry); list_del(&entry->list); list_del(&entry->lru_list); --nr_lru; @@ -94,7 +90,6 @@ static void clear_anon_maps(struct trans } } - sfile_clear_anon(); if (vmisc) { char const * name = verbose_cookie(app); printf("Cleared anon maps for tgid %u (%s).\n", tgid, name); Index: opd_sfile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/daemon/opd_sfile.c,v retrieving revision 1.36 retrieving revision 1.37 diff -u -p -d -r1.36 -r1.37 --- opd_sfile.c 17 Aug 2005 19:15:41 -0000 1.36 +++ opd_sfile.c 19 Mar 2006 18:58:22 -0000 1.37 @@ -446,7 +446,7 @@ void sfile_log_sample(struct transient c } -static int close_sfile(struct sfile * sf) +static int close_sfile(struct sfile * sf, void * data __attribute__((unused))) { size_t i; @@ -460,13 +460,13 @@ static int close_sfile(struct sfile * sf static void kill_sfile(struct sfile * sf) { - close_sfile(sf); + close_sfile(sf, NULL); list_del(&sf->hash); list_del(&sf->lru); } -static int sync_sfile(struct sfile * sf) +static int sync_sfile(struct sfile * sf, void * data __attribute__((unused))) { size_t i; @@ -477,22 +477,25 @@ static int sync_sfile(struct sfile * sf) } -static int is_sfile_kernel(struct sfile * sf) +static int is_sfile_kernel(struct sfile * sf, void * data __attribute__((unused))) { return !!sf->kernel; } -static int is_sfile_anon(struct sfile * sf) +static int is_sfile_anon(struct sfile * sf, void * data) { - return !!sf->anon; + return sf->anon == data; } -static void for_one_sfile(struct sfile * sf, int (*func)(struct sfile *)) +typedef int (*sfile_func)(struct sfile *, void *); + +static void +for_one_sfile(struct sfile * sf, sfile_func func, void * data) { size_t i; - int free_sf = func(sf); + int free_sf = func(sf, data); for (i = 0; i < CG_HASH_SIZE; ++i) { struct list_head * pos; @@ -500,7 +503,7 @@ static void for_one_sfile(struct sfile * list_for_each_safe(pos, pos2, &sf->cg_hash[i]) { struct cg_entry * cg = list_entry(pos, struct cg_entry, hash); - if (free_sf || func(&cg->to)) { + if (free_sf || func(&cg->to, data)) { kill_sfile(&cg->to); list_del(&cg->hash); free(cg); @@ -515,39 +518,39 @@ static void for_one_sfile(struct sfile * } -static void for_each_sfile(int (*func)(struct sfile *)) +static void for_each_sfile(sfile_func func, void * data) { struct list_head * pos; struct list_head * pos2; list_for_each_safe(pos, pos2, &lru_list) { struct sfile * sf = list_entry(pos, struct sfile, lru); - for_one_sfile(sf, func); + for_one_sfile(sf, func, data); } } void sfile_clear_kernel(void) { - for_each_sfile(is_sfile_kernel); + for_each_sfile(is_sfile_kernel, NULL); } -void sfile_clear_anon(void) +void sfile_clear_anon(struct anon_mapping *anon) { - for_each_sfile(is_sfile_anon); + for_each_sfile(is_sfile_anon, anon); } void sfile_sync_files(void) { - for_each_sfile(sync_sfile); + for_each_sfile(sync_sfile, NULL); } void sfile_close_files(void) { - for_each_sfile(close_sfile); + for_each_sfile(close_sfile, NULL); } @@ -578,7 +581,7 @@ int sfile_lru_clear(void) if (!--amount) break; sf = list_entry(pos, struct sfile, lru); - for_one_sfile(sf, (int (*)(struct sfile *))always_true); + for_one_sfile(sf, (sfile_func)always_true, NULL); } return 0; Index: opd_sfile.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/daemon/opd_sfile.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -p -d -r1.11 -r1.12 --- opd_sfile.h 2 May 2005 15:06:58 -0000 1.11 +++ opd_sfile.h 19 Mar 2006 18:58:22 -0000 1.12 @@ -74,8 +74,10 @@ struct cg_entry { /** clear any sfiles that are for the kernel */ void sfile_clear_kernel(void); -/** clear any sfiles that are for anon mappings */ -void sfile_clear_anon(void); +struct anon_mapping; + +/** clear any sfiles for the given anon mapping */ +void sfile_clear_anon(struct anon_mapping *); /** sync sample files */ void sfile_sync_files(void); |