diff options
| author | Gerd Moellmann | 2000-10-27 18:43:39 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-10-27 18:43:39 +0000 |
| commit | a3ba27daef3bf81a134eb0208a8c5207b829f560 (patch) | |
| tree | 3d4f87ed14b25ae6f5105160b66642a6de21c49f /src/gmalloc.c | |
| parent | df359f6c5bba555f646c7987f0830e6e97d8c81b (diff) | |
| download | emacs-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.c | 243 |
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 | |||
| 1732 | This library is free software; you can redistribute it and/or | ||
| 1733 | modify it under the terms of the GNU Library General Public License as | ||
| 1734 | published by the Free Software Foundation; either version 2 of the | ||
| 1735 | License, or (at your option) any later version. | ||
| 1736 | |||
| 1737 | This library is distributed in the hope that it will be useful, | ||
| 1738 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 1739 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 1740 | Library General Public License for more details. | ||
| 1741 | |||
| 1742 | You should have received a copy of the GNU Library General Public | ||
| 1743 | License along with this library; see the file COPYING.LIB. If | ||
| 1744 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, | ||
| 1745 | Cambridge, 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. */ | ||
| 1761 | static void (*old_free_hook) __P ((__ptr_t ptr)); | ||
| 1762 | static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size)); | ||
| 1763 | static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size)); | ||
| 1764 | |||
| 1765 | /* Function to call when something awful happens. */ | ||
| 1766 | static 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 | |||
| 1775 | struct 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 | ||
| 1784 | static void flood __P ((__ptr_t, int, __malloc_size_t)); | ||
| 1785 | static void | ||
| 1786 | flood (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 | |||
| 1797 | static enum mcheck_status checkhdr __P ((const struct hdr *)); | ||
| 1798 | static enum mcheck_status | ||
| 1799 | checkhdr (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 | |||
| 1823 | static void freehook __P ((__ptr_t)); | ||
| 1824 | static void | ||
| 1825 | freehook (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 | |||
| 1845 | static __ptr_t mallochook __P ((__malloc_size_t)); | ||
| 1846 | static __ptr_t | ||
| 1847 | mallochook (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 | |||
| 1865 | static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t)); | ||
| 1866 | static __ptr_t | ||
| 1867 | reallochook (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 | |||
| 1902 | static void | ||
| 1903 | mabort (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 | |||
| 1934 | static int mcheck_used = 0; | ||
| 1935 | |||
| 1936 | int | ||
| 1937 | mcheck (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 | |||
| 1957 | enum mcheck_status | ||
| 1958 | mprobe (__ptr_t ptr) | ||
| 1959 | { | ||
| 1960 | return mcheck_used ? checkhdr (ptr) : MCHECK_DISABLED; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | #endif /* GC_MCHECK */ | ||