rcorder(8) dumps core
YONETANI Tomokazu
qhwt+freebsd-current at les.ath.cx
Thu Sep 16 22:55:57 PDT 2004
On Tue, Sep 14, 2004 at 05:52:12PM +0200, Lukas Ertl wrote:
> today I noticed a problem with rcorder on a very recent -CURRENT:
>
> [root at korben ~]# rcorder -k FreeBSD -s nostart -d /etc/rc.d/*
[snip]
> rcorder in free(): error: chunk is already free
> Abort trap (core dumped)
Core dump from double-free can be avoided by not free()'ing req_list
and prov_list in iterations where it's already in progress. It doesn't
solve circular dependency itself, though.
Index: sbin/rcorder/rcorder.c
===================================================================
RCS file: /home/source/freebsd/cvs/src/sbin/rcorder/rcorder.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 rcorder.c
--- sbin/rcorder/rcorder.c 21 Jun 2002 15:56:16 -0000 1.1.1.2
+++ sbin/rcorder/rcorder.c 17 Sep 2004 05:51:24 -0000
@@ -723,8 +723,8 @@
do_file(fnode)
filenode *fnode;
{
- f_reqnode *r, *r_tmp;
- f_provnode *p, *p_tmp;
+ f_reqnode *r, *r_next;
+ f_provnode *p, *p_next;
provnode *pnode;
int was_set;
@@ -748,22 +748,17 @@
* for each requirement of fnode -> r
* satisfy_req(r, filename)
*/
- r = fnode->req_list;
- while (r != NULL) {
- r_tmp = r;
+ for (r = fnode->req_list; r != NULL; r = r_next) {
+ r_next = r->next;
satisfy_req(r, fnode->filename);
- r = r->next;
- free(r_tmp);
}
- fnode->req_list = NULL;
/*
* for each provision of fnode -> p
* remove fnode from provision list for p in hash table
*/
- p = fnode->prov_list;
- while (p != NULL) {
- p_tmp = p;
+ for (p = fnode->prov_list; p != NULL; p = p_next) {
+ p_next = p->next;
pnode = p->pnode;
if (pnode->next != NULL) {
pnode->next->last = pnode->last;
@@ -771,11 +766,7 @@
if (pnode->last != NULL) {
pnode->last->next = pnode->next;
}
- free(pnode);
- p = p->next;
- free(p_tmp);
}
- fnode->prov_list = NULL;
/* do_it(fnode) */
DPRINTF((stderr, "next do: "));
@@ -792,8 +783,19 @@
}
DPRINTF((stderr, "nuking %s\n", fnode->filename));
- free(fnode->filename);
- free(fnode);
+ if (!was_set) {
+ for (r = fnode->req_list; r != NULL; r = r_next) {
+ r_next = r->next;
+ free(r);
+ }
+ for (p = fnode->prov_list; p != NULL; p = p_next) {
+ p_next = p->next;
+ free(p->pnode);
+ free(p);
+ }
+ free(fnode->filename);
+ free(fnode);
+ }
}
void
More information about the freebsd-current
mailing list