aboutsummaryrefslogtreecommitdiffstats
path: root/src/gmalloc.c
diff options
context:
space:
mode:
authorGerd Moellmann2000-10-27 18:43:39 +0000
committerGerd Moellmann2000-10-27 18:43:39 +0000
commita3ba27daef3bf81a134eb0208a8c5207b829f560 (patch)
tree3d4f87ed14b25ae6f5105160b66642a6de21c49f /src/gmalloc.c
parentdf359f6c5bba555f646c7987f0830e6e97d8c81b (diff)
downloademacs-a3ba27daef3bf81a134eb0208a8c5207b829f560.tar.gz
emacs-a3ba27daef3bf81a134eb0208a8c5207b829f560.zip
Add code from mcheck.c of glibc-1.09.1.
(freehook, reallochook): Handle null pointer arguments. (__malloc_initialize) [GC_MCHECK]: Call mcheck.
Diffstat (limited to 'src/gmalloc.c')
-rw-r--r--src/gmalloc.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/src/gmalloc.c b/src/gmalloc.c
index e7cc2c3947e..751e90baf13 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -522,6 +522,10 @@ __malloc_initialize ()
522 if (__malloc_initialized) 522 if (__malloc_initialized)
523 return 0; 523 return 0;
524 524
525#ifdef GC_MCHECK
526 mcheck (NULL);
527#endif
528
525 if (__malloc_initialize_hook) 529 if (__malloc_initialize_hook)
526 (*__malloc_initialize_hook) (); 530 (*__malloc_initialize_hook) ();
527 531
@@ -1718,3 +1722,242 @@ valloc (size)
1718} 1722}
1719 1723
1720#endif /* Not ELIDE_VALLOC. */ 1724#endif /* Not ELIDE_VALLOC. */
1725
1726#ifdef GC_MCHECK
1727
1728/* Standard debugging hooks for `malloc'.
1729 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
1730 Written May 1989 by Mike Haertel.
1731
1732This library is free software; you can redistribute it and/or
1733modify it under the terms of the GNU Library General Public License as
1734published by the Free Software Foundation; either version 2 of the
1735License, or (at your option) any later version.
1736
1737This library is distributed in the hope that it will be useful,
1738but WITHOUT ANY WARRANTY; without even the implied warranty of
1739MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1740Library General Public License for more details.
1741
1742You should have received a copy of the GNU Library General Public
1743License along with this library; see the file COPYING.LIB. If
1744not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1745Cambridge, MA 02139, USA.
1746
1747 The author may be reached (Email) at the address mike@ai.mit.edu,
1748 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1749
1750#ifdef emacs
1751#include <stdio.h>
1752#else
1753#ifndef _MALLOC_INTERNAL
1754#define _MALLOC_INTERNAL
1755#include <malloc.h>
1756#include <stdio.h>
1757#endif
1758#endif
1759
1760/* Old hook values. */
1761static void (*old_free_hook) __P ((__ptr_t ptr));
1762static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size));
1763static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
1764
1765/* Function to call when something awful happens. */
1766static void (*abortfunc) __P ((enum mcheck_status));
1767
1768/* Arbitrary magical numbers. */
1769#define MAGICWORD 0xfedabeeb
1770#define MAGICFREE 0xd8675309
1771#define MAGICBYTE ((char) 0xd7)
1772#define MALLOCFLOOD ((char) 0x93)
1773#define FREEFLOOD ((char) 0x95)
1774
1775struct hdr
1776 {
1777 __malloc_size_t size; /* Exact size requested by user. */
1778 unsigned long int magic; /* Magic number to check header integrity. */
1779 };
1780
1781#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
1782#define flood memset
1783#else
1784static void flood __P ((__ptr_t, int, __malloc_size_t));
1785static void
1786flood (ptr, val, size)
1787 __ptr_t ptr;
1788 int val;
1789 __malloc_size_t size;
1790{
1791 char *cp = ptr;
1792 while (size--)
1793 *cp++ = val;
1794}
1795#endif
1796
1797static enum mcheck_status checkhdr __P ((const struct hdr *));
1798static enum mcheck_status
1799checkhdr (hdr)
1800 const struct hdr *hdr;
1801{
1802 enum mcheck_status status;
1803 switch (hdr->magic)
1804 {
1805 default:
1806 status = MCHECK_HEAD;
1807 break;
1808 case MAGICFREE:
1809 status = MCHECK_FREE;
1810 break;
1811 case MAGICWORD:
1812 if (((char *) &hdr[1])[hdr->size] != MAGICBYTE)
1813 status = MCHECK_TAIL;
1814 else
1815 status = MCHECK_OK;
1816 break;
1817 }
1818 if (status != MCHECK_OK)
1819 (*abortfunc) (status);
1820 return status;
1821}
1822
1823static void freehook __P ((__ptr_t));
1824static void
1825freehook (ptr)
1826 __ptr_t ptr;
1827{
1828 struct hdr *hdr;
1829
1830 if (ptr)
1831 {
1832 hdr = ((struct hdr *) ptr) - 1;
1833 checkhdr (hdr);
1834 hdr->magic = MAGICFREE;
1835 flood (ptr, FREEFLOOD, hdr->size);
1836 }
1837 else
1838 hdr = NULL;
1839
1840 __free_hook = old_free_hook;
1841 free (hdr);
1842 __free_hook = freehook;
1843}
1844
1845static __ptr_t mallochook __P ((__malloc_size_t));
1846static __ptr_t
1847mallochook (size)
1848 __malloc_size_t size;
1849{
1850 struct hdr *hdr;
1851
1852 __malloc_hook = old_malloc_hook;
1853 hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
1854 __malloc_hook = mallochook;
1855 if (hdr == NULL)
1856 return NULL;
1857
1858 hdr->size = size;
1859 hdr->magic = MAGICWORD;
1860 ((char *) &hdr[1])[size] = MAGICBYTE;
1861 flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
1862 return (__ptr_t) (hdr + 1);
1863}
1864
1865static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t));
1866static __ptr_t
1867reallochook (ptr, size)
1868 __ptr_t ptr;
1869 __malloc_size_t size;
1870{
1871 struct hdr *hdr = NULL;
1872 __malloc_size_t osize = 0;
1873
1874 if (ptr)
1875 {
1876 hdr = ((struct hdr *) ptr) - 1;
1877 osize = hdr->size;
1878
1879 checkhdr (hdr);
1880 if (size < osize)
1881 flood ((char *) ptr + size, FREEFLOOD, osize - size);
1882 }
1883
1884 __free_hook = old_free_hook;
1885 __malloc_hook = old_malloc_hook;
1886 __realloc_hook = old_realloc_hook;
1887 hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1);
1888 __free_hook = freehook;
1889 __malloc_hook = mallochook;
1890 __realloc_hook = reallochook;
1891 if (hdr == NULL)
1892 return NULL;
1893
1894 hdr->size = size;
1895 hdr->magic = MAGICWORD;
1896 ((char *) &hdr[1])[size] = MAGICBYTE;
1897 if (size > osize)
1898 flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
1899 return (__ptr_t) (hdr + 1);
1900}
1901
1902static void
1903mabort (status)
1904 enum mcheck_status status;
1905{
1906 const char *msg;
1907 switch (status)
1908 {
1909 case MCHECK_OK:
1910 msg = "memory is consistent, library is buggy";
1911 break;
1912 case MCHECK_HEAD:
1913 msg = "memory clobbered before allocated block";
1914 break;
1915 case MCHECK_TAIL:
1916 msg = "memory clobbered past end of allocated block";
1917 break;
1918 case MCHECK_FREE:
1919 msg = "block freed twice";
1920 break;
1921 default:
1922 msg = "bogus mcheck_status, library is buggy";
1923 break;
1924 }
1925#ifdef __GNU_LIBRARY__
1926 __libc_fatal (msg);
1927#else
1928 fprintf (stderr, "mcheck: %s\n", msg);
1929 fflush (stderr);
1930 abort ();
1931#endif
1932}
1933
1934static int mcheck_used = 0;
1935
1936int
1937mcheck (func)
1938 void (*func) __P ((enum mcheck_status));
1939{
1940 abortfunc = (func != NULL) ? func : &mabort;
1941
1942 /* These hooks may not be safely inserted if malloc is already in use. */
1943 if (!__malloc_initialized && !mcheck_used)
1944 {
1945 old_free_hook = __free_hook;
1946 __free_hook = freehook;
1947 old_malloc_hook = __malloc_hook;
1948 __malloc_hook = mallochook;
1949 old_realloc_hook = __realloc_hook;
1950 __realloc_hook = reallochook;
1951 mcheck_used = 1;
1952 }
1953
1954 return mcheck_used ? 0 : -1;
1955}
1956
1957enum mcheck_status
1958mprobe (__ptr_t ptr)
1959{
1960 return mcheck_used ? checkhdr (ptr) : MCHECK_DISABLED;
1961}
1962
1963#endif /* GC_MCHECK */