1 /*        $NetBSD: debugrm.c,v 1.4 2018/04/01 22:35:22 christos Exp $ */
2 
3 /*        $KAME: debugrm.c,v 1.6 2001/12/13 16:07:46 sakane Exp $     */
4 
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #define NONEED_DRM
35 
36 #include "config.h"
37 
38 #include <sys/types.h>
39 #include <sys/param.h>
40 
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <time.h>
45 #include <err.h>
46 
47 #include "debugrm.h"
48 
49 #include "vmbuf.h"  /* need to mask vmbuf.c functions. */
50 
51 #define DRMLISTSIZE 1024
52 
53 struct drm_list_t {
54           const void *ptr;
55           char msg[100];
56 };
57 static struct drm_list_t drmlist[DRMLISTSIZE];
58 
59 static int drm_unknown;
60 
61 static void DRM_add(const void *, const char *);
62 static void DRM_del(const void *);
63 static void DRM_setmsg(char *, size_t, const void *, size_t, const char *,
64     size_t, const char *);
65 
66 void
DRM_init(void)67 DRM_init(void)
68 {
69           size_t i;
70           drm_unknown = 0;
71           for (i = 0; i < __arraycount(drmlist); i++)
72                     drmlist[i].ptr = 0;
73 }
74 
75 void
DRM_dump(void)76 DRM_dump(void)
77 {
78           FILE *fp;
79           size_t i;
80 
81           fp = fopen(DRMDUMPFILE, "w");
82           if (fp == NULL)
83                     err(1, "fopen");    /*XXX*/
84           fprintf(fp, "drm_unknown=%d\n", drm_unknown);
85           for (i = 0; i < __arraycount(drmlist); i++) {
86                     if (drmlist[i].ptr)
87                               fprintf(fp, "%s\n", drmlist[i].msg);
88           }
89           fclose(fp);
90 }
91 
92 static void
DRM_add(const void * p,const char * msg)93 DRM_add(const void *p, const char *msg)
94 {
95           size_t i;
96           for (i = 0; i < __arraycount(drmlist); i++) {
97                     if (!drmlist[i].ptr) {
98                               drmlist[i].ptr = p;
99                               strlcpy(drmlist[i].msg, msg, sizeof(drmlist[i].msg));
100                               return;
101                     }
102           }
103 }
104 
105 static void
DRM_del(const void * p)106 DRM_del(const void *p)
107 {
108           size_t i;
109 
110           if (!p)
111                     return;
112 
113           for (i = 0; i < __arraycount(drmlist); i++) {
114                     if (drmlist[i].ptr == p) {
115                               drmlist[i].ptr = 0;
116                               return;
117                     }
118           }
119           drm_unknown++;
120 }
121 
122 static void
DRM_setmsg(char * buf,size_t buflen,const void * ptr,size_t size,const char * file,size_t line,const char * func)123 DRM_setmsg(char *buf, size_t buflen, const void *ptr, size_t size,
124     const char *file, size_t line, const char *func)
125 {
126           time_t t;
127           struct tm *tm;
128           int len;
129 
130           t = time(NULL);
131           tm = localtime(&t);
132           len = strftime(buf, buflen, "%Y/%m/%d:%T ", tm);
133 
134           snprintf(buf + len, buflen - len, "%p %6d %s:%d:%s",
135                     ptr, size, file, line, func);
136 }
137 
138 void *
DRM_malloc(const char * file,size_t line,const char * func,size_t size)139 DRM_malloc(const char *file, size_t line, const char *func, size_t size)
140 {
141           void *p;
142 
143           p = malloc(size);
144           if (p) {
145                     char buf[1024];
146                     DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
147                     DRM_add(p, buf);
148           }
149 
150           return p;
151 }
152 
153 void *
DRM_calloc(const char * file,size_t line,const char * func,size_t number,size_t size)154 DRM_calloc(const char *file, size_t line, const char *func, size_t number,
155     size_t size)
156 {
157           void *p;
158 
159           p = calloc(number, size);
160           if (p) {
161                     char buf[1024];
162                     DRM_setmsg(buf, sizeof(buf), p, number * size, file, line, func);
163                     DRM_add(p, buf);
164           }
165           return p;
166 }
167 
168 void *
DRM_realloc(const char * file,size_t line,const char * func,void * ptr,size_t size)169 DRM_realloc(const char *file, size_t line, const char *func, void *ptr,
170     size_t size)
171 {
172           void *p;
173 
174           p = realloc(ptr, size);
175           if (p) {
176                     char buf[1024];
177                     if (ptr && p != ptr) {
178                               DRM_del(ptr);
179                               DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
180                               DRM_add(p, buf);
181                     }
182           }
183 
184           return p;
185 }
186 
187 void
DRM_free(const char * file,size_t line,const char * func,void * ptr)188 DRM_free(const char *file, size_t line, const char *func, void *ptr)
189 {
190           DRM_del(ptr);
191           free(ptr);
192 }
193 
194 char *
DRM_strdup(const char * file,size_t line,const char * func,const char * str)195 DRM_strdup(const char *file, size_t line, const char *func, const char *str)
196 {
197           char *p;
198 
199           p = strdup(str);
200 
201           if (p) {
202                     char buf[1024];
203                     DRM_setmsg(buf, sizeof(buf), p, strlen(p), file, line, func);
204                     DRM_add(p, buf);
205           }
206 
207           return p;
208 }
209 
210 /*
211  * mask vmbuf.c functions.
212  */
213 void *
DRM_vmalloc(const char * file,size_t line,const char * func,size_t size)214 DRM_vmalloc(const char *file, size_t line, const char *func, size_t size)
215 {
216           void *p;
217 
218           p = vmalloc(size);
219           if (p) {
220                     char buf[1024];
221                     DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
222                     DRM_add(p, buf);
223           }
224 
225           return p;
226 }
227 
228 void *
DRM_vrealloc(const char * file,size_t line,const char * func,void * ptr,size_t size)229 DRM_vrealloc(const char *file, size_t line, const char *func, void *ptr,
230     size_t size)
231 {
232           void *p;
233 
234           p = vrealloc(ptr, size);
235           if (p) {
236                     char buf[1024];
237                     if (ptr && p != ptr) {
238                               DRM_del(ptr);
239                               DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
240                               DRM_add(p, buf);
241                     }
242           }
243 
244           return p;
245 }
246 
247 void
DRM_vfree(const char * file,size_t line,const char * func,void * ptr)248 DRM_vfree(const char *file, size_t line, const char *func, void *ptr)
249 {
250           DRM_del(ptr);
251           vfree(ptr);
252 }
253 
254 void *
DRM_vdup(const char * file,size_t line,const char * func,void * ptr)255 DRM_vdup(const char *file, size_t line, const char *func, void *ptr)
256 {
257           void *p;
258 
259           p = vdup(ptr);
260           if (p) {
261                     char buf[1024];
262                     DRM_setmsg(buf, sizeof(buf), p, 0, file, line, func);
263                     DRM_add(p, buf);
264           }
265 
266           return p;
267 }
268