master hovercats/oakiss / repo / cairo / patches / 0001-util-remove-malloc-stats.patch
  1From 377f3b5caf0a53590162047e03f1e8803592917b Mon Sep 17 00:00:00 2001
  2From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com>
  3Date: Thu, 28 Sep 2023 11:21:53 +0200
  4Subject: [PATCH] util: remove malloc-stats
  5
  6Not really cairo-related and has now been moved into a
  7separate repository at https://github.com/behdad/malloc-stats
  8
  9Fixes #640
 10---
 11 util/README         |  16 --
 12 util/malloc-stats.c | 376 --------------------------------------------
 13 util/meson.build    |   4 -
 14 3 files changed, 396 deletions(-)
 15 delete mode 100644 util/malloc-stats.c
 16
 17diff --git a/util/README b/util/README
 18index b75ae43..90e1f7f 100644
 19--- a/util/README
 20+++ b/util/README
 21@@ -3,22 +3,6 @@ Cairo Utilities
 22 
 23 There are a varieties of utilities we use with cairo.
 24 
 25-
 26-malloc-stats
 27-------------
 28-
 29-This is a small shared library designed to be preloaded by the
 30-linker and its purpose is to make the malloc_stats() function
 31-of glibc produce more useful information.
 32-
 33-Build by:
 34-
 35-	make malloc-stats.so
 36-
 37-and use by:
 38-
 39-	LD_PRELOAD=$(blddir)/util/libmalloc-stats.so app-to-run
 40-
 41 cairo-trace
 42 -----------
 43 
 44diff --git a/util/malloc-stats.c b/util/malloc-stats.c
 45deleted file mode 100644
 46index a086b05..0000000
 47--- a/util/malloc-stats.c
 48+++ /dev/null
 49@@ -1,376 +0,0 @@
 50-/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
 51-/*
 52- * Copyright © 2007 Red Hat, Inc.
 53- *
 54- * Permission to use, copy, modify, distribute, and sell this software
 55- * and its documentation for any purpose is hereby granted without
 56- * fee, provided that the above copyright notice appear in all copies
 57- * and that both that copyright notice and this permission notice
 58- * appear in supporting documentation, and that the name of
 59- * Red Hat, Inc. not be used in advertising or publicity pertaining to
 60- * distribution of the software without specific, written prior
 61- * permission. Red Hat, Inc. makes no representations about the
 62- * suitability of this software for any purpose.  It is provided "as
 63- * is" without express or implied warranty.
 64- *
 65- * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 66- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 67- * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
 68- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 69- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 70- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 71- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 72- *
 73- * Author: Behdad Esfahbod <behdad@behdad.org>
 74- */
 75-
 76-/* A simple malloc wrapper that prints out statistics on termination */
 77-
 78-#ifndef _GNU_SOURCE
 79-#define _GNU_SOURCE
 80-#endif
 81-
 82-#include <stdlib.h>
 83-#include <stdio.h>
 84-#include <stdint.h>
 85-
 86-/* caller-logging */
 87-
 88-#include <string.h>
 89-
 90-struct alloc_stat_t {
 91-	unsigned int num;
 92-	unsigned long long size;
 93-};
 94-
 95-struct alloc_stats_t {
 96-	struct alloc_stat_t malloc, realloc, total;
 97-};
 98-
 99-struct func_stat_t {
100-	struct func_stat_t *next;
101-
102-	const void *addr;
103-	const char *name;
104-
105-	struct alloc_stats_t stat;
106-};
107-
108-static struct alloc_stats_t total_allocations;
109-static struct func_stat_t *func_stats[31627];
110-static int func_stats_num;
111-
112-#ifndef ARRAY_LENGTH
113-#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
114-#endif
115-static void
116-alloc_stats_add (struct alloc_stats_t *stats, int is_realloc, size_t size)
117-{
118-	struct alloc_stat_t *stat = is_realloc ? &stats->realloc : &stats->malloc;
119-
120-	stats->total.num++;
121-	stats->total.size += size;
122-
123-	stat->num++;
124-	stat->size += size;
125-}
126-
127-#include <execinfo.h>
128-
129-static void *
130-_perm_alloc (size_t size)
131-{
132-    static uint8_t *ptr;
133-    static size_t rem;
134-
135-    void *ret;
136-
137-#define SUPERBLOCK_SIZE (1<<23)
138-#define align(x, y) (((x) + ((y)-1)) & ~((y)-1))
139-
140-    size = align (size, 2 * sizeof (void *));
141-    if (size > rem || rem == 0) {
142-	ptr = malloc (SUPERBLOCK_SIZE);
143-	if (ptr == NULL)
144-	    exit (1);
145-	rem = SUPERBLOCK_SIZE;
146-    }
147-
148-#undef SUPERBLOCK_SIZE
149-#undef align
150-
151-    ret = ptr;
152-    rem -= size;
153-    ptr += size;
154-
155-    return ret;
156-}
157-
158-static void
159-resolve_addrs (struct func_stat_t *func_stats, int num)
160-{
161-	int i;
162-	void **addrs;
163-	char **strings;
164-
165-	addrs = malloc (num * sizeof (void *));
166-	for (i = 0; i < num; i++)
167-		addrs[i] = (void *) func_stats[i].addr;
168-
169-	strings = backtrace_symbols (addrs, num);
170-
171-	for (i = 0; i < num; i++) {
172-		char *p;
173-		char *name;
174-		int len;
175-
176-		p = strchr (strings[i], '\t');
177-		if (p)
178-			p++;
179-		else
180-			p = strings[i];
181-
182-		len = strlen (p) + 1;
183-		name = _perm_alloc (len);
184-		memcpy (name, p, len);
185-		func_stats[i].name = name;
186-	}
187-
188-	free (strings);
189-	free (addrs);
190-}
191-
192-static void
193-func_stats_add (const void *caller, int is_realloc, size_t size)
194-{
195-	int i;
196-	struct func_stat_t *elt;
197-
198-	alloc_stats_add (&total_allocations, is_realloc, size);
199-
200-	i = ((uintptr_t) caller ^ 1215497) % ARRAY_LENGTH (func_stats);
201-	for (elt = func_stats[i]; elt != NULL; elt = elt->next) {
202-		if (elt->addr == caller)
203-			break;
204-	}
205-
206-	if (elt == NULL) {
207-		func_stats_num++;
208-
209-		elt = _perm_alloc (sizeof (struct func_stat_t));
210-		elt->next = func_stats[i];
211-		func_stats[i] = elt;
212-		elt->addr = caller;
213-		elt->name = NULL;
214-		memset (&elt->stat, 0, sizeof (struct alloc_stats_t));
215-	}
216-
217-	alloc_stats_add (&elt->stat, is_realloc, size);
218-}
219-
220-/* wrapper stuff */
221-
222-#include <dlfcn.h>
223-
224-static void *(*old_malloc)(size_t);
225-static void *(*old_calloc)(size_t, size_t);
226-static void *(*old_realloc)(void *, size_t);
227-static int enable_hook = 0;
228-
229-static void init(void);
230-
231-void *
232-malloc(size_t size)
233-{
234-    if (!old_malloc)
235-      init ();
236-
237-    if (enable_hook) {
238-	enable_hook = 0;
239-	void *caller = __builtin_return_address(0);
240-	func_stats_add (caller, 0, size);
241-	enable_hook = 1;
242-    }
243-
244-    return old_malloc (size);
245-}
246-
247-void *
248-calloc(size_t nmemb, size_t size)
249-{
250-    if (!old_calloc)
251-      init ();
252-
253-    if (enable_hook) {
254-	enable_hook = 0;
255-	void *caller = __builtin_return_address(0);
256-	func_stats_add (caller, 0, nmemb * size);
257-	enable_hook = 1;
258-    }
259-
260-    return old_calloc (nmemb, size);
261-}
262-
263-void *
264-realloc(void *ptr, size_t size)
265-{
266-    if (!old_malloc)
267-      init ();
268-
269-    if (enable_hook) {
270-	enable_hook = 0;
271-	void *caller = __builtin_return_address(0);
272-	func_stats_add (caller, 1, size);
273-	enable_hook = 1;
274-    }
275-
276-    return old_realloc (ptr, size);
277-}
278-
279-static void
280-init(void)
281-{
282-    old_malloc = dlsym(RTLD_NEXT, "malloc");
283-    if (!old_malloc) {
284-	fprintf(stderr, "%s\n", dlerror());
285-	exit(1);
286-    }
287-    old_calloc = dlsym(RTLD_NEXT, "calloc");
288-    if (!old_calloc) {
289-	fprintf(stderr, "%s\n", dlerror());
290-	exit(1);
291-    }
292-    old_realloc = dlsym(RTLD_NEXT, "realloc");
293-    if (!old_realloc) {
294-	fprintf(stderr, "%s\n", dlerror());
295-	exit(1);
296-    }
297-    enable_hook = 1;
298-}
299-
300-/* reporting */
301-
302-#include <locale.h>
303-
304-static void
305-add_alloc_stats (struct alloc_stats_t *a, struct alloc_stats_t *b)
306-{
307-	a->total.num += b->total.num;
308-	a->total.size += b->total.size;
309-	a->malloc.num += b->malloc.num;
310-	a->malloc.size += b->malloc.size;
311-	a->realloc.num += b->realloc.num;
312-	a->realloc.size += b->realloc.size;
313-}
314-
315-static void
316-dump_alloc_stats (struct alloc_stats_t *stats, const char *name)
317-{
318-	printf ("%8u %'11llu %8u %'11llu %8u %'11llu %s\n",
319-		stats->total.num, stats->total.size,
320-		stats->malloc.num, stats->malloc.size,
321-		stats->realloc.num, stats->realloc.size,
322-		name);
323-}
324-
325-static int
326-compare_func_stats_name (const void *pa, const void *pb)
327-{
328-	const struct func_stat_t *a = pa, *b = pb;
329-	int i;
330-
331-	i = strcmp (a->name, b->name);
332-	if (i)
333-		return i;
334-
335-	return ((char *) a->addr - (char *) b->addr);
336-}
337-
338-static int
339-compare_func_stats (const void *pa, const void *pb)
340-{
341-	const struct func_stat_t *a = pa, *b = pb;
342-
343-	if (a->stat.total.num != b->stat.total.num)
344-		return (a->stat.total.num - b->stat.total.num);
345-
346-	if (a->stat.total.size != b->stat.total.size)
347-		return (a->stat.total.size - b->stat.total.size);
348-
349-	return compare_func_stats_name (pa, pb);
350-}
351-
352-static int
353-merge_similar_entries (struct func_stat_t *func_stats, int num)
354-{
355-	int i, j;
356-
357-	j = 0;
358-	for (i = 1; i < num; i++) {
359-		if (i != j && 0 == strcmp (func_stats[i].name, func_stats[j].name)) {
360-			add_alloc_stats (&func_stats[j].stat, &func_stats[i].stat);
361-		} else {
362-			j++;
363-			if (i != j)
364-				func_stats[j] = func_stats[i];
365-		}
366-	}
367-	j++;
368-
369-	return j;
370-}
371-
372-__attribute__ ((destructor))
373-static void
374-malloc_stats (void)
375-{
376-	unsigned int i, j;
377-	struct func_stat_t *sorted_func_stats;
378-
379-	enable_hook = 0;
380-
381-	if (! func_stats_num)
382-		return;
383-
384-	sorted_func_stats = malloc (sizeof (struct func_stat_t) * (func_stats_num + 1));
385-	if (sorted_func_stats == NULL)
386-		return;
387-
388-	j = 0;
389-	for (i = 0; i < ARRAY_LENGTH (func_stats); i++) {
390-		struct func_stat_t *elt;
391-		for (elt = func_stats[i]; elt != NULL; elt = elt->next)
392-			sorted_func_stats[j++] = *elt;
393-	}
394-
395-	resolve_addrs (sorted_func_stats, j);
396-
397-	/* merge entries with same name */
398-	qsort (sorted_func_stats, j,
399-	       sizeof (struct func_stat_t), compare_func_stats_name);
400-	j = merge_similar_entries (sorted_func_stats, j);
401-
402-	qsort (sorted_func_stats, j,
403-	       sizeof (struct func_stat_t), compare_func_stats);
404-
405-	/* add total */
406-	sorted_func_stats[j].next = NULL;
407-	sorted_func_stats[j].addr = (void *) -1;
408-	sorted_func_stats[j].name = "(total)";
409-	sorted_func_stats[j].stat = total_allocations;
410-	j++;
411-
412-	setlocale (LC_ALL, "");
413-
414-	printf ("          TOTAL                MALLOC              REALLOC\n");
415-	printf ("     num        size      num        size      num        size\n");
416-
417-	for (i = 0; i < j; i++) {
418-		dump_alloc_stats (&sorted_func_stats[i].stat,
419-				  sorted_func_stats[i].name);
420-	}
421-
422-	/* XXX free other stuff? */
423-
424-	free (sorted_func_stats);
425-}
426diff --git a/util/meson.build b/util/meson.build
427index d64dbad..1e186bf 100644
428--- a/util/meson.build
429+++ b/util/meson.build
430@@ -41,7 +41,3 @@ foreach util : cairo_utils
431     dependencies: deps + util_deps + [libcairo_dep, libcairoscript_dep],
432   )
433 endforeach
434-
435-if conf.get('CAIRO_HAS_DLSYM', 0) == 1 and cc.has_header('execinfo.h')
436-  libmallocstats = library('malloc-stats', 'malloc-stats.c', dependencies : dl_dep)
437-endif
438-- 
4392.44.0
440