xref: /titanic_50/usr/src/lib/libdwarf/common/malloc_check.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
1*f3e7f55eSRobert Mustacchi /*
2*f3e7f55eSRobert Mustacchi 
3*f3e7f55eSRobert Mustacchi   Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
4*f3e7f55eSRobert Mustacchi 
5*f3e7f55eSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
6*f3e7f55eSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
7*f3e7f55eSRobert Mustacchi   as published by the Free Software Foundation.
8*f3e7f55eSRobert Mustacchi 
9*f3e7f55eSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
10*f3e7f55eSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
11*f3e7f55eSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*f3e7f55eSRobert Mustacchi 
13*f3e7f55eSRobert Mustacchi   Further, this software is distributed without any warranty that it is
14*f3e7f55eSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
15*f3e7f55eSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
16*f3e7f55eSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
17*f3e7f55eSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
18*f3e7f55eSRobert Mustacchi   other software, or any other product whatsoever.
19*f3e7f55eSRobert Mustacchi 
20*f3e7f55eSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
21*f3e7f55eSRobert Mustacchi   License along with this program; if not, write the Free Software
22*f3e7f55eSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*f3e7f55eSRobert Mustacchi   USA.
24*f3e7f55eSRobert Mustacchi 
25*f3e7f55eSRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
26*f3e7f55eSRobert Mustacchi   Mountain View, CA 94043, or:
27*f3e7f55eSRobert Mustacchi 
28*f3e7f55eSRobert Mustacchi   http://www.sgi.com
29*f3e7f55eSRobert Mustacchi 
30*f3e7f55eSRobert Mustacchi   For further information regarding this notice, see:
31*f3e7f55eSRobert Mustacchi 
32*f3e7f55eSRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33*f3e7f55eSRobert Mustacchi 
34*f3e7f55eSRobert Mustacchi */
35*f3e7f55eSRobert Mustacchi 
36*f3e7f55eSRobert Mustacchi 
37*f3e7f55eSRobert Mustacchi 
38*f3e7f55eSRobert Mustacchi /* malloc_check.c For checking dealloc completeness.
39*f3e7f55eSRobert Mustacchi 
40*f3e7f55eSRobert Mustacchi    This code is as simple as possible and works ok for
41*f3e7f55eSRobert Mustacchi    reasonable size allocation counts.
42*f3e7f55eSRobert Mustacchi 
43*f3e7f55eSRobert Mustacchi    It treats allocation as global, and so will not
44*f3e7f55eSRobert Mustacchi    work very well if an application opens more than one
45*f3e7f55eSRobert Mustacchi    Dwarf_Debug.
46*f3e7f55eSRobert Mustacchi 
47*f3e7f55eSRobert Mustacchi */
48*f3e7f55eSRobert Mustacchi 
49*f3e7f55eSRobert Mustacchi #include <stdio.h>
50*f3e7f55eSRobert Mustacchi #include <stdlib.h>             /* for exit() and various malloc
51*f3e7f55eSRobert Mustacchi                                    prototypes */
52*f3e7f55eSRobert Mustacchi #include "config.h"
53*f3e7f55eSRobert Mustacchi #include "dwarf_incl.h"
54*f3e7f55eSRobert Mustacchi #include "malloc_check.h"
55*f3e7f55eSRobert Mustacchi #ifdef  WANT_LIBBDWARF_MALLOC_CHECK
56*f3e7f55eSRobert Mustacchi 
57*f3e7f55eSRobert Mustacchi /* To turn off printing every entry, just change the define
58*f3e7f55eSRobert Mustacchi    to set PRINT_MALLOC_DETAILS 0.
59*f3e7f55eSRobert Mustacchi */
60*f3e7f55eSRobert Mustacchi #define PRINT_MALLOC_DETAILS 0
61*f3e7f55eSRobert Mustacchi 
62*f3e7f55eSRobert Mustacchi #define MC_TYPE_UNKNOWN 0
63*f3e7f55eSRobert Mustacchi #define MC_TYPE_ALLOC 1
64*f3e7f55eSRobert Mustacchi #define MC_TYPE_DEALLOC 2
65*f3e7f55eSRobert Mustacchi 
66*f3e7f55eSRobert Mustacchi struct mc_data_s {
67*f3e7f55eSRobert Mustacchi     struct mc_data_s *mc_prev;
68*f3e7f55eSRobert Mustacchi     unsigned long mc_address;   /* Assumes this is large enough to hold
69*f3e7f55eSRobert Mustacchi                                    a pointer! */
70*f3e7f55eSRobert Mustacchi 
71*f3e7f55eSRobert Mustacchi     long mc_alloc_number;       /* Assigned in order by when record
72*f3e7f55eSRobert Mustacchi                                    created. */
73*f3e7f55eSRobert Mustacchi     unsigned char mc_alloc_code;        /* Allocation code, libdwarf. */
74*f3e7f55eSRobert Mustacchi     unsigned char mc_type;
75*f3e7f55eSRobert Mustacchi     unsigned char mc_dealloc_noted;     /* Used on an ALLOC node. */
76*f3e7f55eSRobert Mustacchi     unsigned char mc_dealloc_noted_count;       /* Used on an ALLOC
77*f3e7f55eSRobert Mustacchi                                                    node. */
78*f3e7f55eSRobert Mustacchi };
79*f3e7f55eSRobert Mustacchi 
80*f3e7f55eSRobert Mustacchi /*
81*f3e7f55eSRobert Mustacchi 
82*f3e7f55eSRobert Mustacchi 
83*f3e7f55eSRobert Mustacchi */
84*f3e7f55eSRobert Mustacchi #define HASH_TABLE_SIZE 10501
85*f3e7f55eSRobert Mustacchi static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE];
86*f3e7f55eSRobert Mustacchi static long mc_data_list_size = 0;
87*f3e7f55eSRobert Mustacchi 
88*f3e7f55eSRobert Mustacchi static char *alloc_type_name[MAX_DW_DLA + 1] = {
89*f3e7f55eSRobert Mustacchi     "",
90*f3e7f55eSRobert Mustacchi     "DW_DLA_STRING",
91*f3e7f55eSRobert Mustacchi     "DW_DLA_LOC",
92*f3e7f55eSRobert Mustacchi     "DW_DLA_LOCDESC",
93*f3e7f55eSRobert Mustacchi     "DW_DLA_ELLIST",
94*f3e7f55eSRobert Mustacchi     "DW_DLA_BOUNDS",
95*f3e7f55eSRobert Mustacchi     "DW_DLA_BLOCK",
96*f3e7f55eSRobert Mustacchi     "DW_DLA_DEBUG",
97*f3e7f55eSRobert Mustacchi     "DW_DLA_DIE",
98*f3e7f55eSRobert Mustacchi     "DW_DLA_LINE",
99*f3e7f55eSRobert Mustacchi     "DW_DLA_ATTR",
100*f3e7f55eSRobert Mustacchi     "DW_DLA_TYPE",
101*f3e7f55eSRobert Mustacchi     "DW_DLA_SUBSCR",
102*f3e7f55eSRobert Mustacchi     "DW_DLA_GLOBAL",
103*f3e7f55eSRobert Mustacchi     "DW_DLA_ERROR",
104*f3e7f55eSRobert Mustacchi     "DW_DLA_LIST",
105*f3e7f55eSRobert Mustacchi     "DW_DLA_LINEBUF",
106*f3e7f55eSRobert Mustacchi     "DW_DLA_ARANGE",
107*f3e7f55eSRobert Mustacchi     "DW_DLA_ABBREV",
108*f3e7f55eSRobert Mustacchi     "DW_DLA_FRAME_OP",
109*f3e7f55eSRobert Mustacchi     "DW_DLA_CIE",
110*f3e7f55eSRobert Mustacchi     "DW_DLA_FDE",
111*f3e7f55eSRobert Mustacchi     "DW_DLA_LOC_BLOCK",
112*f3e7f55eSRobert Mustacchi     "DW_DLA_FRAME_BLOCK",
113*f3e7f55eSRobert Mustacchi     "DW_DLA_FUNC",
114*f3e7f55eSRobert Mustacchi     "DW_DLA_TYPENAME",
115*f3e7f55eSRobert Mustacchi     "DW_DLA_VAR",
116*f3e7f55eSRobert Mustacchi     "DW_DLA_WEAK",
117*f3e7f55eSRobert Mustacchi     "DW_DLA_ADDR",
118*f3e7f55eSRobert Mustacchi     "DW_DLA_ABBREV_LIST",
119*f3e7f55eSRobert Mustacchi     "DW_DLA_CHAIN",
120*f3e7f55eSRobert Mustacchi     "DW_DLA_CU_CONTEXT",
121*f3e7f55eSRobert Mustacchi     "DW_DLA_FRAME",
122*f3e7f55eSRobert Mustacchi     "DW_DLA_GLOBAL_CONTEXT",
123*f3e7f55eSRobert Mustacchi     "DW_DLA_FILE_ENTRY",
124*f3e7f55eSRobert Mustacchi     "DW_DLA_LINE_CONTEXT",
125*f3e7f55eSRobert Mustacchi     "DW_DLA_LOC_CHAIN",
126*f3e7f55eSRobert Mustacchi     "DW_DLA_HASH_TABLE",
127*f3e7f55eSRobert Mustacchi     "DW_DLA_FUNC_CONTEXT",
128*f3e7f55eSRobert Mustacchi     "DW_DLA_TYPENAME_CONTEXT",
129*f3e7f55eSRobert Mustacchi     "DW_DLA_VAR_CONTEXT",
130*f3e7f55eSRobert Mustacchi     "DW_DLA_WEAK_CONTEXT",
131*f3e7f55eSRobert Mustacchi     "DW_DLA_PUBTYPES_CONTEXT"
132*f3e7f55eSRobert Mustacchi         /* Don't forget to expand this list if the list of codes
133*f3e7f55eSRobert Mustacchi            expands. */
134*f3e7f55eSRobert Mustacchi };
135*f3e7f55eSRobert Mustacchi 
136*f3e7f55eSRobert Mustacchi static unsigned
hash_address(unsigned long addr)137*f3e7f55eSRobert Mustacchi hash_address(unsigned long addr)
138*f3e7f55eSRobert Mustacchi {
139*f3e7f55eSRobert Mustacchi     unsigned long a = addr >> 2;
140*f3e7f55eSRobert Mustacchi 
141*f3e7f55eSRobert Mustacchi     return a % HASH_TABLE_SIZE;
142*f3e7f55eSRobert Mustacchi }
143*f3e7f55eSRobert Mustacchi 
144*f3e7f55eSRobert Mustacchi #if PRINT_MALLOC_DETAILS
145*f3e7f55eSRobert Mustacchi static void
print_alloc_dealloc_detail(unsigned long addr,int code,char * whichisit)146*f3e7f55eSRobert Mustacchi print_alloc_dealloc_detail(unsigned long addr,
147*f3e7f55eSRobert Mustacchi                            int code, char *whichisit)
148*f3e7f55eSRobert Mustacchi {
149*f3e7f55eSRobert Mustacchi     fprintf(stderr,
150*f3e7f55eSRobert Mustacchi             "%s  addr 0x%lx code %d (%s) entry %ld\n",
151*f3e7f55eSRobert Mustacchi             whichisit, addr, code, alloc_type_name[code],
152*f3e7f55eSRobert Mustacchi             mc_data_list_size);
153*f3e7f55eSRobert Mustacchi }
154*f3e7f55eSRobert Mustacchi #else
155*f3e7f55eSRobert Mustacchi #define  print_alloc_dealloc_detail(a,b,c)      /* nothing */
156*f3e7f55eSRobert Mustacchi #endif
157*f3e7f55eSRobert Mustacchi 
158*f3e7f55eSRobert Mustacchi /* Create a zeroed struct or die. */
159*f3e7f55eSRobert Mustacchi static void *
newone(void)160*f3e7f55eSRobert Mustacchi newone(void)
161*f3e7f55eSRobert Mustacchi {
162*f3e7f55eSRobert Mustacchi     struct mc_data_s *newd = malloc(sizeof(struct mc_data_s));
163*f3e7f55eSRobert Mustacchi 
164*f3e7f55eSRobert Mustacchi     if (newd == 0) {
165*f3e7f55eSRobert Mustacchi         fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size);
166*f3e7f55eSRobert Mustacchi         exit(1);
167*f3e7f55eSRobert Mustacchi     }
168*f3e7f55eSRobert Mustacchi     memset(newd, 0, sizeof(struct mc_data_s));
169*f3e7f55eSRobert Mustacchi     return newd;
170*f3e7f55eSRobert Mustacchi }
171*f3e7f55eSRobert Mustacchi 
172*f3e7f55eSRobert Mustacchi /* Notify checker that get_alloc has allocated user data. */
173*f3e7f55eSRobert Mustacchi void
dwarf_malloc_check_alloc_data(void * addr_in,unsigned char code)174*f3e7f55eSRobert Mustacchi dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code)
175*f3e7f55eSRobert Mustacchi {
176*f3e7f55eSRobert Mustacchi     struct mc_data_s *newd = newone();
177*f3e7f55eSRobert Mustacchi     unsigned long addr = (unsigned long) addr_in;
178*f3e7f55eSRobert Mustacchi     struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
179*f3e7f55eSRobert Mustacchi 
180*f3e7f55eSRobert Mustacchi     print_alloc_dealloc_detail(addr, code, "alloc   ");
181*f3e7f55eSRobert Mustacchi     newd->mc_address = addr;
182*f3e7f55eSRobert Mustacchi     newd->mc_alloc_code = code;
183*f3e7f55eSRobert Mustacchi     newd->mc_type = MC_TYPE_ALLOC;
184*f3e7f55eSRobert Mustacchi     newd->mc_alloc_number = mc_data_list_size;
185*f3e7f55eSRobert Mustacchi     newd->mc_prev = *base;
186*f3e7f55eSRobert Mustacchi     *base = newd;
187*f3e7f55eSRobert Mustacchi     newd->mc_alloc_number = mc_data_list_size;
188*f3e7f55eSRobert Mustacchi     mc_data_list_size += 1;
189*f3e7f55eSRobert Mustacchi }
190*f3e7f55eSRobert Mustacchi 
191*f3e7f55eSRobert Mustacchi static void
print_entry(char * msg,struct mc_data_s * data)192*f3e7f55eSRobert Mustacchi print_entry(char *msg, struct mc_data_s *data)
193*f3e7f55eSRobert Mustacchi {
194*f3e7f55eSRobert Mustacchi     fprintf(stderr,
195*f3e7f55eSRobert Mustacchi             "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n",
196*f3e7f55eSRobert Mustacchi             msg,
197*f3e7f55eSRobert Mustacchi             (long) data->mc_address,
198*f3e7f55eSRobert Mustacchi             data->mc_alloc_code,
199*f3e7f55eSRobert Mustacchi             alloc_type_name[data->mc_alloc_code],
200*f3e7f55eSRobert Mustacchi             (data->mc_type == MC_TYPE_ALLOC) ? "alloc  " :
201*f3e7f55eSRobert Mustacchi             (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown",
202*f3e7f55eSRobert Mustacchi             (unsigned) data->mc_dealloc_noted,
203*f3e7f55eSRobert Mustacchi             (unsigned) data->mc_dealloc_noted_count);
204*f3e7f55eSRobert Mustacchi }
205*f3e7f55eSRobert Mustacchi 
206*f3e7f55eSRobert Mustacchi /* newd is a 'dealloc'.
207*f3e7f55eSRobert Mustacchi */
208*f3e7f55eSRobert Mustacchi static long
balanced_by_alloc_p(struct mc_data_s * newd,long * addr_match_num,struct mc_data_s ** addr_match,struct mc_data_s * base)209*f3e7f55eSRobert Mustacchi balanced_by_alloc_p(struct mc_data_s *newd,
210*f3e7f55eSRobert Mustacchi                     long *addr_match_num,
211*f3e7f55eSRobert Mustacchi                     struct mc_data_s **addr_match,
212*f3e7f55eSRobert Mustacchi                     struct mc_data_s *base)
213*f3e7f55eSRobert Mustacchi {
214*f3e7f55eSRobert Mustacchi     struct mc_data_s *cur = base;
215*f3e7f55eSRobert Mustacchi 
216*f3e7f55eSRobert Mustacchi     for (; cur; cur = cur->mc_prev) {
217*f3e7f55eSRobert Mustacchi         if (cur->mc_address == newd->mc_address) {
218*f3e7f55eSRobert Mustacchi             if (cur->mc_type == MC_TYPE_ALLOC) {
219*f3e7f55eSRobert Mustacchi                 if (cur->mc_alloc_code == newd->mc_alloc_code) {
220*f3e7f55eSRobert Mustacchi                     *addr_match = cur;
221*f3e7f55eSRobert Mustacchi                     *addr_match_num = cur->mc_alloc_number;
222*f3e7f55eSRobert Mustacchi                     return cur->mc_alloc_number;
223*f3e7f55eSRobert Mustacchi                 } else {
224*f3e7f55eSRobert Mustacchi                     /* code mismatch */
225*f3e7f55eSRobert Mustacchi                     *addr_match = cur;
226*f3e7f55eSRobert Mustacchi                     *addr_match_num = cur->mc_alloc_number;
227*f3e7f55eSRobert Mustacchi                     return -1;
228*f3e7f55eSRobert Mustacchi                 }
229*f3e7f55eSRobert Mustacchi             } else {
230*f3e7f55eSRobert Mustacchi                 /* Unbalanced new/del */
231*f3e7f55eSRobert Mustacchi                 *addr_match = cur;
232*f3e7f55eSRobert Mustacchi                 *addr_match_num = cur->mc_alloc_number;
233*f3e7f55eSRobert Mustacchi                 return -1;
234*f3e7f55eSRobert Mustacchi             }
235*f3e7f55eSRobert Mustacchi         }
236*f3e7f55eSRobert Mustacchi     }
237*f3e7f55eSRobert Mustacchi     return -1;
238*f3e7f55eSRobert Mustacchi }
239*f3e7f55eSRobert Mustacchi 
240*f3e7f55eSRobert Mustacchi /*  A dealloc is to take place. Ensure it balances an alloc.
241*f3e7f55eSRobert Mustacchi */
242*f3e7f55eSRobert Mustacchi void
dwarf_malloc_check_dealloc_data(void * addr_in,unsigned char code)243*f3e7f55eSRobert Mustacchi dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code)
244*f3e7f55eSRobert Mustacchi {
245*f3e7f55eSRobert Mustacchi     struct mc_data_s *newd = newone();
246*f3e7f55eSRobert Mustacchi     long prev;
247*f3e7f55eSRobert Mustacchi     long addr_match_num = -1;
248*f3e7f55eSRobert Mustacchi     struct mc_data_s *addr_match = 0;
249*f3e7f55eSRobert Mustacchi     unsigned long addr = (unsigned long) addr_in;
250*f3e7f55eSRobert Mustacchi     struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
251*f3e7f55eSRobert Mustacchi 
252*f3e7f55eSRobert Mustacchi 
253*f3e7f55eSRobert Mustacchi     print_alloc_dealloc_detail(addr, code, "dealloc ");
254*f3e7f55eSRobert Mustacchi     newd->mc_address = (unsigned long) addr;
255*f3e7f55eSRobert Mustacchi     newd->mc_alloc_code = code;
256*f3e7f55eSRobert Mustacchi     newd->mc_type = MC_TYPE_DEALLOC;
257*f3e7f55eSRobert Mustacchi     newd->mc_prev = *base;
258*f3e7f55eSRobert Mustacchi     prev =
259*f3e7f55eSRobert Mustacchi         balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base);
260*f3e7f55eSRobert Mustacchi     if (prev < 0) {
261*f3e7f55eSRobert Mustacchi         fprintf(stderr,
262*f3e7f55eSRobert Mustacchi                 "Unbalanced dealloc at index %ld\n", mc_data_list_size);
263*f3e7f55eSRobert Mustacchi         print_entry("new", newd);
264*f3e7f55eSRobert Mustacchi         fprintf(stderr, "addr-match_num? %ld\n", addr_match_num);
265*f3e7f55eSRobert Mustacchi         if (addr_match) {
266*f3e7f55eSRobert Mustacchi             print_entry("prev entry", addr_match);
267*f3e7f55eSRobert Mustacchi             if (addr_match->mc_dealloc_noted > 1) {
268*f3e7f55eSRobert Mustacchi                 fprintf(stderr, "Above is Duplicate dealloc!\n");
269*f3e7f55eSRobert Mustacchi             }
270*f3e7f55eSRobert Mustacchi         }
271*f3e7f55eSRobert Mustacchi         abort();
272*f3e7f55eSRobert Mustacchi         exit(3);
273*f3e7f55eSRobert Mustacchi     }
274*f3e7f55eSRobert Mustacchi     addr_match->mc_dealloc_noted = 1;
275*f3e7f55eSRobert Mustacchi     addr_match->mc_dealloc_noted_count += 1;
276*f3e7f55eSRobert Mustacchi     if (addr_match->mc_dealloc_noted_count > 1) {
277*f3e7f55eSRobert Mustacchi         fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num);
278*f3e7f55eSRobert Mustacchi         print_entry("new dealloc entry", newd);
279*f3e7f55eSRobert Mustacchi         print_entry("bad alloc entry", addr_match);
280*f3e7f55eSRobert Mustacchi     }
281*f3e7f55eSRobert Mustacchi     *base = newd;
282*f3e7f55eSRobert Mustacchi     mc_data_list_size += 1;
283*f3e7f55eSRobert Mustacchi }
284*f3e7f55eSRobert Mustacchi 
285*f3e7f55eSRobert Mustacchi /* Final check for leaks.
286*f3e7f55eSRobert Mustacchi */
287*f3e7f55eSRobert Mustacchi void
dwarf_malloc_check_complete(char * msg)288*f3e7f55eSRobert Mustacchi dwarf_malloc_check_complete(char *msg)
289*f3e7f55eSRobert Mustacchi {
290*f3e7f55eSRobert Mustacchi     long i = 0;
291*f3e7f55eSRobert Mustacchi     long total = mc_data_list_size;
292*f3e7f55eSRobert Mustacchi     long hash_slots_used = 0;
293*f3e7f55eSRobert Mustacchi     long max_chain_length = 0;
294*f3e7f55eSRobert Mustacchi 
295*f3e7f55eSRobert Mustacchi     fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total);
296*f3e7f55eSRobert Mustacchi     for (; i < HASH_TABLE_SIZE; ++i) {
297*f3e7f55eSRobert Mustacchi         struct mc_data_s *cur = mc_data_hash[i];
298*f3e7f55eSRobert Mustacchi         long cur_chain_length = 0;
299*f3e7f55eSRobert Mustacchi 
300*f3e7f55eSRobert Mustacchi         if (cur == 0)
301*f3e7f55eSRobert Mustacchi             continue;
302*f3e7f55eSRobert Mustacchi         ++hash_slots_used;
303*f3e7f55eSRobert Mustacchi         for (; cur; cur = cur->mc_prev) {
304*f3e7f55eSRobert Mustacchi             ++cur_chain_length;
305*f3e7f55eSRobert Mustacchi             if (cur->mc_type == MC_TYPE_ALLOC) {
306*f3e7f55eSRobert Mustacchi                 if (cur->mc_dealloc_noted) {
307*f3e7f55eSRobert Mustacchi                     if (cur->mc_dealloc_noted > 1) {
308*f3e7f55eSRobert Mustacchi                         fprintf(stderr,
309*f3e7f55eSRobert Mustacchi                                 " Duplicate dealloc! entry %ld\n",
310*f3e7f55eSRobert Mustacchi                                 cur->mc_alloc_number);
311*f3e7f55eSRobert Mustacchi                         print_entry("duplicate dealloc", cur);
312*f3e7f55eSRobert Mustacchi 
313*f3e7f55eSRobert Mustacchi                     }
314*f3e7f55eSRobert Mustacchi                     continue;
315*f3e7f55eSRobert Mustacchi                 } else {
316*f3e7f55eSRobert Mustacchi                     fprintf(stderr, "malloc no dealloc, entry %ld\n",
317*f3e7f55eSRobert Mustacchi                             cur->mc_alloc_number);
318*f3e7f55eSRobert Mustacchi                     print_entry("dangle", cur);
319*f3e7f55eSRobert Mustacchi                 }
320*f3e7f55eSRobert Mustacchi             } else {
321*f3e7f55eSRobert Mustacchi                 /* mc_type is MC_TYPE_DEALLOC, already checked */
322*f3e7f55eSRobert Mustacchi 
323*f3e7f55eSRobert Mustacchi             }
324*f3e7f55eSRobert Mustacchi         }
325*f3e7f55eSRobert Mustacchi         if (cur_chain_length > max_chain_length) {
326*f3e7f55eSRobert Mustacchi             max_chain_length = cur_chain_length;
327*f3e7f55eSRobert Mustacchi         }
328*f3e7f55eSRobert Mustacchi     }
329*f3e7f55eSRobert Mustacchi     fprintf(stderr, "mc hash table slots=%ld, "
330*f3e7f55eSRobert Mustacchi             "used=%ld,  maxchain=%ld\n",
331*f3e7f55eSRobert Mustacchi             (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length);
332*f3e7f55eSRobert Mustacchi     return;
333*f3e7f55eSRobert Mustacchi }
334*f3e7f55eSRobert Mustacchi 
335*f3e7f55eSRobert Mustacchi #else
336*f3e7f55eSRobert Mustacchi 
337*f3e7f55eSRobert Mustacchi extern void *libdwarf_an_unused_function_so_not_empty_c_file();
338*f3e7f55eSRobert Mustacchi 
339*f3e7f55eSRobert Mustacchi #endif /* WANT_LIBBDWARF_MALLOC_CHECK */
340