* [Bug 1832] ntpdate doesn't allow timeout > 2s.
* [Bug 1833] The checking sem_timedwait() fails without -pthread.
+* ElectricFence was suffering bitrot - remove it. valgrind seems better.
* Enable all relevant automake warnings.
* Correct Solaris 2.1x PTHREAD_ONCE_INIT extra braces test to avoid
triggering warnings due to excess braces.
+++ /dev/null
-2.0.1
- Add work-arounds for kernel and library bugs under HP-UX.
- HP has been notified and will repair these soon.
-
-2.0.2
- Add support for DEC Alpha. Add %a pattern for printing addresses, which
- assumes they are passed in a void *.
-
-2.0.3 30-Sep-1993
- When realloc is passed a zero address, it should work the same
- way as malloc(). Fix forward declaration of mprotect() in page.c to
- use void *, not caddr_t, for addresses. IRIX 5.0.1 complained about that.
-
-2.0.4 29-May-1994
- Don't attempt to allow access to a zero-sized page when
- EF_ALLOW_MALLOC_0 is set. Attempt to un-map memory from
- Page_Delete(). If that doesn't work, fall back by protecting the
- page from all references. Un-mapping small segments of a mapping
- used to crash my SGI IRIX 5.0 system. I assume that nobody is running
- 5.0 any longer.
-
-2.0.5 20-January-1995
- Port to Linux.
+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-\f
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+++ /dev/null
-ASFLAGS= -mips2
-CC= cc
-AR= ar
-INSTALL= install
-MV= mv
-CHMOD= chmod
-CFLAGS= -g
-LIB_INSTALL_DIR= /usr/lib
-MAN_INSTALL_DIR= /usr/man/man3
-
-PACKAGE_SOURCE= README libefence.3 Makefile efence.h \
- efence.c page.c print.c eftest.c tstheap.c CHANGES
-
-# Un-comment the following if you are running HP/UX.
-# CFLAGS= -Aa -g -D_HPUX_SOURCE -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
-
-# Un-comment the following if you are running AIX. This makes sure you won't
-# get the shared-library malloc() rather than the Electric Fence malloc().
-# COMPILE THE PROGRAMS YOU ARE DEBUGGING WITH THESE FLAGS, TOO.
-# CFLAGS= -g -bnso -bnodelcsect -bI:/lib/syscalls.exp
-
-# Un-comment the following if you are running SunOS 4.X
-# Note the definition of PAGE_PROTECTION_VIOLATED_SIGNAL. This may vary
-# depend on what version of Sun hardware you have.
-# You'll probably have to link the program you are debugging with -Bstatic
-# as well if using Sun's compiler, -static if using GCC.
-# CFLAGS= -g -Bstatic -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
-
-OBJECTS= efence.o page.o print.o
-
-all: libefence.a tstheap eftest
- @ echo
- @ echo "Testing Electric Fence."
- @ echo "After the last test, it should print that the test has PASSED."
- ./eftest
- ./tstheap 3072
- @ echo
- @ echo "Electric Fence confidence test PASSED."
- @ echo
-
-install: libefence.a libefence.3
- $(MV) libefence.a $(LIB_INSTALL_DIR)
- $(CHMOD) 644 $(LIB_INSTALL_DIR)/libefence.a
- $(INSTALL) libefence.3 $(MAN_INSTALL_DIR)/libefence.3
- $(CHMOD) 644 $(MAN_INSTALL_DIR)/libefence.3
-
-clean:
- - rm -f $(OBJECTS) tstheap.o eftest.o tstheap eftest libefence.a \
- libefence.cat ElectricFence.shar
-
-roff:
- nroff -man < libefence.3 > libefence.cat
-
-
-ElectricFence.shar: $(PACKAGE_SOURCE)
- shar $(PACKAGE_SOURCE) > ElectricFence.shar
-
-shar: ElectricFence.shar
-
-libefence.a: $(OBJECTS)
- - rm -f libefence.a
- $(AR) crv libefence.a $(OBJECTS)
-
-tstheap: libefence.a tstheap.o
- - rm -f tstheap
- $(CC) $(CFLAGS) tstheap.o libefence.a -o tstheap
-
-eftest: libefence.a eftest.o
- - rm -f eftest
- $(CC) $(CFLAGS) eftest.o libefence.a -o eftest
-
-$(OBJECTS) tstheap.o eftest.o: efence.h
+++ /dev/null
-# Harlan Stenn <stenn@whimsy.udel.edu>
-# Converted the original Makefile (now in Makefile-) to Makefile.am
-# in July of '00
-
-EXTRA_DIST = libefence.3 CHANGES
-libefence_a_SOURCES = efence.h efence.c page.c print.c
-check_PROGRAMS = @EF_PROGS@
-EXTRA_PROGRAMS = eftest tstheap
-# TESTS = eftest tstheap
-noinst_LIBRARIES = @EF_LIBS@
-EXTRA_LIBRARIES = libefence.a
-LDADD = libefence.a
-
-# Un-comment the following if you are running HP/UX.
-# CFLAGS= -Aa -g -D_HPUX_SOURCE -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
-
-# Un-comment the following if you are running AIX. This makes sure you won't
-# get the shared-library malloc() rather than the Electric Fence malloc().
-# COMPILE THE PROGRAMS YOU ARE DEBUGGING WITH THESE FLAGS, TOO.
-# CFLAGS= -g -bnso -bnodelcsect -bI:/lib/syscalls.exp
-
-# Un-comment the following if you are running SunOS 4.X
-# Note the definition of PAGE_PROTECTION_VIOLATED_SIGNAL. This may vary
-# depend on what version of Sun hardware you have.
-# You'll probably have to link the program you are debugging with -Bstatic
-# as well if using Sun's compiler, -static if using GCC.
-# CFLAGS= -g -Bstatic -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
-
-check-local:
- test ! -f eftest || ./eftest
- test ! -f tstheap || ./tstheap 3072
+++ /dev/null
-This is Electric Fence 2.0.5
-
-Electric Fence is a different kind of malloc() debugger. It uses the virtual
-memory hardware of your system to detect when software overruns the boundaries
-of a malloc() buffer. It will also detect any accesses of memory that has
-been released by free(). Because it uses the VM hardware for detection,
-Electric Fence stops your program on the first instruction that causes
-a bounds violation. It's then trivial to use a debugger to display the
-offending statement.
-
-This version will run on:
- Linux kernel version 1.1.83 and above. Earlier kernels have problems
- with the memory protection implementation.
-
- All System V Revision 4 platforms (and possibly earlier revisions)
- including:
- Every 386 System V I've heard of.
- Solaris 2.x
- SGI IRIX 5.0 (but not 4.x)
-
- IBM AIX on the RS/6000.
-
- SunOS 4.X (using an ANSI C compiler and probably static linking).
-
- HP/UX 9.01, and possibly earlier versions.
-
- OSF 1.3 (and possibly earlier versions) on a DECalpha.
-
-On some of these platforms, you'll have to uncomment lines in the Makefile
-that apply to your particular system.
-
-If you test Electric Fence on a platform not mentioned here, please send me a
-report.
-
-It will probably port to any ANSI/POSIX system that provides mmap(), and
-mprotect(), as long as mprotect() has the capability to turn off all access
-to a memory page, and mmap() can use /dev/zero or the MAP_ANONYMOUS flag
-to create virtual memory pages.
-
-Complete information on the use of Electric Fence is in the manual page
-libefence.3 .
-
- Thanks
-
- Bruce Perens
- Bruce@Pixar.com
+++ /dev/null
-/*
- * Electric Fence - Red-Zone memory allocator.
- * Bruce Perens, 1988, 1993
- *
- * This is a special version of malloc() and company for debugging software
- * that is suspected of overrunning or underrunning the boundaries of a
- * malloc buffer, or touching free memory.
- *
- * It arranges for each malloc buffer to be followed (or preceded)
- * in the address space by an inaccessable virtual memory page,
- * and for free memory to be inaccessable. If software touches the
- * inaccessable page, it will get an immediate segmentation
- * fault. It is then trivial to uncover the offending code using a debugger.
- *
- * An advantage of this product over most malloc debuggers is that this one
- * detects reading out of bounds as well as writing, and this one stops on
- * the exact instruction that causes the error, rather than waiting until the
- * next boundary check.
- *
- * There is one product that debugs malloc buffer overruns
- * better than Electric Fence: "Purify" from Purify Systems, and that's only
- * a small part of what Purify does. I'm not affiliated with Purify, I just
- * respect a job well done.
- *
- * This version of malloc() should not be linked into production software,
- * since it tremendously increases the time and memory overhead of malloc().
- * Each malloc buffer will consume a minimum of two virtual memory pages,
- * this is 16 kilobytes on many systems. On some systems it will be necessary
- * to increase the amount of swap space in order to debug large programs that
- * perform lots of allocation, because of the per-buffer overhead.
- */
-#include "efence.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <memory.h>
-#include <string.h>
-
-#ifdef malloc
-#undef malloc
-#endif
-
-#ifdef calloc
-#undef calloc
-#endif
-
-static const char version[] = "\n Electric Fence 2.0.5"
- " Copyright (C) 1987-1995 Bruce Perens.\n";
-
-/*
- * MEMORY_CREATION_SIZE is the amount of memory to get from the operating
- * system at one time. We'll break that memory down into smaller pieces for
- * malloc buffers. One megabyte is probably a good value.
- */
-#define MEMORY_CREATION_SIZE 1024 * 1024
-
-/*
- * Enum Mode indicates the status of a malloc buffer.
- */
-enum _Mode {
- NOT_IN_USE = 0, /* Available to represent a malloc buffer. */
- FREE, /* A free buffer. */
- ALLOCATED, /* A buffer that is in use. */
- PROTECTED, /* A freed buffer that can not be allocated again. */
- INTERNAL_USE /* A buffer used internally by malloc(). */
-};
-typedef enum _Mode Mode;
-
-/*
- * Struct Slot contains all of the information about a malloc buffer except
- * for the contents of its memory.
- */
-struct _Slot {
- void * userAddress;
- void * internalAddress;
- size_t userSize;
- size_t internalSize;
- Mode mode;
-};
-typedef struct _Slot Slot;
-
-/*
- * EF_ALIGNMENT is a global variable used to control the default alignment
- * of buffers returned by malloc(), calloc(), and realloc(). It is all-caps
- * so that its name matches the name of the environment variable that is used
- * to set it. This gives the programmer one less name to remember.
- * If the value is -1, it will be set from the environment or sizeof(int)
- * at run time.
- */
-int EF_ALIGNMENT = -1;
-
-/*
- * EF_PROTECT_FREE is a global variable used to control the disposition of
- * memory that is released using free(). It is all-caps so that its name
- * matches the name of the environment variable that is used to set it.
- * If its value is greater non-zero, memory released by free is made
- * inaccessable and never allocated again. Any software that touches free
- * memory will then get a segmentation fault. If its value is zero, freed
- * memory will be available for reallocation, but will still be inaccessable
- * until it is reallocated.
- * If the value is -1, it will be set from the environment or to 0 at run-time.
- */
-int EF_PROTECT_FREE = -1;
-
-/*
- * EF_PROTECT_BELOW is used to modify the behavior of the allocator. When
- * its value is non-zero, the allocator will place an inaccessable page
- * immediately _before_ the malloc buffer in the address space, instead
- * of _after_ it. Use this to detect malloc buffer under-runs, rather than
- * over-runs. It won't detect both at the same time, so you should test your
- * software twice, once with this value clear, and once with it set.
- * If the value is -1, it will be set from the environment or to zero at
- * run-time
- */
-int EF_PROTECT_BELOW = -1;
-
-/*
- * EF_ALLOW_MALLOC_0 is set if Electric Fence is to allow malloc(0). I
- * trap malloc(0) by default because it is a common source of bugs.
- */
-int EF_ALLOW_MALLOC_0 = -1;
-
-/*
- * allocationList points to the array of slot structures used to manage the
- * malloc arena.
- */
-static Slot * allocationList = 0;
-
-/*
- * allocationListSize is the size of the allocation list. This will always
- * be a multiple of the page size.
- */
-static size_t allocationListSize = 0;
-
-/*
- * slotCount is the number of Slot structures in allocationList.
- */
-static size_t slotCount = 0;
-
-/*
- * unUsedSlots is the number of Slot structures that are currently available
- * to represent new malloc buffers. When this number gets too low, we will
- * create new slots.
- */
-static size_t unUsedSlots = 0;
-
-/*
- * slotsPerPage is the number of slot structures that fit in a virtual
- * memory page.
- */
-static size_t slotsPerPage = 0;
-
-/*
- * internalUse is set when allocating and freeing the allocatior-internal
- * data structures.
- */
-static int internalUse = 0;
-
-/*
- * noAllocationListProtection is set to tell malloc() and free() not to
- * manipulate the protection of the allocation list. This is only set in
- * realloc(), which does it to save on slow system calls, and in
- * allocateMoreSlots(), which does it because it changes the allocation list.
- */
-static int noAllocationListProtection = 0;
-
-/*
- * bytesPerPage is set at run-time to the number of bytes per virtual-memory
- * page, as returned by Page_Size().
- */
-static size_t bytesPerPage = 0;
-
-/*
- * internalError is called for those "shouldn't happen" errors in the
- * allocator.
- */
-static void
-internalError(void)
-{
- EF_Abort("Internal error in allocator.");
-}
-
-/*
- * initialize sets up the memory allocation arena and the run-time
- * configuration information.
- */
-static void
-initialize(void)
-{
- size_t size = MEMORY_CREATION_SIZE;
- size_t slack;
- char * string;
- Slot * slot;
-
- EF_Print(version);
-
- /*
- * Import the user's environment specification of the default
- * alignment for malloc(). We want that alignment to be under
- * user control, since smaller alignment lets us catch more bugs,
- * however some software will break if malloc() returns a buffer
- * that is not word-aligned.
- *
- * I would like
- * alignment to be zero so that we could catch all one-byte
- * overruns, however if malloc() is asked to allocate an odd-size
- * buffer and returns an address that is not word-aligned, or whose
- * size is not a multiple of the word size, software breaks.
- * This was the case with the Sun string-handling routines,
- * which can do word fetches up to three bytes beyond the end of a
- * string. I handle this problem in part by providing
- * byte-reference-only versions of the string library functions, but
- * there are other functions that break, too. Some in X Windows, one
- * in Sam Leffler's TIFF library, and doubtless many others.
- */
- if ( EF_ALIGNMENT == -1 ) {
- if ( (string = getenv("EF_ALIGNMENT")) != 0 )
- EF_ALIGNMENT = (size_t)atoi(string);
- else
- EF_ALIGNMENT = sizeof(int);
- }
-
- /*
- * See if the user wants to protect the address space below a buffer,
- * rather than that above a buffer.
- */
- if ( EF_PROTECT_BELOW == -1 ) {
- if ( (string = getenv("EF_PROTECT_BELOW")) != 0 )
- EF_PROTECT_BELOW = (atoi(string) != 0);
- else
- EF_PROTECT_BELOW = 0;
- }
-
- /*
- * See if the user wants to protect memory that has been freed until
- * the program exits, rather than until it is re-allocated.
- */
- if ( EF_PROTECT_FREE == -1 ) {
- if ( (string = getenv("EF_PROTECT_FREE")) != 0 )
- EF_PROTECT_FREE = (atoi(string) != 0);
- else
- EF_PROTECT_FREE = 0;
- }
-
- /*
- * See if the user wants to allow malloc(0).
- */
- if ( EF_ALLOW_MALLOC_0 == -1 ) {
- if ( (string = getenv("EF_ALLOW_MALLOC_0")) != 0 )
- EF_ALLOW_MALLOC_0 = (atoi(string) != 0);
- else
- EF_ALLOW_MALLOC_0 = 0;
- }
-
- /*
- * Get the run-time configuration of the virtual memory page size.
- */
- bytesPerPage = Page_Size();
-
- /*
- * Figure out how many Slot structures to allocate at one time.
- */
- slotCount = slotsPerPage = bytesPerPage / sizeof(Slot);
- allocationListSize = bytesPerPage;
-
- if ( allocationListSize > size )
- size = allocationListSize;
-
- if ( (slack = size % bytesPerPage) != 0 )
- size += bytesPerPage - slack;
-
- /*
- * Allocate memory, and break it up into two malloc buffers. The
- * first buffer will be used for Slot structures, the second will
- * be marked free.
- */
- slot = allocationList = (Slot *)Page_Create(size);
- memset((char *)allocationList, 0, allocationListSize);
-
- slot[0].internalSize = slot[0].userSize = allocationListSize;
- slot[0].internalAddress = slot[0].userAddress = allocationList;
- slot[0].mode = INTERNAL_USE;
- if ( size > allocationListSize ) {
- slot[1].internalAddress = slot[1].userAddress
- = ((char *)slot[0].internalAddress) + slot[0].internalSize;
- slot[1].internalSize
- = slot[1].userSize = size - slot[0].internalSize;
- slot[1].mode = FREE;
- }
-
- /*
- * Deny access to the free page, so that we will detect any software
- * that treads upon free memory.
- */
- Page_DenyAccess(slot[1].internalAddress, slot[1].internalSize);
-
- /*
- * Account for the two slot structures that we've used.
- */
- unUsedSlots = slotCount - 2;
-}
-
-/*
- * allocateMoreSlots is called when there are only enough slot structures
- * left to support the allocation of a single malloc buffer.
- */
-static void
-allocateMoreSlots(void)
-{
- size_t newSize = allocationListSize + bytesPerPage;
- void * newAllocation;
- void * oldAllocation = allocationList;
-
- Page_AllowAccess(allocationList, allocationListSize);
- noAllocationListProtection = 1;
- internalUse = 1;
-
- newAllocation = malloc(newSize);
- memcpy(newAllocation, allocationList, allocationListSize);
- memset(&(((char *)newAllocation)[allocationListSize]), 0, bytesPerPage);
-
- allocationList = (Slot *)newAllocation;
- allocationListSize = newSize;
- slotCount += slotsPerPage;
- unUsedSlots += slotsPerPage;
-
- free(oldAllocation);
-
- /*
- * Keep access to the allocation list open at this point, because
- * I am returning to memalign(), which needs that access.
- */
- noAllocationListProtection = 0;
- internalUse = 0;
-}
-
-/*
- * This is the memory allocator. When asked to allocate a buffer, allocate
- * it in such a way that the end of the buffer is followed by an inaccessable
- * memory page. If software overruns that buffer, it will touch the bad page
- * and get an immediate segmentation fault. It's then easy to zero in on the
- * offending code with a debugger.
- *
- * There are a few complications. If the user asks for an odd-sized buffer,
- * we would have to have that buffer start on an odd address if the byte after
- * the end of the buffer was to be on the inaccessable page. Unfortunately,
- * there is lots of software that asks for odd-sized buffers and then
- * requires that the returned address be word-aligned, or the size of the
- * buffer be a multiple of the word size. An example are the string-processing
- * functions on Sun systems, which do word references to the string memory
- * and may refer to memory up to three bytes beyond the end of the string.
- * For this reason, I take the alignment requests to memalign() and valloc()
- * seriously, and
- *
- * Electric Fence wastes lots of memory. I do a best-fit allocator here
- * so that it won't waste even more. It's slow, but thrashing because your
- * working set is too big for a system's RAM is even slower.
- */
-extern C_LINKAGE void *
-memalign(size_t alignment, size_t userSize)
-{
- register Slot * slot;
- register size_t count;
- Slot * fullSlot = 0;
- Slot * emptySlots[2];
- size_t internalSize;
- size_t slack;
- char * address;
-
- if ( allocationList == 0 )
- initialize();
-
- if ( userSize == 0 && !EF_ALLOW_MALLOC_0 )
- EF_Abort("Allocating 0 bytes, probably a bug.");
-
- /*
- * If EF_PROTECT_BELOW is set, all addresses returned by malloc()
- * and company will be page-aligned.
- */
- if ( !EF_PROTECT_BELOW && alignment > 1 ) {
- if ( (slack = userSize % alignment) != 0 )
- userSize += alignment - slack;
- }
-
- /*
- * The internal size of the buffer is rounded up to the next page-size
- * boudary, and then we add another page's worth of memory for the
- * dead page.
- */
- internalSize = userSize + bytesPerPage;
- if ( (slack = internalSize % bytesPerPage) != 0 )
- internalSize += bytesPerPage - slack;
-
- /*
- * These will hold the addresses of two empty Slot structures, that
- * can be used to hold information for any memory I create, and any
- * memory that I mark free.
- */
- emptySlots[0] = 0;
- emptySlots[1] = 0;
-
- /*
- * The internal memory used by the allocator is currently
- * inaccessable, so that errant programs won't scrawl on the
- * allocator's arena. I'll un-protect it here so that I can make
- * a new allocation. I'll re-protect it before I return.
- */
- if ( !noAllocationListProtection )
- Page_AllowAccess(allocationList, allocationListSize);
-
- /*
- * If I'm running out of empty slots, create some more before
- * I don't have enough slots left to make an allocation.
- */
- if ( !internalUse && unUsedSlots < 7 ) {
- allocateMoreSlots();
- }
-
- /*
- * Iterate through all of the slot structures. Attempt to find a slot
- * containing free memory of the exact right size. Accept a slot with
- * more memory than we want, if the exact right size is not available.
- * Find two slot structures that are not in use. We will need one if
- * we split a buffer into free and allocated parts, and the second if
- * we have to create new memory and mark it as free.
- *
- */
-
- for ( slot = allocationList, count = slotCount ; count > 0; count-- ) {
- if ( slot->mode == FREE
- && slot->internalSize >= internalSize ) {
- if ( !fullSlot
- ||slot->internalSize < fullSlot->internalSize){
- fullSlot = slot;
- if ( slot->internalSize == internalSize
- && emptySlots[0] )
- break; /* All done, */
- }
- }
- else if ( slot->mode == NOT_IN_USE ) {
- if ( !emptySlots[0] )
- emptySlots[0] = slot;
- else if ( !emptySlots[1] )
- emptySlots[1] = slot;
- else if ( fullSlot
- && fullSlot->internalSize == internalSize )
- break; /* All done. */
- }
- slot++;
- }
- if ( !emptySlots[0] )
- internalError();
-
- if ( !fullSlot ) {
- /*
- * I get here if I haven't been able to find a free buffer
- * with all of the memory I need. I'll have to create more
- * memory. I'll mark it all as free, and then split it into
- * free and allocated portions later.
- */
- size_t chunkSize = MEMORY_CREATION_SIZE;
-
- if ( !emptySlots[1] )
- internalError();
-
- if ( chunkSize < internalSize )
- chunkSize = internalSize;
-
- if ( (slack = chunkSize % bytesPerPage) != 0 )
- chunkSize += bytesPerPage - slack;
-
- /* Use up one of the empty slots to make the full slot. */
- fullSlot = emptySlots[0];
- emptySlots[0] = emptySlots[1];
- fullSlot->internalAddress = Page_Create(chunkSize);
- fullSlot->internalSize = chunkSize;
- fullSlot->mode = FREE;
- unUsedSlots--;
- }
-
- /*
- * If I'm allocating memory for the allocator's own data structures,
- * mark it INTERNAL_USE so that no errant software will be able to
- * free it.
- */
- if ( internalUse )
- fullSlot->mode = INTERNAL_USE;
- else
- fullSlot->mode = ALLOCATED;
-
- /*
- * If the buffer I've found is larger than I need, split it into
- * an allocated buffer with the exact amount of memory I need, and
- * a free buffer containing the surplus memory.
- */
- if ( fullSlot->internalSize > internalSize ) {
- emptySlots[0]->internalSize
- = fullSlot->internalSize - internalSize;
- emptySlots[0]->internalAddress
- = ((char *)fullSlot->internalAddress) + internalSize;
- emptySlots[0]->mode = FREE;
- fullSlot->internalSize = internalSize;
- unUsedSlots--;
- }
-
- if ( !EF_PROTECT_BELOW ) {
- /*
- * Arrange the buffer so that it is followed by an inaccessable
- * memory page. A buffer overrun that touches that page will
- * cause a segmentation fault.
- */
- address = (char *)fullSlot->internalAddress;
-
- /* Set up the "live" page. */
- if ( internalSize - bytesPerPage > 0 )
- Page_AllowAccess(
- fullSlot->internalAddress
- ,internalSize - bytesPerPage);
-
- address += internalSize - bytesPerPage;
-
- /* Set up the "dead" page. */
- if ( EF_PROTECT_FREE )
- Page_Delete(address, bytesPerPage);
- else
- Page_DenyAccess(address, bytesPerPage);
-
- /* Figure out what address to give the user. */
- address -= userSize;
- }
- else { /* EF_PROTECT_BELOW != 0 */
- /*
- * Arrange the buffer so that it is preceded by an inaccessable
- * memory page. A buffer underrun that touches that page will
- * cause a segmentation fault.
- */
- address = (char *)fullSlot->internalAddress;
-
- /* Set up the "dead" page. */
- if ( EF_PROTECT_FREE )
- Page_Delete(address, bytesPerPage);
- else
- Page_DenyAccess(address, bytesPerPage);
-
- address += bytesPerPage;
-
- /* Set up the "live" page. */
- if ( internalSize - bytesPerPage > 0 )
- Page_AllowAccess(address, internalSize - bytesPerPage);
- }
-
- fullSlot->userAddress = address;
- fullSlot->userSize = userSize;
-
- /*
- * Make the pool's internal memory inaccessable, so that the program
- * being debugged can't stomp on it.
- */
- if ( !internalUse )
- Page_DenyAccess(allocationList, allocationListSize);
-
- return address;
-}
-
-/*
- * Find the slot structure for a user address.
- */
-static Slot *
-slotForUserAddress(void * address)
-{
- register Slot * slot = allocationList;
- register size_t count = slotCount;
-
- for ( ; count > 0; count-- ) {
- if ( slot->userAddress == address )
- return slot;
- slot++;
- }
-
- return 0;
-}
-
-/*
- * Find the slot structure for an internal address.
- */
-static Slot *
-slotForInternalAddress(void * address)
-{
- register Slot * slot = allocationList;
- register size_t count = slotCount;
-
- for ( ; count > 0; count-- ) {
- if ( slot->internalAddress == address )
- return slot;
- slot++;
- }
- return 0;
-}
-
-/*
- * Given the internal address of a buffer, find the buffer immediately
- * before that buffer in the address space. This is used by free() to
- * coalesce two free buffers into one.
- */
-static Slot *
-slotForInternalAddressPreviousTo(void * address)
-{
- register Slot * slot = allocationList;
- register size_t count = slotCount;
-
- for ( ; count > 0; count-- ) {
- if ( ((char *)slot->internalAddress)
- + slot->internalSize == address )
- return slot;
- slot++;
- }
- return 0;
-}
-
-extern C_LINKAGE void
-free(void * address)
-{
- Slot * slot;
- Slot * previousSlot = 0;
- Slot * nextSlot = 0;
-
- if ( address == 0 )
- return;
-
- if ( allocationList == 0 )
- EF_Abort("free() called before first malloc().");
-
- if ( !noAllocationListProtection )
- Page_AllowAccess(allocationList, allocationListSize);
-
- slot = slotForUserAddress(address);
-
- if ( !slot )
- EF_Abort("free(%a): address not from malloc().", address);
-
- if ( slot->mode != ALLOCATED ) {
- if ( internalUse && slot->mode == INTERNAL_USE )
- /* Do nothing. */;
- else {
- EF_Abort(
- "free(%a): freeing free memory."
- ,address);
- }
- }
-
- if ( EF_PROTECT_FREE )
- slot->mode = PROTECTED;
- else
- slot->mode = FREE;
-
- previousSlot = slotForInternalAddressPreviousTo(slot->internalAddress);
- nextSlot = slotForInternalAddress(
- ((char *)slot->internalAddress) + slot->internalSize);
-
- if ( previousSlot
- && (previousSlot->mode == FREE || previousSlot->mode == PROTECTED) ) {
- /* Coalesce previous slot with this one. */
- previousSlot->internalSize += slot->internalSize;
- if ( EF_PROTECT_FREE )
- previousSlot->mode = PROTECTED;
-
- slot->internalAddress = slot->userAddress = 0;
- slot->internalSize = slot->userSize = 0;
- slot->mode = NOT_IN_USE;
- slot = previousSlot;
- unUsedSlots++;
- }
- if ( nextSlot
- && (nextSlot->mode == FREE || nextSlot->mode == PROTECTED) ) {
- /* Coalesce next slot with this one. */
- slot->internalSize += nextSlot->internalSize;
- nextSlot->internalAddress = nextSlot->userAddress = 0;
- nextSlot->internalSize = nextSlot->userSize = 0;
- nextSlot->mode = NOT_IN_USE;
- unUsedSlots++;
- }
-
- slot->userAddress = slot->internalAddress;
- slot->userSize = slot->internalSize;
-
- /*
- * Free memory is _always_ set to deny access. When EF_PROTECT_FREE
- * is true, free memory is never reallocated, so it remains access
- * denied for the life of the process. When EF_PROTECT_FREE is false,
- * the memory may be re-allocated, at which time access to it will be
- * allowed again.
- *
- * Some operating systems allow munmap() with single-page resolution,
- * and allow you to un-map portions of a region, rather than the
- * entire region that was mapped with mmap(). On those operating
- * systems, we can release protected free pages with Page_Delete(),
- * in the hope that the swap space attached to those pages will be
- * released as well.
- */
- if ( EF_PROTECT_FREE )
- Page_Delete(slot->internalAddress, slot->internalSize);
- else
- Page_DenyAccess(slot->internalAddress, slot->internalSize);
-
- if ( !noAllocationListProtection )
- Page_DenyAccess(allocationList, allocationListSize);
-}
-
-extern C_LINKAGE void *
-realloc(void * oldBuffer, size_t newSize)
-{
- void * newBuffer = malloc(newSize);
-
- if ( oldBuffer ) {
- size_t size;
- Slot * slot;
-
- Page_AllowAccess(allocationList, allocationListSize);
- noAllocationListProtection = 1;
-
- slot = slotForUserAddress(oldBuffer);
-
- if ( slot == 0 )
- EF_Abort(
- "realloc(%a, %d): address not from malloc()."
- ,oldBuffer
- ,newSize);
-
- if ( newSize < (size = slot->userSize) )
- size = newSize;
-
- if ( size > 0 )
- memcpy(newBuffer, oldBuffer, size);
-
- free(oldBuffer);
- noAllocationListProtection = 0;
- Page_DenyAccess(allocationList, allocationListSize);
-
- if ( size < newSize )
- memset(&(((char *)newBuffer)[size]), 0, newSize - size);
-
- /* Internal memory was re-protected in free() */
- }
-
- return newBuffer;
-}
-
-extern C_LINKAGE void *
-malloc(size_t size)
-{
- if ( allocationList == 0 )
- initialize(); /* This sets EF_ALIGNMENT */
-
- return memalign(EF_ALIGNMENT, size);
-}
-
-extern C_LINKAGE void *
-calloc(size_t nelem, size_t elsize)
-{
- size_t size = nelem * elsize;
- void * allocation = malloc(size);
-
- memset(allocation, 0, size);
- return allocation;
-}
-
-/*
- * This will catch more bugs if you remove the page alignment, but it
- * will break some software.
- */
-extern C_LINKAGE void *
-valloc (size_t size)
-{
- return memalign(bytesPerPage, size);
-}
-
-#ifdef __hpux
-/*
- * HP-UX 8/9.01 strcat reads a word past source when doing unaligned copies!
- * Work around it here. The bug report has been filed with HP.
- */
-char *strcat(char *d, const char *s)
-{
- strcpy(d+strlen(d), s);
- return d;
-}
-#endif
+++ /dev/null
-#include <sys/types.h>
-#include <sys/param.h>
-
-/*
- * ef_number is the largest unsigned integer we'll need. On systems that
- * support 64-bit pointers, this may be "unsigned long long".
- */
-#if defined(USE_LONG_LONG)
-typedef unsigned long long ef_number;
-#else
-typedef unsigned long ef_number;
-#endif
-
-/*
- * NBBY is the number of bits per byte. Some systems define it in
- * <sys/param.h> .
- */
-#ifndef NBBY
-#define NBBY 8
-#endif
-
-/*
- * This is used to declare functions with "C" linkage if we are compiling
- * with C++ .
- */
-#ifdef __cplusplus
-#define C_LINKAGE "C"
-#else
-#define C_LINKAGE
-#endif
-
-void Page_AllowAccess(void * address, size_t size);
-void * Page_Create(size_t size);
-void Page_Delete(void * address, size_t size);
-void Page_DenyAccess(void * address, size_t size);
-size_t Page_Size(void);
-
-void EF_Abort(const char * message, ...);
-void EF_Exit(const char * message, ...);
-void EF_Print(const char * message, ...);
-void EF_Lock();
-void EF_UnLock();
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <setjmp.h>
-#include <signal.h>
-#include "efence.h"
-
-/*
- * Electric Fence confidence tests.
- * Make sure all of the various functions of Electric Fence work correctly.
- */
-
-#ifndef PAGE_PROTECTION_VIOLATED_SIGNAL
-#define PAGE_PROTECTION_VIOLATED_SIGNAL SIGSEGV
-#endif
-
-struct diagnostic {
- int (*test)(void);
- int expectedStatus;
- const char * explanation;
-};
-
-extern int EF_PROTECT_BELOW;
-extern int EF_ALIGNMENT;
-
-static jmp_buf env;
-
-/*
- * There is still too little standardization of the arguments and return
- * type of signal handler functions.
- */
-static
-void
-segmentationFaultHandler(
-int signalNumber
-#if ( defined(_AIX) )
-, ...
-#endif
-)
- {
- signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
- longjmp(env, 1);
-}
-
-static int
-gotSegmentationFault(int (*test)(void))
-{
- if ( setjmp(env) == 0 ) {
- int status;
-
- signal(PAGE_PROTECTION_VIOLATED_SIGNAL
- ,segmentationFaultHandler);
- status = (*test)();
- signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
- return status;
- }
- else
- return 1;
-}
-
-static char * allocation;
-/* c is global so that assignments to it won't be optimized out. */
-char c;
-
-static int
-testSizes(void)
-{
- /*
- * If ef_number can't hold all of the bits of a void *, have the user
- * add -DUSE_ LONG_LONG to the compiler flags so that ef_number will be
- * declared as "unsigned long long" instead of "unsigned long".
- */
- return ( sizeof(ef_number) < sizeof(void *) );
-}
-
-static int
-allocateMemory(void)
-{
- allocation = (char *)malloc(1);
-
- if ( allocation != 0 )
- return 0;
- else
- return 1;
-}
-
-static int
-freeMemory(void)
-{
- free(allocation);
- return 0;
-}
-
-static int
-protectBelow(void)
-{
- EF_PROTECT_BELOW = 1;
- return 0;
-}
-
-static int
-read0(void)
-{
- c = *allocation;
-
- return 0;
-}
-
-static int
-write0(void)
-{
- *allocation = 1;
-
- return 0;
-}
-
-static int
-read1(void)
-{
- c = allocation[1];
-
- return 0;
-}
-
-static int
-readMinus1(void)
-{
- c = allocation[-1];
- return 0;
-}
-
-static struct diagnostic diagnostics[] = {
- {
- testSizes, 0,
- "Please add -DLONG_LONG to the compiler flags and recompile."
- },
- {
- allocateMemory, 0,
- "Allocation 1: This test allocates a single byte of memory."
- },
- {
- read0, 0,
- "Read valid memory 1: This test reads the allocated memory."
- },
- {
- write0, 0,
- "Write valid memory 1: This test writes the allocated memory."
- },
- {
- read1, 1,
- "Read overrun: This test reads beyond the end of the buffer."
- },
- {
- freeMemory, 0,
- "Free memory: This test frees the allocated memory."
- },
- {
- protectBelow, 0,
- "Protect below: This sets Electric Fence to protect\n"
- "the lower boundary of a malloc buffer, rather than the\n"
- "upper boundary."
- },
- {
- allocateMemory, 0,
- "Allocation 2: This allocates memory with the lower boundary"
- " protected."
- },
- {
- read0, 0,
- "Read valid memory 2: This test reads the allocated memory."
- },
- {
- write0, 0,
- "Write valid memory 2: This test writes the allocated memory."
- },
- {
- readMinus1, 1,
- "Read underrun: This test reads before the beginning of the"
- " buffer."
- },
- {
- 0, 0, 0
- }
-};
-
-static const char failedTest[]
- = "Electric Fence confidence test failed.\n";
-
-static const char newline = '\n';
-
-int
-main(int argc, char * * argv)
-{
- static const struct diagnostic * diag = diagnostics;
-
-
- EF_PROTECT_BELOW = 0;
- EF_ALIGNMENT = 0;
-
- while ( diag->explanation != 0 ) {
- int status = gotSegmentationFault(diag->test);
-
- if ( status != diag->expectedStatus ) {
- /*
- * Don't use stdio to print here, because stdio
- * uses malloc() and we've just proven that malloc()
- * is broken. Also, use _exit() instead of exit(),
- * because _exit() doesn't flush stdio.
- */
- write(2, failedTest, sizeof(failedTest) - 1);
- write(2, diag->explanation, strlen(diag->explanation));
- write(2, &newline, 1);
- _exit(-1);
- }
- diag++;
- }
- return 0;
-}
+++ /dev/null
-.TH efence 3 27-April-1993
-.SH NAME
-efence \- Electric Fence Malloc Debugger
-.SH SYNOPSIS
-.nf
-.ft B
-#include <stdlib.h>
-.ft
-.fi
-.LP
-.nf
-.ft B
-void * malloc (size_t size);
-.ft
-.fi
-.LP
-.nf
-.ft B
-void free (void *ptr);
-.ft
-.fi
-.LP
-.nf
-.ft B
-void * realloc (void *ptr, size_t size);
-.ft
-.fi
-.LP
-.nf
-.ft B
-void * calloc (size_t nelem, size_t elsize);
-.ft
-.fi
-.LP
-.nf
-.ft B
-void * memalign (size_t alignment, size_t size);
-.ft
-.fi
-.LP
-.nf
-.ft B
-void * valloc (size_t size);
-.ft
-.fi
-.LP
-.nf
-.ft B
-extern int EF_ALIGNMENT;
-.ft
-.fi
-.LP
-.nf
-.ft B
-extern int EF_PROTECT_BELOW;
-.ft
-.fi
-.LP
-.nf
-.ft B
-extern int EF_PROTECT_FREE;
-.ft
-.fi
-.SH DESCRIPTION
-.I Electric Fence
-helps you detect two common programming bugs:
-software that overruns the boundaries of a malloc() memory
-allocation, and software that touches a memory allocation that has been
-released by free(). Unlike other malloc() debuggers, Electric Fence will
-detect
-.I read
-accesses as well as writes, and it will pinpoint the exact instruction that
-causes an error. It has been in use at Pixar since 1987, and at many other
-sites for years.
-.LP
-Electric Fence uses the virtual memory hardware of your computer to place an
-inaccessible memory page immediately after (or before, at the user's option)
-each memory allocation. When software reads or writes this inaccessible page,
-the
-hardware issues a segmentation fault, stopping the program at the offending
-instruction. It is then trivial to find the erroneous statement using your
-favorite debugger. In a similar manner, memory that has been released by
-free() is made inaccessible, and any code that touches it will get a
-segmentation fault.
-.LP
-Simply linking your application with libefence.a will allow you to detect
-most, but not all, malloc buffer overruns and accesses of free memory.
-If you want to be reasonably sure that you've found
-.I all
-bugs of this type, you'll have to read and understand the rest of this
-man page.
-.SH USAGE
-Link your program with the library
-.B libefence.a .
-Make sure you are
-.I not
-linking with
-.B -lmalloc,
-.B -lmallocdebug,
-or with other malloc-debugger or malloc-enhancer libraries.
-You can only use one at a time.
-If your system administrator
-has installed Electric Fence for public use, you'll be able to use the
-.B -lefence
-argument to the linker, otherwise you'll have to put the path-name for
-.B libefence.a
-in the linker's command line.
-Some systems will require special arguments to the linker to assure that
-you are using the Electric Fence malloc() and not the one from your C library.
-On AIX systems, you may have to use the flags
-.br
-.B -bnso
-.B -bnodelcsect
-.B -bI:/lib/syscalls.exp
-.br
-On Sun systems running SunOS 4.X, you'll probably have to use
-.B -Bstatic.
-.LP
-Run your program
-.I using a debugger.
-It's easier to work this way than to create a
-.B core
-file and post-mortem debug it. Electric Fence can create
-.I huge
-core files, and some operating systems will thus take minutes simply to dump
-core! Some operating systems will not create usable core files from programs
-that are linked with Electric Fence.
-If your program has one of the errors detected by Electric Fence, it will
-get a segmentation fault (SIGSEGV) at the offending instruction. Use the
-debugger to locate the erroneous statement, and repair it.
-.SH GLOBAL AND ENVIRONMENT VARIABLES
-Electric Fence has four configuration switches that can be enabled via
-the shell environment, or by setting the value of global integer variables
-using a debugger. These switches change what bugs Electric Fence will detect,
-so it's important that you know how to use them.
-.TP
-EF_ALIGNMENT
-This is an integer that specifies the alignment for any memory allocations
-that will be returned by malloc(), calloc(), and realloc().
-The value is specified in
-bytes, thus a value of 4 will cause memory to be aligned to 32-bit boundaries
-unless your system doesn't have a 8-bit characters. EF_ALIGNMENT is set to
-sizeof(int) by default, since that is generally the word-size of your CPU.
-If your program requires that allocations be aligned to 64-bit
-boundaries and you have a 32-bit
-.B int
-you'll have to set this value to 8. This is the case when compiling with the
-.B -mips2
-flag on MIPS-based systems such as those from SGI.
-The memory allocation that is returned by Electric Fence malloc() is aligned
-using the value in EF_ALIGNMENT, and
-.I its size the multiple of
-.I that value
-that is greater than or equal to the requested size.
-For this reason, you will sometimes want to set EF_ALIGNMENT to 0 (no
-alignment), so that
-you can detect overruns of less than your CPU's word size. Be sure to read
-the section
-.I WORD-ALIGNMENT AND OVERRUN DETECTION
-in this manual page before you try this.
-To change this value, set EF_ALIGNMENT in the shell environment to an
-integer value, or assign
-to the global integer variable EF_ALIGNMENT using a debugger.
-.TP
-EF_PROTECT_BELOW
-Electric Fence usually places an inaccessible page immediately after each
-memory allocation, so that software that runs past the end of the allocation
-will be detected. Setting EF_PROTECT_BELOW to 1 causes Electric Fence
-to place the inaccessible page
-.I before
-the allocation in the address space, so that under-runs will be detected
-instead of over-runs.
-When EF_PROTECT_BELOW is set, the EF_ALIGNMENT parameter is ignored.
-All allocations will be aligned to virtual-memory-page boundaries, and
-their size will be the exact size that was requested.
-To change this value, set EF_PROTECT_BELOW in the shell environment to an
-integer value, or assign to the global integer variable EF_PROTECT_BELOW using
-a debugger.
-.TP
-EF_PROTECT_FREE
-Electric Fence usually returns free memory to a pool from which it may be
-re-allocated. If you suspect that a program may be touching free memory,
-set EF_PROTECT_FREE to 1. This will cause Electric Fence to never re-allocate
-memory once it has been freed, so that any access to free memory will be
-detected. Some programs will use tremendous amounts of memory when this
-parameter is set.
-To change this value, set EF_PROTECT_FREE in the shell environment to an
-integer value, or assign to the global integer variable EF_PROTECT_FREE using
-a debugger.
-.TP
-EF_ALLOW_MALLOC_0
-By default, Electric Fence traps calls to malloc() with a size of zero, because
-they are often the result of a software bug. If EF_ALLOW_MALLOC_0 is non-zero,
-the software will not trap calls to malloc() with a size of zero.
-To change this value, set EF_ALLOC_MALLOC_0 in the shell environment to an
-integer value, or assign to the global integer variable EF_ALLOC_MALLOC_0 using
-a debugger.
-.SH WORD-ALIGNMENT AND OVERRUN DETECTION
-There is a conflict between the alignment restrictions that malloc() operates
-under and the debugging strategy used by Electric Fence. When detecting
-overruns, Electric Fence malloc() allocates two or more virtual memory
-pages for each allocation. The last page is made inaccessible in such a way
-that any read, write, or execute access will cause a segmentation fault.
-Then, Electric Fence malloc() will return an address such that the first
-byte after
-the end of the allocation is on the inaccessible page.
-Thus, any overrun
-of the allocation will cause a segmentation fault.
-.LP
-It follows that the
-address returned by malloc() is the address of the inaccessible page minus
-the size of the memory allocation.
-Unfortunately, malloc() is required to return
-.I word-aligned
-allocations, since many CPUs can only access a word when its address is aligned.
-The conflict happens when software makes a memory allocation using a size that
-is not a multiple of the word size, and expects to do word accesses to that
-allocation. The location of the inaccessible page is fixed by hardware at
-a word-aligned address. If Electric Fence malloc() is to return an aligned
-address, it must increase the size of the allocation to a multiple of the
-word size.
-In addition, the functions memalign() and valloc() must honor explicit
-specifications on the alignment of the memory allocation, and this, as well
-can only be implemented by increasing the size of the allocation.
-Thus, there will be situations in which the end of a memory allocation
-contains some padding space, and accesses of that padding space will not
-be detected, even if they are overruns.
-.LP
-Electric Fence provides the variable EF_ALIGNMENT so that the user can
-control the default alignment used by malloc(), calloc(), and realloc().
-To debug overruns as small as a single byte, you can set EF_ALIGNMENT to
-zero. This will result in Electric Fence malloc() returning unaligned
-addresses for allocations with sizes that are not a multiple of the word
-size. This is not a problem in most cases, because compilers must pad the
-size of objects so that alignment restrictions are honored when storing
-those objects in arrays. The problem surfaces when software allocates
-odd-sized buffers for objects that must be word-aligned. One case of this
-is software that allocates a buffer to contain a structure and a
-string, and the string has an odd size (this example was in a popular TIFF
-library). If word references are made to un-aligned buffers, you will see
-a bus error (SIGBUS) instead of a segmentation fault. The only way to fix
-this is to re-write the offending code to make byte references or not make
-odd-sized allocations, or to set EF_ALIGNMENT to the word size.
-.LP
-Another example of software incompatible with
-EF_ALIGNMENT < word-size
-is the strcmp() function and other string functions on SunOS (and probably
-Solaris), which make word-sized accesses to character strings, and may
-attempt to access up to three bytes beyond the end of a string. These
-result in a segmentation fault (SIGSEGV). The only way around this is to
-use versions of the string functions that perform byte references instead
-of word references.
-.SH INSTRUCTIONS FOR DEBUGGING YOUR PROGRAM
-.TP
-1.
-Link with libefence.a as explained above.
-.TP
-2.
-Run your program in a debugger and fix any overruns or accesses to free memory.
-.TP
-3.
-Quit the debugger.
-.TP
-4.
-Set EF_PROTECT_BELOW = 1 in the shell environment.
-.TP
-5.
-Repeat step 2, this time repairing underruns if they occur.
-.TP
-6.
-Quit the debugger.
-.TP
-7.
-Read the restrictions in the section on
-.I WORD-ALIGNMENT AND OVERRUN DETECTION.
-See if you can
-set EF_ALIGNMENT to 0 and repeat step 2. Sometimes this will be too much work,
-or there will be problems with library routines for which you don't have the
-source, that will prevent you from doing this.
-.SH MEMORY USAGE AND EXECUTION SPEED
-Since Electric Fence uses at least two virtual memory pages for each of its
-allocations, it's a terrible memory hog. I've sometimes found it necessary to
-add a swap file using swapon(8) so that the system would have enough virtual
-memory to debug my program. Also, the way we manipulate memory results in
-various cache and translation buffer entries being flushed with each call
-to malloc or free. The end result is that your program will be much slower
-and use more resources while you are debugging it with Electric Fence.
-.LP
-Don't leave libefence.a linked into production software! Use it only
-for debugging.
-.SH PORTING
-Electric Fence is written for ANSI C. You should be able to port it with
-simple changes to the Makefile and to page.c,
-which contains the memory management primitives .
-Many POSIX platforms will require only a re-compile.
-The operating system facilities required to port Electric Fence are:
-.IP
-A way to allocate memory pages
-.br
-A way to make selected pages inaccessible.
-.br
-A way to make the pages accessible again.
-.br
-A way to detect when a program touches an inaccessible page.
-.br
-A way to print messages.
-.LP
-Please e-mail me a copy of any changes you have to make, so that I can
-merge them into the distribution.
-.SH AUTHOR
-Bruce Perens
-.SH WARNINGS
-I have tried to do as good a job as I can on this software, but I doubt
-that it is even theoretically possible to make it bug-free.
-This software has no warranty. It will not detect some bugs that you might
-expect it to detect, and will indicate that some non-bugs are bugs.
-Bruce Perens and/or Pixar will not be liable to any claims resulting
-from the use of this software or the ideas within it.
-The entire responsibility for its use must
-be assumed by the user. If you use it and it results in loss of life
-and/or property, tough. If it leads you on a wild goose chase and you waste
-two weeks debugging something, too bad.
-If you can't deal with the above, please don't use the software! I've written
-this in an attempt to help other people, not to get myself sued or prosecuted.
-.SH LICENSE
-Copyright 1987-1995 Bruce Perens. All rights reserved.
-.br
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License, Version 2,
-as published by the Free Software Foundation. A copy of this license is
-distributed with this software in the file "COPYING".
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Read the
-file "COPYING" for more details.
-.SH CONTACTING THE AUTHOR
-.nf
-Bruce Perens
-c/o Pixar
-1001 West Cutting Blvd., Suite 200
-Richmond, CA 94804
-
-Telephone: 510-215-3502
-Fax: 510-236-0388
-Internet: Bruce@Pixar.com
-.fi
-.ft
-.SH FILES
-/dev/zero: Source of memory pages (via mmap(2)).
-.SH SEE ALSO
-malloc(3), mmap(2), mprotect(2), swapon(8)
-.SH DIAGNOSTICS
-Segmentation Fault: Examine the offending statement for violation of the
-boundaries of a memory allocation.
-.br
-Bus Error: See the section on
-.I WORD-ALIGNMENT AND OVERRUN DETECTION.
-in this manual page.
-.SH BUGS
-My explanation of the alignment issue could be improved.
-.LP
-Some Sun systems running SunOS 4.1 are reported to signal an access to a
-protected page with
-.B SIGBUS
-rather than
-.B SIGSEGV,
-I suspect this is an undocumented feature of a particular Sun hardware
-version, not just the operating system.
-On these systems, eftest will fail with a bus error until you modify the
-Makefile to define
-.B PAGE_PROTECTION_VIOLATED_SIGNAL
-as
-.B SIGBUS.
-.LP
-There are, without doubt, other bugs and porting issues. Please contact me via
-e-mail if you have any bug reports, ideas, etc.
-.SH WHAT'S BETTER
-PURIFY, from Purify Systems, does a much better job than Electric Fence, and
-does much more. It's available at this writing on SPARC and HP.
-I'm not affiliated with Purify, I just think it's a wonderful product
-and you should check it out.
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include "efence.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-/*
- * Lots of systems are missing the definition of PROT_NONE.
- */
-#ifndef PROT_NONE
-#define PROT_NONE 0
-#endif
-
-/*
- * 386 BSD has MAP_ANON instead of MAP_ANONYMOUS.
- */
-#if ( !defined(MAP_ANONYMOUS) && defined(MAP_ANON) )
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-/*
- * For some reason, I can't find mprotect() in any of the headers on
- * IRIX or SunOS 4.1.2
- */
-/* extern C_LINKAGE int mprotect(void * addr, size_t len, int prot); */
-
-static caddr_t startAddr = (caddr_t) 0;
-
-static const char *
-stringErrorReport(void)
-{
- return strerror(errno);
-}
-
-/*
- * Create memory.
- */
-#if defined(MAP_ANONYMOUS)
-void *
-Page_Create(size_t size)
-{
- caddr_t allocation;
-
- /*
- * In this version, "startAddr" is a _hint_, not a demand.
- * When the memory I map here is contiguous with other
- * mappings, the allocator can coalesce the memory from two
- * or more mappings into one large contiguous chunk, and thus
- * might be able to find a fit that would not otherwise have
- * been possible. I could _force_ it to be contiguous by using
- * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
- * generated by other software, etc.
- */
- allocation = (caddr_t) mmap(
- startAddr
- ,(int)size
- ,PROT_READ|PROT_WRITE
- ,MAP_PRIVATE|MAP_ANONYMOUS
- ,-1
- ,0);
-
-#ifndef __hpux
- /*
- * Set the "address hint" for the next mmap() so that it will abut
- * the mapping we just created.
- *
- * HP/UX 9.01 has a kernel bug that makes mmap() fail sometimes
- * when given a non-zero address hint, so we'll leave the hint set
- * to zero on that system. HP recently told me this is now fixed.
- * Someone please tell me when it is probable to assume that most
- * of those systems that were running 9.01 have been upgraded.
- */
- startAddr = allocation + size;
-#endif
-
- if ( allocation == (caddr_t)-1 )
- EF_Exit("mmap() failed: %s", stringErrorReport());
-
- return (void *)allocation;
-}
-#else
-void *
-Page_Create(size_t size)
-{
- static int devZeroFd = -1;
- caddr_t allocation;
-
- if ( devZeroFd == -1 ) {
- devZeroFd = open("/dev/zero", O_RDWR);
- if ( devZeroFd < 0 )
- EF_Exit(
- "open() on /dev/zero failed: %s"
- ,stringErrorReport());
- }
-
- /*
- * In this version, "startAddr" is a _hint_, not a demand.
- * When the memory I map here is contiguous with other
- * mappings, the allocator can coalesce the memory from two
- * or more mappings into one large contiguous chunk, and thus
- * might be able to find a fit that would not otherwise have
- * been possible. I could _force_ it to be contiguous by using
- * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
- * generated by other software, etc.
- */
- allocation = (caddr_t) mmap(
- startAddr
- ,(int)size
- ,PROT_READ|PROT_WRITE
- ,MAP_PRIVATE
- ,devZeroFd
- ,0);
-
- startAddr = allocation + size;
-
- if ( allocation == (caddr_t)-1 )
- EF_Exit("mmap() failed: %s", stringErrorReport());
-
- return (void *)allocation;
-}
-#endif
-
-static void
-mprotectFailed(void)
-{
- EF_Exit("mprotect() failed: %s", stringErrorReport());
-}
-
-void
-Page_AllowAccess(void * address, size_t size)
-{
- if ( mprotect((caddr_t)address, size, PROT_READ|PROT_WRITE) < 0 )
- mprotectFailed();
-}
-
-void
-Page_DenyAccess(void * address, size_t size)
-{
- if ( mprotect((caddr_t)address, size, PROT_NONE) < 0 )
- mprotectFailed();
-}
-
-void
-Page_Delete(void * address, size_t size)
-{
- if ( munmap((caddr_t)address, size) < 0 )
- Page_DenyAccess(address, size);
-}
-
-#if defined(_SC_PAGESIZE)
-size_t
-Page_Size(void)
-{
- return (size_t)sysconf(_SC_PAGESIZE);
-}
-#elif defined(_SC_PAGE_SIZE)
-size_t
-Page_Size(void)
-{
- return (size_t)sysconf(_SC_PAGE_SIZE);
-}
-#else
-/* extern int getpagesize(); */
-size_t
-Page_Size(void)
-{
- return getpagesize();
-}
-#endif
+++ /dev/null
-#include "efence.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-
-/*
- * These routines do their printing without using stdio. Stdio can't
- * be used because it calls malloc(). Internal routines of a malloc()
- * debugger should not re-enter malloc(), so stdio is out.
- */
-
-/*
- * NUMBER_BUFFER_SIZE is the longest character string that could be needed
- * to represent an unsigned integer, assuming we might print in base 2.
- */
-#define NUMBER_BUFFER_SIZE (sizeof(ef_number) * NBBY)
-
-static void
-printNumber(ef_number number, ef_number base)
-{
- char buffer[NUMBER_BUFFER_SIZE];
- char * s = &buffer[NUMBER_BUFFER_SIZE];
- int size;
-
- do {
- ef_number digit;
-
- if ( --s == buffer )
- EF_Abort("Internal error printing number.");
-
- digit = number % base;
-
- if ( digit < 10 )
- *s = '0' + digit;
- else
- *s = 'a' + digit - 10;
-
- } while ( (number /= base) > 0 );
-
- size = &buffer[NUMBER_BUFFER_SIZE] - s;
-
- if ( size > 0 )
- write(2, s, size);
-}
-
-static void
-vprint(const char * pattern, va_list args)
-{
- static const char bad_pattern[] =
- "\nBad pattern specifier %%%c in EF_Print().\n";
- const char * s = pattern;
- char c;
-
- while ( (c = *s++) != '\0' ) {
- if ( c == '%' ) {
- c = *s++;
- switch ( c ) {
- case '%':
- (void) write(2, &c, 1);
- break;
- case 'a':
- /*
- * Print an address passed as a void pointer.
- * The type of ef_number must be set so that
- * it is large enough to contain all of the
- * bits of a void pointer.
- */
- printNumber(
- (ef_number)va_arg(args, void *)
- ,0x10);
- break;
- case 's':
- {
- const char * string;
- size_t length;
-
- string = va_arg(args, char *);
- length = strlen(string);
-
- (void) write(2, string, length);
- }
- break;
- case 'd':
- {
- int n = va_arg(args, int);
-
- if ( n < 0 ) {
- char c = '-';
- write(2, &c, 1);
- n = -n;
- }
- printNumber(n, 10);
- }
- break;
- case 'x':
- printNumber(va_arg(args, u_int), 0x10);
- break;
- case 'c':
- {
- char c = va_arg(args, char);
-
- (void) write(2, &c, 1);
- }
- break;
- default:
- {
- EF_Print(bad_pattern, c);
- }
-
- }
- }
- else
- (void) write(2, &c, 1);
- }
-}
-
-void
-EF_Abort(const char * pattern, ...)
-{
- va_list args;
-
- va_start(args, pattern);
-
- EF_Print("\nElectricFence Aborting: ");
- vprint(pattern, args);
- EF_Print("\n");
-
- va_end(args);
-
- /*
- * I use kill(getpid(), SIGILL) instead of abort() because some
- * mis-guided implementations of abort() flush stdio, which can
- * cause malloc() or free() to be called.
- */
- kill(getpid(), SIGILL);
- /* Just in case something handles SIGILL and returns, exit here. */
- _exit(-1);
-}
-
-void
-EF_Exit(const char * pattern, ...)
-{
- va_list args;
-
- va_start(args, pattern);
-
- EF_Print("\nElectricFence Exiting: ");
- vprint(pattern, args);
- EF_Print("\n");
-
- va_end(args);
-
- /*
- * I use _exit() because the regular exit() flushes stdio,
- * which may cause malloc() or free() to be called.
- */
- _exit(-1);
-}
-
-void
-EF_Print(const char * pattern, ...)
-{
- va_list args;
-
- va_start(args, pattern);
- vprint(pattern, args);
- va_end(args);
-}
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <limits.h>
-#include "efence.h"
-
-/*
- * This is a simple program to exercise the allocator. It allocates and frees
- * memory in a pseudo-random fashion. It should run silently, using up time
- * and resources on your system until you stop it or until it has gone
- * through TEST_DURATION (or the argument) iterations of the loop.
- */
-
-extern C_LINKAGE double drand48(void); /* For pre-ANSI C systems */
-
-#define POOL_SIZE 1024
-#define LARGEST_BUFFER 30000
-#define TEST_DURATION 1000000
-
-void * pool[POOL_SIZE];
-
-#ifdef FAKE_DRAND48
-/*
- * Add -DFAKE_DRAND48 to your compile flags if your system doesn't
- * provide drand48().
- */
-
-#ifndef ULONG_MAX
-#define ULONG_MAX ~(1L)
-#endif
-
-double
-drand48(void)
-{
- return (random() / (double)ULONG_MAX);
-}
-#endif
-
-int
-main(int argc, char * * argv)
-{
- int count = 0;
- int duration = TEST_DURATION;
-
- if ( argc >= 2 )
- duration = atoi(argv[1]);
-
- for ( ; count < duration; count++ ) {
- void * * element = &pool[(int)(drand48() * POOL_SIZE)];
- size_t size = (size_t)(drand48() * (LARGEST_BUFFER + 1));
-
- if ( *element ) {
- free( *element );
- *element = 0;
- }
- else if ( size > 0 ) {
- *element = malloc(size);
- }
- }
- return 0;
-}
SUBDIRS = \
scripts \
include \
- ElectricFence \
libntp \
sntp \
libparse \
esac
AC_MSG_RESULT([$ntp_autokey])
-AC_MSG_CHECKING([if we want to compile with ElectricFence])
-AC_ARG_WITH(
- [electricfence],
- [AS_HELP_STRING(
- [--with-electricfence],
- [- compile with ElectricFence malloc debugger]
- )],
- [ans=$withval],
- [ans=no]
-)
-case "$ans" in
- no) ;;
- *)
- LIBS="$LIBS \${top_builddir}/ElectricFence/libefence.a"
- EF_PROGS="eftest tstheap"
- AC_SUBST([EF_PROGS])
- EF_LIBS=libefence.a
- AC_SUBST([EF_LIBS])
- ans=yes
- ;;
-esac
-AC_MSG_RESULT([$ans])
-
AC_SUBST([MAKE_CHECK_LAYOUT])
AC_MSG_CHECKING([if we want to run check-layout])
case "$cross_compiling$PATH_PERL" in
[Default location of crypto key info])
AC_CONFIG_FILES([Makefile])
-AC_CONFIG_FILES([ElectricFence/Makefile])
AC_CONFIG_FILES([adjtimed/Makefile])
AC_CONFIG_FILES([clockstuff/Makefile])
AC_CONFIG_FILES([include/Makefile])