├── .gitignore ├── .gitmodules ├── Memory-Leak-Tracer ├── Makefile ├── README ├── leakcount.c └── memory_shim.c ├── ccmalloc ├── .cvsignore ├── BUGS ├── FEATURES ├── INSTALL ├── LICENSE ├── Makefile.in ├── NEWS ├── README ├── TODO ├── USAGE ├── VERSION ├── ccmalloc.cfg ├── configure ├── src │ ├── .cvsignore │ ├── callchain.c │ ├── ccmalloc.cc │ ├── ccmalloc.h │ ├── ccmalloc.in │ ├── hash.c │ ├── hash.h │ └── wrapper.c ├── test │ ├── .cvsignore │ ├── Makefile │ ├── README │ ├── ccmalloc_C++_01 │ ├── ccmalloc_C++_02 │ ├── ccmalloc_C_01 │ ├── ccmalloc_C_02 │ ├── ccmalloc_C_03 │ ├── ccmalloc_C_04 │ ├── ccmalloc_C_05 │ ├── ccmalloc_C_06 │ ├── ccmalloc_C_07 │ ├── ccmalloc_C_08 │ ├── ccmalloc_C_09 │ ├── ccmalloc_C_10 │ ├── ccmalloc_C_11 │ ├── ccmalloc_C_12 │ ├── ccmalloc_C_13 │ ├── ccmalloc_C_14 │ ├── ccmalloc_C_15 │ ├── ccmalloc_C_16 │ ├── ccmalloc_C_17 │ ├── ccmalloc_C_18 │ ├── ccmalloc_C_19 │ ├── execute │ ├── lib_test_C_11.c │ ├── lib_test_C_19.c │ ├── test_C++_01.cc │ ├── test_C++_02.cc │ ├── test_C_01.c │ ├── test_C_04.c │ ├── test_C_05.c │ ├── test_C_06.c │ ├── test_C_07.c │ ├── test_C_08.c │ ├── test_C_09.c │ ├── test_C_10.c │ ├── test_C_11.c │ ├── test_C_12.c │ ├── test_C_15.c │ ├── test_C_16.c │ ├── test_C_17.c │ ├── test_C_18.c │ ├── test_C_19.c │ ├── testall │ └── testone └── util │ └── install ├── doc ├── AddressSanitizer算法及源码解析 _ PCB博客.mhtml ├── C_C++内存问题检查利器—Purify (一) - 陈皓专栏 【空谷幽兰,心如皓月】 - 博客频道 - CSDN.NET.mhtml ├── C_C++内存问题检查利器—Purify (三) - 陈皓专栏 【空谷幽兰,心如皓月】 - 博客频道 - CSDN.NET.mhtml ├── C_C++内存问题检查利器—Purify (二) - 陈皓专栏 【空谷幽兰,心如皓月】 - 博客频道 - CSDN.NET.mhtml ├── C_C++内存问题检查利器—Purify (五) - 陈皓专栏 【空谷幽兰,心如皓月】 - 博客频道 - CSDN.NET.mhtml ├── C_C++内存问题检查利器—Purify (四) - 陈皓专栏 【空谷幽兰,心如皓月】 - 博客频道 - CSDN.NET.mhtml ├── Linux C 编程内存泄露检测工具(二):memwatch - neil - ITeye技术网站.mhtml ├── Linux 内存检测工具 memwatch的使用 - Tony的专栏 - 博客频道 - CSDN.NET.mhtml ├── Linux应用程序内存错误自动化测试研究.pdf ├── linux下内存泄漏的动态跟踪分析.pdf ├── memwatch内存泄露检测工具 - lightsong - 博客园.mhtml ├── 一种内存泄漏检测技术的研究和实现.pdf ├── 一种有效的动态内存泄漏检测技术的研究与实现.pdf ├── 使用 DrMemory 发现内存编程错误.mhtml ├── 使用 electric-fence 调试内存越界 - xiaocao9903的专栏 - 博客频道 - CSDN.NET.mhtml ├── 内存泄漏检测工具与评估方法.pdf ├── 内存调试工具Electric Fence - ChenXin的专栏 - 博客频道 - CSDN.NET.mhtml ├── 基于C++的动态内存实时监测器①.pdf ├── 嵌入式linux系统中的内存泄漏的研究.pdf ├── 嵌入式软件动态内存检测工具的研究与实现.pdf └── 用户态内存管理关键技术研究.pdf ├── malloc_hooks ├── The GNU C Library Hooks for Malloc.doc └── malloc_hooks.c └── memwatch ├── FAQ ├── Makefile ├── README ├── USING ├── gpl.txt ├── memwatch.c ├── memwatch.h ├── memwatch.lsm └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | /si 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "memleak-finder"] 2 | path = memleak-finder 3 | url = https://github.com/efficios/memleak-finder 4 | [submodule "malloc_count"] 5 | path = malloc_count 6 | url = https://github.com/bingmann/malloc_count 7 | [submodule "mleak"] 8 | path = mleak 9 | url = https://github.com/hyc/mleak 10 | [submodule "count-malloc"] 11 | path = count-malloc 12 | url = https://github.com/zunda/count-malloc 13 | [submodule "malloc-lab"] 14 | path = malloc-lab 15 | url = https://github.com/htian/malloc-lab 16 | [submodule "memalloc"] 17 | path = memalloc 18 | url = https://github.com/brightroll/memalloc 19 | [submodule "libmallochooks"] 20 | path = libmallochooks 21 | url = https://github.com/stephenrkell/libmallochooks 22 | [submodule "malloc_wrap"] 23 | path = malloc_wrap 24 | url = https://github.com/ice799/malloc_wrap 25 | [submodule "malloc_instrumentation"] 26 | path = malloc_instrumentation 27 | url = https://github.com/jtolds/malloc_instrumentation 28 | [submodule "memory-wrapper"] 29 | path = memory-wrapper 30 | url = https://github.com/meetrp/memory-wrapper 31 | [submodule "libumem"] 32 | path = libumem 33 | url = https://github.com/gburd/libumem 34 | [submodule "drmemory"] 35 | path = drmemory 36 | url = https://github.com/DynamoRIO/drmemory 37 | [submodule "valgrind-trunk-3"] 38 | path = valgrind-trunk-3 39 | url = https://github.com/svn2github/valgrind-trunk-3 40 | [submodule "mpatrol"] 41 | path = mpatrol 42 | url = https://github.com/groleo/mpatrol 43 | [submodule "electric-fence"] 44 | path = electric-fence 45 | url = https://github.com/CheggEng/electric-fence 46 | [submodule "cstuff"] 47 | path = cstuff 48 | url = https://github.com/MoserMichael/cstuff 49 | [submodule "duma"] 50 | path = duma 51 | url = https://github.com/fortitudezhang/duma 52 | [submodule "leakcanary"] 53 | path = leakcanary 54 | url = https://github.com/square/leakcanary 55 | -------------------------------------------------------------------------------- /Memory-Leak-Tracer/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -g 3 | 4 | BINS=memory_shim.so leakcount 5 | 6 | all: $(BINS) 7 | 8 | memory_shim.so: memory_shim.c 9 | $(CC) $(CFLAGS) -fPIC -shared -o memory_shim.so memory_shim.c -ldl 10 | 11 | leakcount: leakcount.c 12 | $(CC) $(CFLAGS) -o leakcount leakcount.c 13 | 14 | clean: 15 | rm $(BINS) 16 | -------------------------------------------------------------------------------- /Memory-Leak-Tracer/README: -------------------------------------------------------------------------------- 1 | DESIGN: 2 | Leakcount - Leakcount is relatively simple. It parses the terminal commands, 3 | and uses them to call execvpe in the child process. The parent 4 | simply waits for the child to finish and then exits. 5 | 6 | Memory_Shim - Utilized by the child process created in leakcount. Serves to 7 | intercept calls to malloc/free. It uses a linked list to store 8 | the ptrs created by malloc and the size of memory created. In 9 | the destructor I first iterate all the way through the list, and 10 | store any unfreed mem in leaks[]. I then use leaks[] to print 11 | afterwards. This is because, when I try to print during my iteration 12 | through the list, fprintf was calling malloc and modifing the list 13 | as I was trying to go through it. 14 | 15 | EXECUTION: 16 | ./leakcount ./test_prog 17 | ./leakcount ./test_prog test_prog_arg 18 | -------------------------------------------------------------------------------- /Memory-Leak-Tracer/leakcount.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* First half of main is dedicated to reading in and parsing 13 | the arguments that will be used with execvpe. */ 14 | int main(int argc, char *argv[]) { 15 | 16 | char *args[4] = {NULL, NULL, NULL, NULL}; 17 | char *env[] = {"LD_PRELOAD=./memory_shim.so", NULL}; 18 | 19 | /* 1a. Make sure that they did not give a directory as an argument. If so, print message and exit. */ 20 | struct stat sb; 21 | stat(argv[1], &sb); 22 | if(S_ISDIR(sb.st_mode)) { 23 | printf("You must enter a program as an argument, not directory. Exiting Leakout Program.\n"); 24 | exit(1); 25 | } 26 | 27 | /* 1b. If there was no program arg entered print an appropriate error message and exit. */ 28 | if(argc == 1) { 29 | printf("Need to enter program to run leak test on. Exiting Leakcount Program.\n"); 30 | exit(1); 31 | } 32 | 33 | /* 1c. Extract the file name. */ 34 | args[0] = basename(argv[1]); 35 | 36 | /* 1d. If an argument was given for the program, save it for execvp. */ 37 | if(argc == 3) { 38 | args[1] = argv[2]; 39 | } 40 | 41 | /* 2a. Fork the process. The child will used the parsed argument info 42 | from the first part of main to call execvpe, which will in turn, 43 | replace the child with the specifed program and set the env to 44 | load my shim library first. */ 45 | if(fork() == 0) { 46 | execvpe(argv[1], args, env); 47 | perror("execvpe"); 48 | } 49 | 50 | /* 2b. Have the parent wait on the child process to finish execution. */ 51 | wait(NULL); 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Memory-Leak-Tracer/memory_shim.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void __attribute__ ((constructor)) init(void); 8 | void __attribute__ ((destructor)) cleanup(void); 9 | void *(*original_malloc)(size_t size) = NULL; 10 | void (*original_free)(void *ptr) = NULL; 11 | 12 | /* Struct node used to implement linked list that will store 13 | the size of mem malloced along with its associated ptr. */ 14 | struct node { 15 | int mem_size; 16 | void *mem_ptr; 17 | struct node *next; 18 | }; 19 | 20 | int list_length = 0; 21 | int leak_count = 0; 22 | struct node *root; 23 | struct node *current; 24 | 25 | /* Prints out information regarding any leaked memory. */ 26 | void cleanup(void) { 27 | int sum = 0, i = 0, leak_count = 0; 28 | int leaks[list_length]; 29 | struct node *temp = root; 30 | 31 | /* 1. Loop through list while updating the total number 32 | * of leaks and the sum of the memory leaks. */ 33 | for(i = 0; i < list_length; i++) { 34 | if(temp->mem_ptr != NULL) { 35 | sum += temp->mem_size; 36 | leaks[leak_count] = temp->mem_size; 37 | leak_count++; 38 | } 39 | temp = temp->next; 40 | } 41 | 42 | /* 2. Print out the leaks. */ 43 | for(i = 0; i < leak_count; i++) { 44 | fprintf(stderr, "LEAK\t %i\n", leaks[i]); 45 | } 46 | 47 | /* 3. Print out the total number of leaks. */ 48 | fprintf(stderr, "TOTAL\t %i\t %i\n", leak_count, sum); 49 | } 50 | 51 | /* sets the wrapper's pointers to point to malloc and free */ 52 | void init(void) { 53 | if(original_malloc == NULL) { 54 | original_malloc = dlsym(RTLD_NEXT, "malloc"); 55 | } 56 | if(original_free == NULL) { 57 | original_free = dlsym(RTLD_NEXT, "free"); 58 | } 59 | } 60 | 61 | /* Retrieves the requested memory, stores the information on said memory 62 | * block as a node in the linked_list, and returns a pointer to the memory.*/ 63 | void *malloc(size_t size) { 64 | 65 | /* 1. Call original malloc to retrieve the requested memory. */ 66 | void *ptr = original_malloc(size); 67 | 68 | /* 2a. If the list is empty, create a new node and set it as the root. 69 | * Store the memory size and the pointer to the memory. */ 70 | if(list_length == 0) { 71 | root = (struct node *) original_malloc(sizeof(struct node)); 72 | root->mem_size = (int) (size); 73 | root->mem_ptr = ptr; 74 | root->next = NULL; 75 | current = root; 76 | } 77 | 78 | /* 2b. Otherwise, create a new node and append it to the list. 79 | * Store the memory size and the pointer to the memory. */ 80 | else { 81 | struct node *new_node = (struct node *) original_malloc(sizeof(struct node)); 82 | new_node->mem_size = (int) (size); 83 | new_node->mem_ptr = ptr; 84 | new_node->next = NULL; 85 | current->next = new_node; 86 | current = new_node; 87 | } 88 | 89 | /* 3. Increment the list_length and return the memory pointer. */ 90 | list_length++; 91 | return ptr; 92 | } 93 | 94 | /* Iterates through the list to find the node containing the ptr 95 | to be freed. Sets the nodes ptr to "NULL" to indicate that 96 | the memory has now been freed. Finally, calls original free. */ 97 | void free(void *ptr) { 98 | int i; 99 | struct node *temp = root; 100 | for(i = 0; i < list_length; i++) { 101 | if(temp->mem_ptr == ptr) { 102 | temp->mem_size = 0; 103 | temp->mem_ptr = NULL; 104 | } 105 | temp = temp->next; 106 | } 107 | original_free(ptr); 108 | } 109 | -------------------------------------------------------------------------------- /ccmalloc/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | obj 3 | lib 4 | bin 5 | -------------------------------------------------------------------------------- /ccmalloc/BUGS: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | BUGS: 3 | ------------------------------------------------------------------------------ 4 | 5 | (1) A leaking file descriptor may result in a segmentation fault after 6 | the report of ccmalloc has been printed. Fixing the leak should make 7 | the fault go away. 8 | 9 | (2) Thread support does not seem to work. 10 | 11 | (3) Linking and compiling your own projects with Sun's CC still does not 12 | work. 13 | 14 | (4) On newer Linux systems or just with newer version of GLIBC I sometimes 15 | get a call from 'free()' after the shutdown code of ccmalloc has been 16 | executed. This is currently reported as a problem but should be ignored. 17 | 18 | (5) If you call malloc and free only implicitly over library functions 19 | of the C-library like strdup then the linker does not link the malloc 20 | called by strdup to the malloc supported by ccmalloc and you do not 21 | get any ccmalloc report at all! To avoid this make sure that your object 22 | file has malloc or free as external symbols (e.g. the leak in the program 23 | `main(){strdup();}' can not be detected) 24 | 25 | (6) Some standard libraries like libc or lg++ may also have memory leaks. 26 | ccmalloc tries to exclude these leaks from the report (see `library-leaks' 27 | in `start-up-file' or `.ccmalloc'). However some libraries maintain an 28 | internal buffer usually referenced through a static variable and the buffer 29 | memory is never released. These buffers are always reported as a leak and 30 | in my opinion actually should be reported as a leak, since using a static 31 | pointer to a buffer which is never released is poor design in my view. 32 | 33 | ------------------------------------------------------------------------------ 34 | (C) 1997-2001 Armin Biere 35 | $Id: BUGS,v 1.5 2003/02/03 08:03:54 biere Exp $ 36 | ------------------------------------------------------------------------------ 37 | -------------------------------------------------------------------------------- /ccmalloc/FEATURES: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | FEATURES: 3 | ------------------------------------------------------------------------------ 4 | 5 | ccmalloc 6 | ======== 7 | 8 | is a memory profiler: 9 | 10 | + simple usage model (new) 11 | 12 | + supports dynamically linked libraries (not dlopen) 13 | 14 | + detects memory leaks 15 | 16 | + detects multiple deallocation of same data 17 | 18 | + detects under writes and over writes 19 | 20 | + detects writes to already deallocated data 21 | 22 | + allocation and deallocation statistics 23 | 24 | + also applicable for optimized and stripped code 25 | 26 | + provides file and linenumber info for whole (c)all (c)hain 27 | (not only for the immediate caller of malloc/free) 28 | 29 | + supports C++ 30 | 31 | + no recompilation needed 32 | (just link with `-lccmalloc -ldl' or with `ccmalloc.o -ldl') 33 | 34 | + efficient representation of (c)all(c)hains 35 | 36 | + customizable pretty printing of call chains 37 | 38 | + selective printing of call chains 39 | 40 | + customizable resource usage 41 | (from 1 to 6(+epsilon) additional pointers per allocation) 42 | 43 | + sorting 44 | 45 | + (compressed) log file 46 | 47 | + log file for parallel execution 48 | 49 | + startup file `.ccmalloc' 50 | 51 | + OS: Linux, Solaris, and (NEW) FreeBSD 52 | 53 | + Compiler: 54 | 55 | o gcc (for C only needed for compiling library) 56 | 57 | - you need to dynamically compile your program 58 | 59 | - sorry no more docs than `ccmalloc.cfg' this file and the test files 60 | in the test directory. 61 | 62 | - uses `nm' and `gdb' to get information about symbols 63 | and `gzip' or `compress' to compress log files (all 64 | should be in your PATH if needed) 65 | 66 | - see BUGS 67 | 68 | ------------------------------------------------------------------------------ 69 | (C) 1997-2003 Armin Biere 70 | $Id: FEATURES,v 1.5 2003/02/03 08:03:54 biere Exp $ 71 | ------------------------------------------------------------------------------ 72 | -------------------------------------------------------------------------------- /ccmalloc/INSTALL: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | INSTALL: 3 | ------------------------------------------------------------------------------ 4 | 5 | Run the 'configure' script with an optional installation prefix as argument 6 | (default is '--prefix=/usr/local'). Then type 'make' followed by 'make 7 | install', after which you can clean up the compilation directory with 'make 8 | distclean'. By default a library 9 | 10 | $(PREFIX)/lib/libccmalloc.o 11 | 12 | is installed and for each available C++ compiler a C++ wrapper is installed: 13 | 14 | $(PREFIX)/lib/ccmalloc-gcc.o 15 | $(PREFIX)/lib/ccmalloc-g++.o 16 | $(PREFIX)/lib/ccmalloc-CC.o # not working yet !!! 17 | ... 18 | 19 | 20 | You should copy 'ccmalloc.cfg' as '.ccmalloc' to your project directory and 21 | read it carefully. 22 | 23 | The distribution also contains some tests that can be run by issuing the 24 | command 'make test'. However the output of the test cases has to be 25 | inspected manually. 26 | 27 | ------------------------------------------------------------------------------ 28 | (C) 1997-2003 Armin Biere 29 | $Id: INSTALL,v 1.6 2003/02/03 08:03:54 biere Exp $ 30 | ------------------------------------------------------------------------------ 31 | -------------------------------------------------------------------------------- /ccmalloc/LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 675 Mass Ave, Cambridge, MA 02139, USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 19yy 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) 19yy name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Library General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /ccmalloc/Makefile.in: -------------------------------------------------------------------------------- 1 | CC=@CC@ 2 | CFLAGS=@CFLAGS@ 3 | COMPILERS=@COMPILERS@ 4 | TARGETS=lib/libccmalloc.a @TARGETS@ bin/ccmalloc 5 | PREFIX=@PREFIX@ 6 | 7 | #--------------------------------------------------------------------------# 8 | 9 | OBJ=obj/callchain.o obj/hash.o obj/wrapper.o 10 | 11 | #--------------------------------------------------------------------------# 12 | 13 | all: $(TARGETS) 14 | 15 | clean: 16 | rm -f obj/*.o lib/*.a bin/* core 17 | 18 | distclean: clean 19 | rm -f src/config.h Makefile 20 | rm -rf obj lib bin 21 | cd test; make clean 22 | 23 | #--------------------------------------------------------------------------# 24 | # The library is not inialized statically. Thus the library may produce 25 | # some bogus messages like `free(...) called after reporting'. However it 26 | # should work even if another compiler is used by the user. 27 | # 28 | lib/libccmalloc.a: $(OBJ) 29 | ar rc $@ $(OBJ) 30 | ranlib $@ 31 | 32 | #--------------------------------------------------------------------------# 33 | 34 | obj/callchain.o: src/config.h src/hash.h src/callchain.c src/ccmalloc.h 35 | $(CC) $(CFLAGS) -c -o $@ src/callchain.c 36 | obj/hash.o: src/hash.h src/hash.c 37 | $(CC) $(CFLAGS) -c -o $@ src/hash.c 38 | obj/wrapper.o: src/config.h src/wrapper.c 39 | $(CC) $(CFLAGS) -c -o $@ src/wrapper.c 40 | bin/ccmalloc: Makefile src/ccmalloc.in 41 | rm -f $@ 42 | sed \ 43 | -e 's,@''PREFIX@,$(PREFIX),g' \ 44 | -e 's,@''COMPILERS@,"$(COMPILERS)",g' \ 45 | -e 's,@''VERSION@,@VERSION@,g' \ 46 | src/ccmalloc.in > $@ 47 | chmod 755 $@ 48 | 49 | #--------------------------------------------------------------------------# 50 | 51 | .PHONY: all clean distclean install uninstall 52 | -------------------------------------------------------------------------------- /ccmalloc/NEWS: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | NEWS for version 0.4.0 3 | ------------------------------------------------------------------------------ 4 | 5 | o work around for gcc 2.95.4 and 3.0.4 for non conforming 6 | __builtin_return_address() (Edward Welbourne). 7 | 8 | o new '--no-wrapper' option to ccmalloc script allows to disable C++ support 9 | by not linking against the C++ wrapper. 10 | 11 | o malloc in wrapper.c only fills the new allocated block with the magic 12 | char 0x42 if the allocation of the block was successful. This allows to 13 | stress test the memory system even with ccmalloc compiled in (like 14 | calling 'malloc((1 << 31))'). 15 | 16 | ------------------------------------------------------------------------------ 17 | NEWS for version 0.3.9 18 | ------------------------------------------------------------------------------ 19 | 20 | o fixed configure to work on FreeBSD 21 | 22 | o patched configure to correctly set 'HAVE_ATEXIT' and also detect the path 23 | of the default dynamically linked libc. This patch fixes some problems 24 | with Redhat 7.1 which uses libc6. 25 | 26 | o '--version' and '--help' for 'ccmalloc' script 27 | 28 | o finally allowed 'free(0)' 29 | 30 | ------------------------------------------------------------------------------ 31 | NEWS for version 0.3.8 32 | ------------------------------------------------------------------------------ 33 | 34 | o checking statically allocated dynamic data for C++ seems to work again 35 | 36 | o better support for C++: increased buffer size, better lexer for parsing 37 | demangling info of C++ template symbols from gdb (Henning Moll). 38 | 39 | ------------------------------------------------------------------------------ 40 | NEWS for version 0.3.7 41 | ------------------------------------------------------------------------------ 42 | 43 | o fixed 'ccmalloc' script to skip files compiled with '-S' and '-c' 44 | 45 | o fixed 'ccmalloc' script to filter out '-o ' as well 46 | 47 | o do not log chain that contain a reference to 'ccmalloc_init' 48 | 49 | ------------------------------------------------------------------------------ 50 | NEWS for version 0.3.4 51 | ------------------------------------------------------------------------------ 52 | 53 | o Started to work on compatibility with Sun's workshop compiler CC. 54 | The idea is to compile 'callchain.c' with 'gcc' and the 'C++' wrapper 55 | 'ccmalloc.cc' with 'CC'. Then it should be possible to link and compile 56 | your own project with 'CC'. Just link as follows 57 | 58 | CC -o binary your-obj1.o your-obj2.o ccmalloc-CC.o -lccmalloc -ldl 59 | 60 | I also added a script 'ccmalloc' that hides this additional arguments to 61 | the compiler and makes the usage of ccmalloc similar to the usage of 62 | 'purify'. Now the standard way of using ccmalloc with C++ becomes 63 | 64 | ccmalloc CC -o binary your-obj1.o your-obj2.o 65 | 66 | or with 'gcc' 67 | 68 | ccmalloc gcc -o binary your-obj1.o your-obj2.o 69 | 70 | However, for some unknown reason 'CC' still produces link errors and 71 | this feature does not work yet. 72 | 73 | o Added patches by Fritz Elfert for better command line argument detection 74 | under Linux (and actually reenabled the whole detection code). 75 | 76 | ------------------------------------------------------------------------------ 77 | NEWS for version 0.3.3 (patches from Henning Moll) 78 | ------------------------------------------------------------------------------ 79 | 80 | o Fixed off by one bug in reporting line number 81 | 82 | o Used 'set width 0' command for GDB to produce easier to parse one line 83 | output. This removes some 'could not read info from gdb' messages, i.e. 84 | with long symbol names as in STL. 85 | 86 | o Skipped 'Current language: ...' message from GDB for better support of 87 | multiple language debugging. 88 | 89 | o Better heuristics for skipping library callchains. 90 | 91 | ------------------------------------------------------------------------------ 92 | NEWS for version 0.3.2 93 | ------------------------------------------------------------------------------ 94 | 95 | o Initialized 'logfile' properly 96 | 97 | o Added '-x' for 'nm' on Solaris 98 | 99 | o Forced 'gdb' not to read initialization file '.gdbinit' 100 | 101 | ------------------------------------------------------------------------------ 102 | NEWS for version 0.3.0 103 | ------------------------------------------------------------------------------ 104 | 105 | o Removed support for SunOS (only Solaris and Linux left) 106 | 107 | o Added the ability for ccmalloc to report only the call chains for wasted 108 | allocations, i.e. allocations which were not completely freed properly 109 | (Ian Ishmael). 110 | 111 | ------------------------------------------------------------------------------ 112 | NEWS for version 0.2.4 113 | ------------------------------------------------------------------------------ 114 | 115 | o Moved `banner()' out of the initialization code. This fixed the `ctime' 116 | bug: Because `banner()' calls `ctime' itself, and `ctime' might call 117 | malloc, the memory potentially allocated by ctime must be public memory, 118 | since it could be deallocated from a following call to `ctime' 119 | originating outside from `ccmalloc'. 120 | 121 | ------------------------------------------------------------------------------ 122 | NEWS for version 0.2.3 123 | ------------------------------------------------------------------------------ 124 | 125 | new features: 126 | ============= 127 | 128 | o Change the cmp_CallChains_by_*_for_Qsort functions to not return 0 so 129 | often by comparing them on address data, too. (This means we have to 130 | read in the data from gdb before sorting the callchains.) This allows 131 | one to compare resulting log files from different runs of the same 132 | program with, e.g. diff or emacs ediff, without getting too many 133 | irrelevant differences (Johannes). 134 | 135 | o Last, but not least, read address data for dynamic libraries from gdb 136 | as well. Only works for those dynamic libraries that the program is 137 | linked with, not the ones that are dlopen'ed explicitly. Controlled 138 | by a flag called `load-dynlibs' (Johannes). 139 | 140 | o new flag `align-8-byte' to align memory to 8 byte on Linux. 141 | 142 | bugfixes: 143 | ========= 144 | 145 | o The configure script now tries to find the standard C library (libc.so) 146 | and checks if it can be opened with dlopen. This should make ccmalloc 147 | run on Redhat 5.0 Linux out of the box. 148 | 149 | o GPL ;-) 150 | 151 | o Fix the src/Makefile so that it also installs the config file and 152 | so that install depends on ccmalloc.o (Johannes). 153 | 154 | ------------------------------------------------------------------------------ 155 | NEWS for version 0.2.2 156 | ------------------------------------------------------------------------------ 157 | 158 | bug fixes: 159 | ========== 160 | 161 | o `wrapper.c' did not handle realloc correctly while in state INITIALIZING. 162 | 163 | This lead to `*** realloc(0x8065f3d) called with non valid argument' 164 | before the program was even started. This bug occured when using KDE 165 | together with Qt. Now even the static allocator in wrapper.c saves the 166 | size of the allocated data. 167 | 168 | ------------------------------------------------------------------------------ 169 | NEWS for version 0.2.1 170 | ------------------------------------------------------------------------------ 171 | 172 | bug fixes: 173 | ========== 174 | 175 | o returned data is now 8 byte aligned on SunOS and Solaris. This avoids 176 | a Bus Error when allocating heap memory for doubles. 177 | (a lot of people reported that bug) 178 | 179 | o shrinking allocated data with realloc works now 180 | (a lot of people reported that bug) 181 | 182 | o fixed dereferencing bug in cmpAddr (Johannes Keukelaar) 183 | 184 | o calls fflush before killing itself 185 | 186 | new features: 187 | ============= 188 | 189 | o `only-log-chain' and `dont-log-chain' (Johannes Keukelaar) 190 | 191 | o `logpid' (Didier Remy) 192 | 193 | ------------------------------------------------------------------------------ 194 | (C) 1997-2003 Armin Biere 195 | $Id: NEWS,v 1.19 2003/02/03 08:03:54 biere Exp $ 196 | ------------------------------------------------------------------------------ 197 | -------------------------------------------------------------------------------- /ccmalloc/README: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | README: 3 | ------------------------------------------------------------------------------ 4 | 5 | ccmalloc-0.4.0 (C) 1997-2003 Armin Biere 6 | 7 | Thanks to everyone sending me bug reports, patches, or just a small note. 8 | This increases the probability that ccmalloc will be developed further ;-) 9 | 10 | First have a look at NEWS, FEATURES, ccmalloc.cfg, INSTALL, and finally 11 | USAGE. 12 | 13 | NOTE that ccmalloc.cfg contains the most important information. 14 | 15 | If you have any questions, comments, or additions to this software then 16 | please feel free to contact me. 17 | 18 | Armin Biere. 19 | 20 | (biere@inf.ethz.ch, http://www.inf.ethz.ch/personal/biere) 21 | 22 | ------------------------------------------------------------------------------ 23 | (C) 1997-2003 Armin Biere 24 | $Id: README,v 1.8 2003/02/03 08:03:54 biere Exp $ 25 | ------------------------------------------------------------------------------ 26 | -------------------------------------------------------------------------------- /ccmalloc/TODO: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | TODO: 3 | ------------------------------------------------------------------------------ 4 | 5 | (1) port to alpha (64bit systems in general) 6 | (2) write a script that evaluates the test runs 7 | (3) new allocator with protected (mprotect) internal data 8 | 9 | ------------------------------------------------------------------------------ 10 | (C) 1997-2003 Armin Biere 11 | $Id: TODO,v 1.4 2003/02/03 08:03:54 biere Exp $ 12 | ------------------------------------------------------------------------------ 13 | -------------------------------------------------------------------------------- /ccmalloc/USAGE: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | USAGE: 3 | ------------------------------------------------------------------------------ 4 | 5 | The library comes with a script 'ccmalloc' that you just need to add as 6 | first argument to the link command in your project. A typical project build 7 | might look like this: 8 | 9 | gcc -c -o mod1.o mod1.c # compilation 10 | gcc -c -o mod2.o mod2.c # compilation 11 | gcc -o binary mod1.o mod2.o -lm # linking 12 | 13 | Now you just have to replace the linking command with 14 | 15 | ccmalloc gcc -o binary mod1.o mod2.o -lm # linking 16 | 17 | It does no harm to also use the 'ccmalloc' prefix for compilation only, 18 | since the script tries to analyse the arguments and just calls the compiler 19 | if linking is supposed to be omitted. 20 | 21 | Depending on the installation prefix, e.g. see the '--prefix' option to 22 | 'configure', this will actually execute the following command: 23 | 24 | gcc -o binary mod1.o mod2.o -lm /usr/local/lib/ccmalloc-gcc.o \ 25 | -L/usr/local/lib -lccmalloc -ldl 26 | 27 | You can, of course, specify this last command manually without using the 28 | 'ccmalloc' script. This may be necessary for some configurations. Note, 29 | that the 'ccmalloc-.o' file is just a C++ wrapper for ccmalloc and may 30 | be omitted (in version 3.8 this may not be true anymore). 31 | 32 | ------------------------------------------------------------------------------ 33 | (C) 1997-2003 Armin Biere 34 | $Id: USAGE,v 1.5 2003/02/03 08:03:54 biere Exp $ 35 | ------------------------------------------------------------------------------ 36 | -------------------------------------------------------------------------------- /ccmalloc/VERSION: -------------------------------------------------------------------------------- 1 | 0.4.0 2 | -------------------------------------------------------------------------------- /ccmalloc/ccmalloc.cfg: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | %%%% generic configuration file for %%%% 3 | %%%% the ccmalloc memory profiler %%%% 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | 6 | %-----------------------------------------------------------------% 7 | % COPY THIS FILE TO '.ccmalloc' in your project or home directory % 8 | %-----------------------------------------------------------------% 9 | 10 | ############################################################################## 11 | ## (C) 1997-2003 Armin Biere, 1998 Johannes Keukelaar 12 | ## $Id: ccmalloc.cfg,v 1.6 2003/02/03 08:03:54 biere Exp $ 13 | ############################################################################## 14 | 15 | %%% '%' and '#' are comments !!!!!!! 16 | 17 | % This file must be called '.ccmalloc' and is searched for in the 18 | % current directory and in the home directory of the user. If it 19 | % does not exist then the default values mentioned below are used. 20 | 21 | % It is also the only available user manual yet ;-) So here is a reading 22 | % hint. First have a look at the short one line descriptions of each option 23 | % ... 24 | 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | % with 'file' the executable is specified [a.out] 27 | % ---------------------------------------------------------------------- 28 | % This should not be necessary for Linux and Solaris because the proc 29 | % file system can be used to find argv[0]. 30 | % 31 | % (the rest of this comment only applies to other OS) 32 | % 33 | % For other OS you should use this option unless the executable is 34 | % in the current directory or its name is 'a.out'. 35 | % 36 | % If you do not specify this then ccmalloc tries to find an executable 37 | % in the current directory that matches the running program starting 38 | % with 'a.out'. For this process it must call 'nm' on each executable 39 | % file in the directory which may be time consuming. With this option 40 | % you can speed up this process. 41 | % 42 | % You can also specify absolute or relative path names. This is 43 | % necessary if you do not start your program from the current directory. 44 | % But you can also simply link or name your program to 'a.out'. 45 | 46 | %file FILE 47 | 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | % 'log' specify the logfile [stderr] 50 | % ---------------------------------------------------------------------- 51 | % The default is to use stderr. The argument to 'log' is the name of 52 | % the file you want to write to. It can also be 'stdout' or '-' which 53 | % sets stdout as logfile. If the logfile is stdout or stderr and is 54 | % connected to a terminal then the output is slightly different. 55 | % 56 | % For big programs the logfile can be really big. To reduce the size 57 | % you can use a small chain length (see 'chain-length' below). The other 58 | % possibility is to use compressed logfiles. This can be done by 59 | % specifying a logfile name with a '.gz' (or a '.Z') suffix. This means 60 | % that gnuzip (resp. compress) is used to compress the output. 61 | 62 | %log FILE 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | % 'logpid' specify the logfile 66 | % ---------------------------------------------------------------------- 67 | % Can be used alternatively to the 'log' command if you want to use 68 | % ccmalloc for debugging parallel applications where several copies of 69 | % the program you are debugging must be run simoultaneously. In this 70 | % case you can not use 'log' because you do not want to write to the same 71 | % log file. Using 'logpid' uses a file name ending with the of 72 | % the process which means the name is unique even if several copies of 73 | % your program are run simoultaneously. 74 | % 75 | % If you use the compressing suffixes then the is inserted before 76 | % the suffix (e.g. 'logpid ccmalloc.log.gz' uses 'ccmalloc.log..gz' 77 | % as the name for the log file). 78 | 79 | %logpid FILE 80 | 81 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 82 | % 'dont-log-chain' skip info about certain chains [] 83 | % ---------------------------------------------------------------------- 84 | % This command may be repeated any number of times. The argument to this 85 | % command is a comma-separated list of function-or-file-and-line 86 | % specifications. Garbage allocated from a callchain that contains this 87 | % subchain anywhere will _not_ be logged. 88 | % 89 | % The ';'-separated list should not contain any spaces. E.g. not: 90 | % 91 | % main ; foo ; bar 92 | % 93 | % but: 94 | % 95 | % main;foo;bar 96 | % 97 | % A function-or-file-and-line specification is a string followed by an 98 | % optional colon and number, for example: main or main:14 or main.c or 99 | % main.c:15. Note that the string is compared with both the function and the 100 | % file name, if available. If main.c happens to be a function name, that 101 | % will cause a match (for that string at least). Not specifying a line 102 | % number will match any line number. If line number information is not 103 | % available, anything will match! Not specifying a name (e.g. ;;;) will 104 | % match an unknown function name. Not giving any parameters at all, will 105 | % match a chain containing at least one unknown function. 106 | % 107 | % Note that if you say 'dont-log-chain wrapper.c' nothing will be logged. 108 | 109 | %dont-log-chain 110 | 111 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 112 | % 'only-log-chain' skip info about other chains [] 113 | % ---------------------------------------------------------------------- 114 | % The obvious counterpart to dont-log-chain. In this case, only matching 115 | % chains will be reported. Non-matching chains will not be reported. 116 | % Can be repeated any number of times; if the chain matches any of the 117 | % instances, it will be reported. 118 | 119 | %only-log-chain 120 | 121 | ######################################################################## 122 | # # 123 | # This is the 'flag' section # 124 | # # 125 | # 'set FLAG' is the same as 'set FLAG 1' # 126 | # # 127 | # The default values are those set below. If 'silent' is disabled # 128 | # then you will find the banner in the log file (or it is listed on # 129 | # stdout or stderr). The banner describes the current settings of all # 130 | # these flags. # 131 | # # 132 | ######################################################################## 133 | 134 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 135 | % with 'only-count' ccmalloc only counts garbage - no call chains [0] 136 | % ---------------------------------------------------------------------- 137 | % If only-count is set to one then only one additional pointer for 138 | % each allocated data is used and no call chain is generated. This is 139 | % the fasted and most space efficient mode ccmalloc can operate 140 | % in. In this mode you get at least the size of garbage produced. 141 | % 142 | % Note that 'check-free-space' does not work at all with 'only-count' 143 | % set and over writes ('check-overwrites') are only checked when 144 | % calling free. 145 | 146 | %set only-count 0 147 | 148 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 149 | % 'load-dynlibs' load dynamic linked libraries into gdb [0] 150 | % ---------------------------------------------------------------------- 151 | % If your program is linked with dynamic libraries, function and file 152 | % name information is not available for addresses in those libraries, 153 | % unless you set 'load-dynlibs' to 1. 154 | 155 | %set load-dynlibs 0 156 | 157 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 158 | % 'keep-deallocated-data' does not recycle deallocated data [0] 159 | % ---------------------------------------------------------------------- 160 | % If you enable keep-deallocated-data then all data deallocated with 161 | % 'free' (or 'delete' in C++) is not given back to the free store 162 | % but stays associated with the call chain of its allocation. This is 163 | % very useful if your program does multiple deallocation of the 164 | % same data. 165 | 166 | %set keep-deallocated-data 0 167 | 168 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 169 | % 'check-overwrites' detect overwrites [0] 170 | % ---------------------------------------------------------------------- 171 | % If you want to detect 'off by n bytes' errors you should set 172 | % 'checking-overwrites' to n/4 (on 32-Bit machines). 173 | % 174 | % ccmalloc inserts a boundary above allocated data. This boundary 175 | % consists of 'check-overwrites' words. If your program writes to 176 | % this area then ccmalloc can detect this (see also check-start 177 | % and check-interval). 'ccmalloc' also does checking for overwrites 178 | % at non word boundaries (e.g. strcpy(malloc(strlen("hello")),"hello");) 179 | 180 | %set check-overwrites 0 181 | 182 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 183 | % 'check-underwrites' detect underwrites [0] 184 | % ---------------------------------------------------------------------- 185 | % same with writes below allocated data. You do not have to set this 186 | % option if you only want detect 'off (below) by one' errors because 187 | % ccmalloc keeps a magic value just before the user data. 188 | 189 | %set check-underwrites 0 190 | 191 | 192 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 193 | % 'check-free-space' can be used to find dangling pointers. [0] 194 | % ---------------------------------------------------------------------- 195 | % A very serious type of bug is to write on data that has already been 196 | % freed. If this happens the free space management of malloc is in 197 | % trouble and you will perhaps encounter non deterministic behaviour of 198 | % your program. To test this first enable 'keep-deallocated-data' and 199 | % restart your program. If the problem goes away and ccmalloc does not 200 | % report anything then you should *also* enable 'check-free-space'. Now 201 | % ccmalloc checks already deallocated data for corruption. 202 | % 203 | % Note that to perform this check 'keep-deallocated-data' also must 204 | % be enabled and 'only-count' disabled. 205 | 206 | %set check-free-space 0 207 | 208 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 209 | % 'check-interval' can be used to speed up checks [0] 210 | % ---------------------------------------------------------------------- 211 | % If check-overwrite, check-underwrites or check-free-space is set then 212 | % the default is to do 'write checks' when data is deallocated and 213 | % to do 'free space checks' when reporting together with 214 | % 'write checks' for garbage. When you want these checks to be 215 | % performed more often then you should set 'check-interval' to a 216 | % positive number. This number is the interval between the number of 217 | % calls to free or malloc without performing the checks. 218 | 219 | %set check-interval 0 220 | 221 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 222 | % 'check-start' can be used to speed up checks [0] 223 | % ---------------------------------------------------------------------- 224 | % The flag 'check-start' delays the start of checks until the given 225 | % number of calls to free and malloc have occured. Together with 226 | % 'check-interval' you can use a binary search to find an aproximation 227 | % when a corruption occured! If you simply set check-interval to 1 and 228 | % check-start to 0 then this will slow done your program too much. 229 | 230 | %set check-start 0 231 | 232 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 233 | % 'silent' disables banner [0] 234 | % ---------------------------------------------------------------------- 235 | % If you don't want to see the banner of ccmalloc then set 236 | % 'silent' to 1 (f.e. when logging to stderr) 237 | 238 | %set silent 239 | 240 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 241 | % 'file-info' en/disables file and line number information [1] 242 | % ---------------------------------------------------------------------- 243 | % If your program was compiled with debugging information (-g) then 244 | % ccmalloc can generate line number and file info for call chains opening 245 | % a pipe to gdb. For very big programs this method is slow. In this case 246 | % you can set 'file-info' to zero and you will only get the function 247 | % names. For SunOS 4.3.1 'nm' does not 'demangle' C++ identifiers 248 | % very well. So gdb is called instead but only if 'file-info' is 249 | % not set to 0. 250 | 251 | %set file-info 1 252 | 253 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 254 | % 'continue' if ccmalloc aborts when something weired happened [0] 255 | % ---------------------------------------------------------------------- 256 | % If the free function of ccmalloc is called with an argument that does 257 | % not make sense to ccmalloc or that has already been freed then you 258 | % probably want the program to stop at this point. This is also 259 | % the default behaviour. But you can force ccmalloc also to ignore 260 | % this if you set 'continue' to 1. This flag also controls the behaviour 261 | % of ccmalloc when free space is found to be corrupted or a write 262 | % boundary has been overwritten. 263 | 264 | %set continue 0 265 | 266 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 267 | % 'chain-length' is the length of the maximal call chain [0 = infinite] 268 | % ---------------------------------------------------------------------- 269 | % You can restrict the length of call chains by setting 'chain-length' 270 | % to a number greater than zero. If 'chain-length' is zero (the default) 271 | % then chains are as long as possible (on a non x86 system only call 272 | % chains with a finite maximal length can be generated). For big 273 | % programs especially if keep-deallocated-data is enabled this can 274 | % reduce the size of the log file from over 100MB to several MB! 275 | 276 | %set chain-length 0 277 | 278 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 279 | % 'print-addresses' of data [0] 280 | % ---------------------------------------------------------------------- 281 | % If you want to see the addresses of the allocated data (and 282 | % deallocated data if keep-deallocated-data is set to 1) set 283 | % 'print-addresses' to 1. 284 | 285 | %set print-addresses 0 286 | 287 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 288 | % 'print-on-one-line' shortens log file [0] 289 | % ---------------------------------------------------------------------- 290 | % The default is to print function names and file/line number info 291 | % on separate lines. With 'print-on-one-line' set 1 all are printed 292 | % on one line. 293 | 294 | %set print-on-one-line 0 295 | 296 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 297 | % 'additional-line' enlarges readability [1] 298 | % ---------------------------------------------------------------------- 299 | % When printing call chains an empty line is printed between to 300 | % call points. Set 'additional-line' to 0 to disable this feature. 301 | 302 | %set additional-line 1 303 | 304 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 305 | % 'statistics' enables more accurate profiling [0] 306 | % ---------------------------------------------------------------------- 307 | % Calculate number of allocations and deallocations and bytes also on 308 | % a per call chain basis. This uses 4 additional pointers for each 309 | % call chain. 310 | 311 | %set statistics 0 312 | 313 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 314 | % set order for sorting of call chains [1] [1] 315 | % ---------------------------------------------------------------------- 316 | % When printing the report to the log file the call chains are sorted by 317 | % default with respect to the largest accumulated garbage produced by 318 | % that call chain. This can be changed with setting 'sort-by-wasted' 319 | % to 0. In this case they are sorted by the number of allocated bytes. 320 | % If you want the number of allocations (only possible if 'statistics' 321 | % is enabled) as sorting criteria instead then set 'sort-by-size' to 0. 322 | 323 | %set sort-by-wasted 1 324 | %set sort-by-size 1 325 | 326 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 327 | % report library chains [0] 328 | % ---------------------------------------------------------------------- 329 | % Some external libraries (like libg++) have memory leaks. On some 330 | % systems even a call to printf produces a leak. ccmalloc tries to 331 | % detect this (only heuristically!) and with this flag you can control 332 | % if leaks produced by such library calls are reported. 333 | % 334 | % Since version 0.2.1 some similar effect can be achieved by using 335 | % 'dont-log-chain' with no argument. 336 | 337 | %set library-chains 0 338 | 339 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 340 | % print debugging information [X] (compile time dependend) 341 | % ---------------------------------------------------------------------- 342 | 343 | %set debug X 344 | 345 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 346 | % align memory on 8 byte boundary [0] (no effect on SunOS or Solaris) 347 | % ---------------------------------------------------------------------- 348 | 349 | %set align-8-byte 0 350 | 351 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 352 | % only report allocations which ended up being wasted (i.e don't report 353 | % allocations which were completely freed properly. ) [1] 354 | % ---------------------------------------------------------------------- 355 | 356 | %set only-wasting-alloc 1 357 | -------------------------------------------------------------------------------- /ccmalloc/configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #--------------------------------------------------------------------------# 4 | 5 | usage() { 6 | echo "usage: configure [--prefix=][--debug]" 7 | echo "" 8 | echo " --prefix= specify installation prefix" 9 | echo " --debug enable internal debugging of library" 10 | echo 11 | cat <&2 50 | exit 1 51 | ;; 52 | esac 53 | shift 54 | done 55 | 56 | #--------------------------------------------------------------------------# 57 | # get version 58 | # 59 | printf "$fmt" "version" 60 | version=`cat VERSION` 61 | echo " $version" 62 | 63 | #--------------------------------------------------------------------------# 64 | # check if OS is supported 65 | # 66 | 67 | printf "$fmt" "system" 68 | 69 | case `uname` in 70 | SunOS ) 71 | case `uname -r` in 72 | 5.* ) 73 | os=solaris 74 | ;; 75 | esac 76 | ;; 77 | Linux ) 78 | os=linux 79 | ;; 80 | FreeBSD ) 81 | os=freebsd 82 | ;; 83 | esac 84 | 85 | if [ $os = unsupported ] 86 | then 87 | echo 88 | echo "*** configure: unsupported operating system" 1>&2 89 | exit 1 90 | fi 91 | 92 | echo " $os" 93 | 94 | #--------------------------------------------------------------------------# 95 | # search for C compilers 96 | 97 | printf "$fmt" "C compiler" 98 | 99 | if [ "$CC" ]; then searchlist="$CC"; else searchlist="gcc cc"; fi 100 | CC="" 101 | 102 | compilers="" 103 | for cc in $searchlist 104 | do 105 | for dir in `echo $PATH | sed -e 's,:, ,g'` 106 | do 107 | if [ -f $dir/$cc ] 108 | then 109 | [ "$CC" ] || CC="$cc" 110 | [ "$compilers" ] && compilers="$compilers " 111 | compilers="${compilers}$cc" 112 | break 113 | fi 114 | done 115 | done 116 | 117 | if [ "$CC" ] 118 | then 119 | case $CC in 120 | gcc) CFLAGS="-g -Wall";; 121 | cc) CFLAGS="-g -W";; 122 | *) CFLAGS="-g";; 123 | esac 124 | echo " $CC $CFLAGS" 125 | else 126 | echo 127 | echo "*** configure: no C compiler found" 1>&2 128 | exit 1 129 | fi 130 | 131 | #--------------------------------------------------------------------------# 132 | # search for C++ compilers 133 | 134 | printf "$fmt" "C++ compilers" 135 | 136 | if [ "$CXX" ]; then searchlist="$CXX"; else searchlist="g++ gcc CC"; fi 137 | 138 | COMPILERS="" 139 | for cc in $searchlist 140 | do 141 | for dir in `echo $PATH | sed -e 's,:, ,g'` 142 | do 143 | if [ -f $dir/$cc ] 144 | then 145 | [ "$COMPILERS" ] && COMPILERS="$COMPILERS " 146 | COMPILERS="${COMPILERS}$cc" 147 | break 148 | fi 149 | done 150 | done 151 | 152 | if [ "$COMPILERS" ] 153 | then 154 | echo " $COMPILERS" 155 | else 156 | echo 157 | echo "*** configure: no C++ compiler found" 1>&2 158 | exit 1 159 | fi 160 | 161 | for cc in $COMPILERS 162 | do 163 | [ $cc = CC ] && \ 164 | echo "*** warning: CC as C++ compiler does not work properly yet" 1>&2 165 | done 166 | 167 | #--------------------------------------------------------------------------# 168 | # check if installation directory exists 169 | # 170 | printf "$fmt" "prefix" 171 | 172 | case "$prefix" in 173 | /*) 174 | ;; 175 | *) 176 | echo 177 | echo "*** configure: prefix '$prefix' is no absolute path name" 1>&2 178 | exit 1 179 | ;; 180 | esac 181 | 182 | echo " $prefix" 183 | 184 | #--------------------------------------------------------------------------# 185 | # searching for real libc 186 | 187 | printf "$fmt" libc 188 | 189 | tmp=/tmp/configure-ccmalloc-findlibc-$$ 190 | dir=`pwd` 191 | mkdir /tmp/configure-ccmalloc-findlibc-$$ || exit 1 192 | cd $tmp 193 | rm -f main.c 194 | cat <main.c 195 | #include 196 | #include 197 | #include 198 | int main(int arc, char **argv) 199 | { 200 | int bl; 201 | const char * str; 202 | void * handle = dlopen(argv[1], RTLD_NOW); 203 | if((str = dlerror()) != NULL) fprintf(stderr, "*** %s\n", str); 204 | exit(str != NULL); 205 | } 206 | EOF 207 | 208 | case $os in 209 | freebsd ) 210 | LIB="" 211 | ;; 212 | * ) 213 | LIB="-ldl" 214 | ;; 215 | esac 216 | 217 | libc=notfound 218 | if $CC main.c $LIB 1>/dev/null 2>/dev/null 219 | then 220 | libc="`ldd ./a.out | awk '/libc/{print $3}'`" 221 | if ./a.out "$libc" 1>/dev/null 2>/dev/null 222 | then 223 | libc="$libc" 224 | else 225 | libc=notfound 226 | fi 227 | fi 228 | cd $dir 229 | rm -rf $tmp 230 | 231 | if [ "$libc" = notfound ] 232 | then 233 | echo 234 | echo "*** configure: could not find 'libc.so'" 1>&2 235 | exit 1 236 | fi 237 | 238 | echo " $libc" 239 | 240 | #--------------------------------------------------------------------------# 241 | 242 | printf "$fmt" atexit 243 | 244 | tmp=/tmp/configure-ccmalloc-atexit-$$ 245 | dir=`pwd` 246 | mkdir /tmp/configure-ccmalloc-atexit-$$ || exit 1 247 | cd $tmp 248 | rm -f main.c 249 | 250 | cat <main.c 251 | #include 252 | #include 253 | void foo() { printf ("yes\n"); } 254 | int main(void) 255 | { 256 | atexit(foo); 257 | exit(0); 258 | } 259 | EOF 260 | 261 | atexit=no 262 | if $CC main.c 1>/dev/null 2>/dev/null 263 | then 264 | [ "`./a.out`" = yes ] && atexit=yes 265 | fi 266 | cd $dir 267 | rm -rf $tmp 268 | 269 | echo " $atexit" 270 | 271 | #--------------------------------------------------------------------------# 272 | 273 | printf "$fmt" "setting up directories" 274 | for d in obj lib bin 275 | do 276 | if [ ! -d $d ]; then mkdir $d; fi 277 | done 278 | echo " done" 279 | 280 | #--------------------------------------------------------------------------# 281 | # 282 | printf "$fmt" "generating src/config.h" 283 | 284 | rm -f src/config.h 285 | ( 286 | echo "#ifndef _config_h_INCLUDED" 287 | [ $debug = no ] && echo "#define NDEBUG" 288 | [ $os = solaris ] && echo "#define OS_IS_SOLARIS" 289 | [ $os = linux ] && echo "#define OS_IS_LINUX" 290 | [ $atexit = yes ] && echo "#define HAVE_ATEXIT" 291 | cat<<-EOF 292 | #define VERSION "$version" 293 | #define NAME_OF_LIBC "$libc" 294 | #if defined(OS_IS_LINUX) || defined(OS_IS_SOLARIS) 295 | #define CAN_GET_ARGV0 296 | #endif 297 | #endif /* _config_h_INCLUDED */ 298 | EOF 299 | ) > src/config.h 300 | echo " done" 301 | 302 | #--------------------------------------------------------------------------# 303 | # 304 | dst=Makefile 305 | printf "$fmt" "generating $dst" 306 | 307 | TARGETS="" 308 | for cc in $COMPILERS 309 | do 310 | [ "$TARGETS" ] && TARGETS="$TARGETS " 311 | TARGETS="$TARGETS obj/ccmalloc-${cc}.o" 312 | done 313 | 314 | rm -f $dst 315 | sed \ 316 | -e "s,@PREFIX@,$prefix,g" \ 317 | -e "s,@CC@,$CC,g" \ 318 | -e "s,@CFLAGS@,$CFLAGS,g" \ 319 | -e "s,@COMPILERS@,$COMPILERS,g" \ 320 | -e "s,@VERSION@,$version,g" \ 321 | -e "s,@TARGETS@,$TARGETS,g" \ 322 | Makefile.in > $dst 323 | 324 | echo >> $dst 325 | cat >>Makefile<> $dst 343 | echo " $cc -DCTORDTOR $CXXFLAGS -c -o \$@ src/ccmalloc.cc" >> $dst 344 | echo >> $dst 345 | done 346 | 347 | cat >>Makefile<> $dst 359 | done 360 | 361 | cat >>Makefile<> $dst 374 | done 375 | 376 | echo " done" 377 | 378 | -------------------------------------------------------------------------------- /ccmalloc/src/.cvsignore: -------------------------------------------------------------------------------- 1 | config.h 2 | -------------------------------------------------------------------------------- /ccmalloc/src/ccmalloc.cc: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * (C) 1997-2003 Armin Biere 3 | * 4 | * $Id: ccmalloc.cc,v 1.11 2003/02/03 08:03:56 biere Exp $ 5 | *---------------------------------------------------------------------------- 6 | */ 7 | 8 | extern "C" 9 | { 10 | #include "ccmalloc.h" 11 | }; 12 | 13 | class CCMalloc_InitAndReport 14 | { 15 | public: 16 | CCMalloc_InitAndReport () 17 | { 18 | ccmalloc_static_initialization (); 19 | } 20 | 21 | ~CCMalloc_InitAndReport () 22 | { 23 | ccmalloc_report (); 24 | } 25 | }; 26 | 27 | static CCMalloc_InitAndReport ccmalloc_initAndReport; 28 | -------------------------------------------------------------------------------- /ccmalloc/src/ccmalloc.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * (C) 1997-2003 Armin Biere 3 | * 4 | * $Id: ccmalloc.h,v 1.8 2003/02/03 08:03:56 biere Exp $ 5 | *---------------------------------------------------------------------------- 6 | */ 7 | 8 | #ifndef _ccmalloc_h_INCLUDED 9 | #define _ccmalloc_h_INCLUDED 10 | 11 | #include 12 | 13 | void *ccmalloc_malloc (size_t); 14 | void ccmalloc_free (void *); 15 | void ccmalloc_report (void); 16 | void ccmalloc_static_initialization (void); 17 | void ccmalloc_atexit (void (*)(void)); 18 | void ccmalloc_abort (const char *fmt, ...); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /ccmalloc/src/ccmalloc.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # (C) 2001 Armin Biere ETH Zuerich 3 | # 4 | # This script may be used to link an executable with ccmalloc. It 5 | # automatically tries to filter out requests which do not generate an 6 | # executable binary. With this script the usage model of ccmalloc becomes 7 | # similar to purify. Just use 'ccmalloc gcc' wherever you regularly would 8 | # use 'gcc' alone. 9 | # 10 | COMPILERS=@COMPILERS@ 11 | PREFIX=@PREFIX@ 12 | 13 | usage () { 14 | echo \ 15 | "ccmalloc [ ..] [ ..] .." 16 | echo 17 | echo "where is" 18 | echo 19 | echo " --version print version and exit" 20 | echo " --help | -h print this command line option summary and exit\n" 21 | echo " --no-wrapper do not link in the C++ wrapper\n" 22 | echo 23 | echo "and is one of the following" 24 | echo 25 | echo " $COMPILERS" 26 | echo 27 | cat < is an object or source file. If contains '-S' 29 | or '-c' then linking is of course disabled and ccmalloc behaves just as if 30 | the compiler was called directly. 31 | EOF 32 | } 33 | 34 | die() { 35 | echo "*** ccmalloc: $1" 1>&2 36 | exit 1 37 | } 38 | 39 | [ $# -lt 1 ] && \ 40 | die "command line argument is missing (try '-h')" 41 | 42 | nowrapper=no 43 | 44 | while [ "`echo $1 | cut -b 1`" = "-" ] 45 | do 46 | case $1 in 47 | --help | -h) 48 | usage 49 | exit 0 50 | ;; 51 | --version) 52 | echo "@VERSION@" 53 | exit 0 54 | ;; 55 | --no-wrapper) 56 | nowrapper=yes 57 | ;; 58 | -*) 59 | die "invalid option '$1'" 60 | ;; 61 | esac 62 | shift 63 | done 64 | 65 | args="$*" 66 | base="`basename $1`" 67 | shift 68 | 69 | foundfile=no 70 | link=yes 71 | last="" 72 | while [ $# -gt 0 ] 73 | do 74 | case $1 in 75 | *.o) 76 | [ "$last" = "-o" ] || foundfile=yes 77 | ;; 78 | *.s | *.c | *.cc | *.cpp | *.cxx ) 79 | foundfile=yes 80 | ;; 81 | -S | -c) 82 | link=no 83 | ;; 84 | *) 85 | ;; 86 | esac 87 | last="$1" 88 | shift 89 | done 90 | 91 | if [ "$link" = no ] 92 | then 93 | exec $args 94 | fi 95 | 96 | if [ $foundfile = no ] 97 | then 98 | echo "*** ccmalloc: missing source or object file" 1>&2 99 | exit 1 100 | fi 101 | 102 | foundcompiler=no 103 | for CC in $COMPILERS 104 | do 105 | if [ $CC = "$base" ] 106 | then 107 | foundcompiler=yes 108 | break; 109 | fi 110 | done 111 | 112 | wrapper="" 113 | if [ $nowrapper = yes ] 114 | then 115 | wrappermessage="none (disabled by command line option)" 116 | elif [ $foundcompiler = yes ] 117 | then 118 | wrapper="$PREFIX/lib/ccmalloc-$CC.o" 119 | wrappermessage="$wrapper" 120 | else 121 | wrappermessage="no C++ wrapper for '$base' installed" 122 | fi 123 | 124 | echo "[ccmalloc] version .. @VERSION@" 125 | echo "[ccmalloc] prefix .. $PREFIX" 126 | echo "[ccmalloc] compilers .. $COMPILERS " 127 | echo "[ccmalloc] wrapper .. $wrappermessage" 128 | 129 | cmd="$args" 130 | test "$wrapper" = "" || cmd="$cmd $wrapper" 131 | cmd="$cmd -L$PREFIX/lib -lccmalloc -ldl" 132 | 133 | echo $cmd 134 | exec $cmd 135 | -------------------------------------------------------------------------------- /ccmalloc/src/hash.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * (C) 1997-1998 Armin Biere 3 | * 4 | * $Id: hash.c,v 1.2 2001/12/04 09:46:41 biere Exp $ 5 | *---------------------------------------------------------------------------- 6 | */ 7 | 8 | #include "hash.h" 9 | 10 | /* ------------------------------------------------------------------------ */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | /* ------------------------------------------------------------------------ */ 17 | 18 | typedef struct HashTableBucket 19 | { 20 | void *data; /* do not move this !!!! */ 21 | struct HashTableBucket *next; 22 | } 23 | HashTableBucket; 24 | 25 | /* ------------------------------------------------------------------------ */ 26 | 27 | typedef struct HashTable_ 28 | { 29 | int count; 30 | int size; 31 | int threshold; 32 | int num_resizes; 33 | int primes_idx; 34 | 35 | HashTableBucket **table; 36 | 37 | int (*cmp_keys) (void *key1, void *key2); 38 | int (*hash_key) (void *key); 39 | void *(*get_key_from_data) (void *data); 40 | void (*free_data) (void *); 41 | void (*error) (char *); 42 | } 43 | HashTable_; 44 | 45 | /* ------------------------------------------------------------------------ */ 46 | 47 | /* let s be the current size and s' the desired next size 48 | * we request a larger size iff n = 80% s where n is 49 | * the number of valid nodes. Now we want to have 50 | * n = 50% s' for not wasting too much space. 51 | * This gives the formula 52 | * 53 | * s' = (8/5) s 54 | * 55 | * the primes can be generated with the following awk program: 56 | * 57 | * BEGIN { 58 | * P = 3; M = 2147483647 # 2**31 59 | * while(P primes[primes_idx]) 141 | primes_idx++; 142 | 143 | res->primes_idx = primes_idx; 144 | res->size = primes[primes_idx]; 145 | res->count = 0; 146 | 147 | res->cmp_keys = setToSimpleIfZero (cmp_keys); 148 | res->hash_key = setToSimpleIfZero (hash_key); 149 | res->get_key_from_data = setToSimpleIfZero (get_key_from_data); 150 | res->free_data = setToSimpleIfZero (free_data); 151 | res->error = setToSimpleIfZero (error); 152 | 153 | /* ceil(0.8 * res -> size) */ 154 | 155 | res->threshold = (((res->size) << 2) + 4) / 5; 156 | res->num_resizes = 0; 157 | 158 | res->table = (HashTableBucket **) 159 | malloc (res->size * sizeof (HashTableBucket *)); 160 | 161 | for (i = 0; i < res->size; i++) 162 | res->table[i] = 0; 163 | 164 | return res; 165 | } 166 | 167 | /* ------------------------------------------------------------------------ */ 168 | 169 | void 170 | free_HashTable (HashTable ht) 171 | { 172 | int i; 173 | void (*free_data) (void *); 174 | free_data = ht->free_data; 175 | 176 | for (i = 0; i < ht->size; i++) 177 | { 178 | HashTableBucket *p, *tmp; 179 | for (p = ht->table[i]; p; p = tmp) 180 | { 181 | tmp = p->next; 182 | free_data (p->data); 183 | free (p); 184 | } 185 | } 186 | 187 | free (ht->table); 188 | free (ht); 189 | } 190 | 191 | /* ------------------------------------------------------------------------ */ 192 | 193 | static void 194 | resize_HashTable (HashTable ht) 195 | { 196 | HashTable new_ht = new_HashTable (primes[ht->primes_idx + 1], 197 | ht->cmp_keys, 198 | ht->hash_key, 199 | ht->get_key_from_data, 200 | ht->free_data, 201 | ht->error); 202 | int i; 203 | void *(*get_key_from_data) (void *) = ht->get_key_from_data; 204 | 205 | for (i = 0; i < ht->size; i++) 206 | { 207 | HashTableBucket *p, *tmp; 208 | for (p = ht->table[i]; p; p = tmp) 209 | { 210 | HashTableBucket **position = (HashTableBucket **) 211 | get_position_of_key_in_HashTable (new_ht, get_key_from_data 212 | (p->data)); 213 | tmp = p->next; 214 | p->next = *position; 215 | *position = p; 216 | new_ht->count++; 217 | } 218 | } 219 | 220 | free (ht->table); 221 | new_ht->num_resizes = ht->num_resizes + 1; 222 | *ht = *new_ht; 223 | free (new_ht); 224 | } 225 | 226 | /* ------------------------------------------------------------------------ */ 227 | 228 | void ** 229 | get_position_of_key_in_HashTable (HashTable ht, void *key) 230 | { 231 | int h = ht->hash_key (key); 232 | HashTableBucket **p; 233 | int (*cmp_keys) (void *, void *) = ht->cmp_keys; 234 | void *(*get_key_from_data) (void *) = ht->get_key_from_data; 235 | 236 | if (h < 0) 237 | h = -h; 238 | h %= ht->size; 239 | p = &(ht->table[h]); 240 | 241 | while (*p) 242 | { 243 | if (cmp_keys (key, get_key_from_data ((*p)->data)) == 0) 244 | { 245 | return (void **) p; 246 | } 247 | else 248 | p = &((*p)->next); 249 | } 250 | 251 | return (void **) p; 252 | } 253 | 254 | /* ------------------------------------------------------------------------ */ 255 | 256 | void * 257 | get_data_from_position_in_HashTable (HashTable ht, void **position) 258 | { 259 | (void) ht; 260 | return (*(HashTableBucket **) position)->data; 261 | } 262 | 263 | /* ------------------------------------------------------------------------ */ 264 | 265 | int 266 | get_size_of_HashTable (HashTable ht) 267 | { 268 | return ht->count; /* do not mess up with ht -> size ! */ 269 | } 270 | 271 | /* ------------------------------------------------------------------------ */ 272 | 273 | const char * 274 | get_statistics_for_HashTable (HashTable ht) 275 | { 276 | static char buffer[200]; 277 | int collisions = 0, maxchain = 0, i; 278 | 279 | for (i = 0; i < ht->size; i++) 280 | { 281 | HashTableBucket *b = ht->table[i]; 282 | if (b) 283 | { 284 | int j = 1; 285 | for (b = b->next; b; b = b->next) 286 | j++; 287 | 288 | if (maxchain < j) 289 | maxchain = j; 290 | if (j > 1) 291 | collisions += j - 1; 292 | } 293 | } 294 | 295 | sprintf (buffer, 296 | "elements=%d size=%d resizes=%d collisions=%d maxchain=%d", 297 | ht->count, ht->size, ht->num_resizes, collisions, maxchain); 298 | 299 | return buffer; 300 | } 301 | 302 | /* ------------------------------------------------------------------------ */ 303 | 304 | void 305 | insert_at_position_into_HashTable (HashTable ht, void **_position, void *data) 306 | { 307 | HashTableBucket *b, **position = (HashTableBucket **) _position; 308 | 309 | if (!position) 310 | (ht->error) ("insert_at_position_into_HashTable: non valid position"); 311 | 312 | if (ht->count >= ht->threshold) 313 | { 314 | resize_HashTable (ht); 315 | position = (HashTableBucket **) 316 | get_position_of_key_in_HashTable (ht, (ht->get_key_from_data) (data)); 317 | } 318 | 319 | b = (HashTableBucket *) malloc (sizeof (HashTableBucket)); 320 | b->data = data; 321 | b->next = *position; 322 | *position = b; 323 | ht->count++; 324 | } 325 | 326 | /* ------------------------------------------------------------------------ */ 327 | 328 | void 329 | overwrite_at_position_in_HashTable (HashTable ht, void *_position, void *data) 330 | { 331 | HashTableBucket **position = (HashTableBucket **) _position, *tmp; 332 | 333 | if (!position) 334 | (ht->error) ("overwrite_at_position_in_HashTable: non valid position"); 335 | 336 | tmp = *position; 337 | 338 | # ifndef NDEBUG 339 | { 340 | void *keyOld = (ht->get_key_from_data) (tmp->data); 341 | void *keyNew = (ht->get_key_from_data) (data); 342 | 343 | if ((ht->cmp_keys) (keyOld, keyNew) != 0) 344 | (ht->error) ("overwrite_at_position_in_HashTable: keys do not match"); 345 | } 346 | # endif 347 | 348 | (ht->free_data) (tmp->data); 349 | tmp->data = data; 350 | } 351 | 352 | /* ------------------------------------------------------------------------ */ 353 | 354 | int 355 | insert_into_HashTable (HashTable ht, void *data) 356 | { 357 | void **position = 358 | get_position_of_key_in_HashTable (ht, (ht->get_key_from_data) (data)); 359 | 360 | if (!*position) 361 | { 362 | insert_at_position_into_HashTable (ht, position, data); 363 | return 0; 364 | } 365 | else 366 | return 1; 367 | } 368 | 369 | /* ------------------------------------------------------------------------ */ 370 | 371 | void 372 | overwrite_in_HashTable (HashTable ht, void *data) 373 | { 374 | void **position = 375 | get_position_of_key_in_HashTable (ht, (ht->get_key_from_data) (data)); 376 | 377 | if (*position) 378 | { 379 | insert_at_position_into_HashTable (ht, position, data); 380 | } 381 | else 382 | { 383 | overwrite_at_position_in_HashTable (ht, position, data); 384 | } 385 | } 386 | 387 | /* ------------------------------------------------------------------------ */ 388 | 389 | void * 390 | get_data_from_HashTable (HashTable ht, void *key) 391 | { 392 | HashTableBucket *bucket = 393 | *(HashTableBucket **) get_position_of_key_in_HashTable (ht, key); 394 | 395 | return bucket ? bucket->data : 0; 396 | } 397 | 398 | /* ------------------------------------------------------------------------ */ 399 | 400 | void 401 | remove_from_HashTable (HashTable ht, void *key) 402 | { 403 | HashTableBucket *tmp, **position = 404 | (HashTableBucket **) get_position_of_key_in_HashTable (ht, key); 405 | 406 | if ((tmp = *position)) 407 | { 408 | *position = tmp->next; 409 | ht->free_data (tmp->data); 410 | free (tmp); 411 | } 412 | } 413 | 414 | /* ------------------------------------------------------------------------ */ 415 | 416 | void 417 | setup_HashTableIterator (HashTable ht, HashTableIterator * iterator) 418 | { 419 | iterator->ht = ht; 420 | iterator->pos = -1; /* have a look at increment_HashTableIterator */ 421 | iterator->cursor = 0; 422 | increment_HashTableIterator (iterator); 423 | } 424 | 425 | /* ------------------------------------------------------------------------ */ 426 | 427 | void 428 | increment_HashTableIterator (HashTableIterator * iterator) 429 | { 430 | HashTableBucket *current = (HashTableBucket *) iterator->cursor; 431 | 432 | if (current && current->next) 433 | { 434 | iterator->cursor = current->next; 435 | } 436 | else 437 | { 438 | int i = iterator->pos + 1; 439 | int sz = iterator->ht->size; 440 | HashTableBucket **table = iterator->ht->table; 441 | 442 | while (i < sz) 443 | { 444 | if (table[i]) 445 | { 446 | iterator->pos = i; 447 | iterator->cursor = table[i]; 448 | return; 449 | } 450 | else 451 | i++; 452 | } 453 | 454 | iterator->cursor = 0; 455 | iterator->pos = sz; 456 | } 457 | } 458 | 459 | /* ------------------------------------------------------------------------ */ 460 | 461 | int 462 | is_done_HashTableIterator (HashTableIterator * iterator) 463 | { 464 | return iterator->cursor == 0; 465 | } 466 | 467 | /* ------------------------------------------------------------------------ */ 468 | 469 | void * 470 | get_data_from_HashTableIterator (HashTableIterator * iterator) 471 | { 472 | HashTableBucket *bucket = (HashTableBucket *) iterator->cursor; 473 | 474 | if (!bucket) 475 | return 0; 476 | else 477 | return bucket->data; 478 | } 479 | 480 | /* ------------------------------------------------------------------------ */ 481 | 482 | /*---------------------------------------------------------------------------. 483 | | the following function is the famous hash function of P.J. Weinberger as | 484 | | desribed in the dragon book of A.V. Aho, R. Sethi and J.D. Ullman. | 485 | `---------------------------------------------------------------------------*/ 486 | 487 | #define HASHPJWSHIFT ((sizeof(int))*8-4) 488 | 489 | int 490 | hashpjw_HashTable (void *_s) 491 | { 492 | const char *s = (char *) _s, *p; 493 | int h = 0, g; 494 | 495 | for (p = s; *p != '\0'; p++) 496 | { 497 | h = (h << 4) + *p; 498 | if ((g = h & (0xf << HASHPJWSHIFT))) 499 | { 500 | h = h ^ (g >> HASHPJWSHIFT); 501 | h = h ^ g; 502 | } 503 | } 504 | 505 | return h > 0 ? h : -h; // no modulo but positive 506 | } 507 | -------------------------------------------------------------------------------- /ccmalloc/src/hash.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * (C) 1997-1998 Armin Biere 3 | * 4 | * $Id: hash.h,v 1.2 2001/12/04 09:46:41 biere Exp $ 5 | *---------------------------------------------------------------------------- 6 | */ 7 | #ifndef _hash_h_INCLUDED 8 | #define _hash_h_INCLUDED 9 | 10 | /*---------------------------------------------------------------------------. 11 | | This is an implementation of a general hash table module. | 12 | | It assumes that keys for data stored in the hash table can | 13 | | be extracted from the data. | 14 | | | 15 | | One very important feature of this implementation is that | 16 | | the data stored in the hashtable is `owned' by the hash | 17 | | table. The user should not delete it! It will be deleted | 18 | | by the destructor of the hash table or by an `overwrite' | 19 | | method. To ease the use of different allocators and to | 20 | | be able to store statically allocated data in a hash table | 21 | | the user can provide his own `free' function. | 22 | | | 23 | | TOF | 24 | | | 25 | | HashTable: | 26 | | | 27 | | new_HashTable constructor | 28 | | free_HashTable destructor | 29 | | | 30 | | insert_into_HashTable maninpulator | 31 | | insert_at_position_into_HashTable maninpulator | 32 | | overwrite_in_HashTable maninpulator | 33 | | overwrite_at_position_in_HashTable maninpulator | 34 | | remove_from_HashTable maninpulator | 35 | | | 36 | | get_data_from_HashTable inspector | 37 | | get_data_from_position_in_HashTable inspector | 38 | | get_position_of_key_in_HashTable inspector | 39 | | | 40 | | get_size_of_HashTable inspector | 41 | | get_statistics_of_HashTable inspector | 42 | | | 43 | | HashTableIterator: | 44 | | | 45 | | no constructors or | 46 | | destructors | 47 | | | 48 | | setup_HashTableIterator maninpulator | 49 | | increment_HashTableIterator maninpulator | 50 | | | 51 | | is_done_HashTableIterator inspector | 52 | | get_data_from_HashTableIterator inspector | 53 | | | 54 | | general: | 55 | | | 56 | | hashpjw_HashTable | 57 | `---------------------------------------------------------------------------*/ 58 | 59 | typedef struct HashTable_ *HashTable; 60 | 61 | /* Construct a new HashTable. The first parameter gives the initial 62 | * minimal size of the hashtable. The hashtable resizes itself if 63 | * necessary and grows exponentially with each resize step. 64 | * This means that using 0 as minimal_size does not really hurt too much. 65 | * 66 | * The next five function parameters are used to control the 67 | * data and the keys stored in the hash table. 68 | * 69 | * cmp_keys -- is the comparison function for keys. It should 70 | * return the same results as the `strcmp'function. 71 | * (actually: 0 iff the two args are the same) 72 | * If cmp_keys is 0 then pointer comparison is used. 73 | * 74 | * hash_key -- hash function (see also hashpjw_HashTable). If it 75 | * is zero than a cast from `void *' to `int' is used. 76 | * 77 | * get_key_from_data -- 78 | * this function is used to get the key from 79 | * the data stored in the hash table. If this parameter 80 | * is zero than it is assumed that the data is the 81 | * also its key. 82 | * 83 | * free_data -- user provided deallocator of data stored in the 84 | * hashtable. If zero do not deallocate data. 85 | * 86 | * error -- this function is called if an internal error 87 | * ocurred (f.e. interface violation). As default 88 | * (set to zero) print an descriptive error message 89 | * and produce a segmentation fault. 90 | */ 91 | 92 | extern HashTable 93 | new_HashTable (int minimal_size, 94 | int (*cmp_keys) (void *key1, void *key2), 95 | int (*hash_key) (void *key), 96 | void *(*get_key_from_data) (void *data), 97 | void (*free_data) (void *data), void (*error) (char *errmsg)); 98 | 99 | /* Destructor of HashTables. Free all stored data with the user provided 100 | * deallocation function. 101 | */ 102 | 103 | extern void free_HashTable (HashTable); 104 | 105 | /* insert a data into the HashTable but do not overwrite existing 106 | * data with the same key. The return value is true iff 107 | * some data with the same key is already stored in the hash table. 108 | * In this case the user generally has to deallocate `data_with_key' 109 | * on his own. 110 | */ 111 | 112 | extern int insert_into_HashTable (HashTable ht, void *data_with_key); 113 | 114 | /* remove correponding data from the hash table and deallocate 115 | * it using the user provided deallocator. 116 | */ 117 | 118 | extern void remove_from_HashTable (HashTable ht, void *key); 119 | 120 | /* overwrite an existing entry in the hash table with the same 121 | * key as the key of `data_with_key' or insert a new entry. 122 | * In the first case also deallocate the overwritten data. 123 | */ 124 | 125 | extern void overwrite_in_HashTable (HashTable ht, void *data_with_key); 126 | 127 | /* search for data with this key. Return zero if not found. 128 | * (see also `get_data_from_position_in_HashTable') 129 | */ 130 | 131 | extern void *get_data_from_HashTable (HashTable ht, void *key); 132 | 133 | /* return the number of stored key/data pairs 134 | */ 135 | 136 | extern int get_size_of_HashTable (HashTable ht); 137 | 138 | /* Returns an statically allocated string with useful ;-) 139 | * statistical information. This string is overwritten by 140 | * subsequent calls to this function. 141 | */ 142 | 143 | extern const char *get_statistics_for_HashTable (HashTable ht); 144 | 145 | /* For many applications of hash tables (f.e. a symbol table 146 | * of a compiler) the user must check if some data with a 147 | * given key already exists in the hash table before he 148 | * actually constructs the data (f.e. a new entry into the 149 | * symbol table). If no data with this key is found then 150 | * the new allocated data is inserted into the hash table. 151 | * This means that the same search must be done again. 152 | * 153 | * This can be avoided if we know from the first search 154 | * where the new allocated data will be inserted. For 155 | * this purpose `get_position_of_key_in_HashTable' can be used. 156 | * The *dereferenced* return value is exactly 0 iff the search 157 | * was succesfull. In this case 158 | * `get_data_from_position_in_HashTable' can be used to get the 159 | * actual data for the key. If the search is not succesfull 160 | * the user can now allocated the new data and insert it 161 | * at the returned position with 162 | * `insert_at_position_into_HashTable' or 163 | * `overwrite_at_position_in_HashTable'. 164 | */ 165 | 166 | extern void **get_position_of_key_in_HashTable (HashTable ht, void *key); 167 | 168 | extern void *get_data_from_position_in_HashTable (HashTable, void **position); 169 | 170 | extern void 171 | insert_at_position_into_HashTable (HashTable ht, void **position, void *data); 172 | 173 | extern void 174 | overwrite_at_position_in_HashTable (HashTable ht, void *position, void *data); 175 | 176 | /* The definition of this structure is placed here 177 | * because it should be possible to allocate an iterator as 178 | * an automatic variable. This is also more convenient for 179 | * the user. 180 | */ 181 | 182 | typedef struct HashTableIterator 183 | { 184 | HashTable ht; 185 | int pos; 186 | void *cursor; 187 | } 188 | HashTableIterator; 189 | 190 | /* Setup an iterator. It is possible to have multiple 191 | * iterators for the same hash table and to traverse 192 | * the hash table in parallel. 193 | * ATTENTION: These iterators are not save with 194 | * respect to `remove' operations on the traversed 195 | * hash table. 196 | */ 197 | 198 | extern void setup_HashTableIterator (HashTable, HashTableIterator *); 199 | 200 | extern void increment_HashTableIterator (HashTableIterator *); 201 | 202 | extern void *get_data_from_HashTableIterator (HashTableIterator *); 203 | 204 | extern int is_done_HashTableIterator (HashTableIterator *); 205 | 206 | /* Hash function for zero terminated data (f.e. strings). 207 | * It is from the `dragon book' and should work very 208 | * well especially for strings as keys. 209 | */ 210 | 211 | extern int hashpjw_HashTable (void *); 212 | 213 | #endif 214 | -------------------------------------------------------------------------------- /ccmalloc/src/wrapper.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | * (C) 1997-2003 Armin Biere 3 | * 4 | * $Id: wrapper.c,v 1.5 2003/02/03 08:03:56 biere Exp $ 5 | *---------------------------------------------------------------------------- 6 | */ 7 | 8 | #include "config.h" 9 | 10 | /* ------------------------------------------------------------------------ */ 11 | 12 | /* Uncomment the next line to get a raw logging of all calls to malloc 13 | * and free. 14 | */ 15 | 16 | /* 17 | #define LOG_EXTERNAL_MALLOC 18 | */ 19 | 20 | /* ------------------------------------------------------------------------ */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifndef NDEBUG 31 | #include 32 | #endif 33 | 34 | extern void *ccmalloc_malloc (size_t); 35 | extern void ccmalloc_free (void *); 36 | extern int ccmalloc_size (void *, size_t *); 37 | extern void ccmalloc_die_or_continue (char *fmt, ...); 38 | 39 | #ifndef RTLD_NOW 40 | #define RTLD_NOW 1 41 | #endif 42 | 43 | #define MALLOC_SYMBOL "malloc" 44 | #define FREE_SYMBOL "free" 45 | 46 | /* ------------------------------------------------------------------------ */ 47 | /* This should work. But sometimes it is not enough. Then you have to set 48 | * this to a higher value and recompile ccmalloc. 49 | */ 50 | 51 | #define MAX_STATIC_MEM 100000 52 | 53 | /* ------------------------------------------------------------------------ */ 54 | 55 | enum WrapperState 56 | { 57 | WRAPPER_UNINITIALIZED, 58 | WRAPPER_INITIALIZING, 59 | WRAPPER_INITIALIZED 60 | }; 61 | 62 | /* ------------------------------------------------------------------------ */ 63 | 64 | static void *(*libc_malloc) (size_t) = 0; 65 | static void (*libc_free) (void *) = 0; 66 | static enum WrapperState wrapper_state = WRAPPER_UNINITIALIZED; 67 | static int semaphore = 0; 68 | 69 | static char static_mem[MAX_STATIC_MEM]; 70 | static char *bottom_static_mem = static_mem; 71 | static char *top_static_mem = static_mem + MAX_STATIC_MEM; 72 | 73 | static long wrapper_bytes_allocated = 0, 74 | wrapper_num_allocated = 0, wrapper_num_deallocated = 0; 75 | 76 | /* ------------------------------------------------------------------------ */ 77 | 78 | static int 79 | wrapper_strlen (const char *str) 80 | { 81 | const char *p; 82 | for (p = str; *p; p++) 83 | ; 84 | 85 | return p - str; 86 | } 87 | 88 | /* ------------------------------------------------------------------------ */ 89 | /* can not call `printf' because it calls malloc itself */ 90 | 91 | static void 92 | print (const char *str) 93 | { 94 | write (2, str, wrapper_strlen (str)); 95 | } 96 | 97 | /* ------------------------------------------------------------------------ */ 98 | #ifdef LOG_EXTERNAL_MALLOC 99 | /* ------------------------------------------------------------------------ */ 100 | /* unfortunately we can not use `printf' since `printf' calls malloc itself 101 | */ 102 | static char print_hex_tab[16] = { 103 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 104 | 'f' 105 | }; 106 | 107 | /* 32Bit: sizeof(unsigned) == 4 */ 108 | 109 | static void 110 | print_hex (unsigned d) 111 | { 112 | char buffer[9]; 113 | 114 | buffer[7] = print_hex_tab[d % 16]; 115 | d /= 16; 116 | buffer[6] = print_hex_tab[d % 16]; 117 | d /= 16; 118 | buffer[5] = print_hex_tab[d % 16]; 119 | d /= 16; 120 | buffer[4] = print_hex_tab[d % 16]; 121 | d /= 16; 122 | buffer[3] = print_hex_tab[d % 16]; 123 | d /= 16; 124 | buffer[2] = print_hex_tab[d % 16]; 125 | d /= 16; 126 | buffer[1] = print_hex_tab[d % 16]; 127 | d /= 16; 128 | buffer[0] = print_hex_tab[d % 16]; 129 | d /= 16; 130 | 131 | buffer[8] = 0; 132 | 133 | print (buffer); 134 | } 135 | 136 | static void 137 | print_dec (unsigned d) 138 | { 139 | if (d) 140 | { 141 | char buffer[11]; /* also 32 bit !! */ 142 | int i = 10; 143 | 144 | buffer[11] = 0; 145 | 146 | while (1) 147 | { 148 | buffer[i] = print_hex_tab[d % 10]; 149 | d /= 10; 150 | if (d) 151 | i--; 152 | else 153 | break; 154 | } 155 | 156 | print (buffer + i); 157 | } 158 | else 159 | print ("0"); 160 | } 161 | 162 | /* ------------------------------------------------------------------------ */ 163 | #endif 164 | /* ------------------------------------------------------------------------ */ 165 | 166 | static void 167 | load_libc () 168 | { 169 | void *handle; 170 | const char *err; 171 | char *libcname; 172 | 173 | libcname = NAME_OF_LIBC; 174 | 175 | handle = dlopen (libcname, RTLD_NOW); 176 | if ((err = dlerror ())) 177 | { 178 | print ("*** wrapper can not open `"); 179 | print (libcname); 180 | print ("'!\n"); 181 | print ("*** dlerror() reports: "); 182 | print (err); 183 | print ("\n"); 184 | exit (1); 185 | } 186 | 187 | libc_malloc = (void *(*)(size_t)) dlsym (handle, MALLOC_SYMBOL); 188 | if ((err = dlerror ())) 189 | { 190 | print ("*** wrapper does not find `"); 191 | print (MALLOC_SYMBOL); 192 | print ("' in `libc.so'!\n"); 193 | exit (1); 194 | } 195 | 196 | libc_free = (void (*)(void *)) dlsym (handle, FREE_SYMBOL); 197 | if ((err = dlerror ())) 198 | { 199 | print ("*** wrapper does not find `"); 200 | print (FREE_SYMBOL); 201 | print ("' in `libc.so'!\n"); 202 | exit (1); 203 | } 204 | } 205 | 206 | /* ------------------------------------------------------------------------ */ 207 | /* just play it save and always do an 8 byte alignment 208 | */ 209 | 210 | #define WRAPPER_ALIGN_MASK 7 211 | 212 | /* ------------------------------------------------------------------------ */ 213 | 214 | #define wrapper_isAligned(c) ((((unsigned)c) & WRAPPER_ALIGN_MASK) == 0) 215 | 216 | #define wrapper_align(c) \ 217 | { \ 218 | if(!wrapper_isAligned(c)) \ 219 | { \ 220 | *(unsigned*)&c = (((unsigned)c) | WRAPPER_ALIGN_MASK); \ 221 | *(unsigned*)&c = (((unsigned)c) + 1); \ 222 | } \ 223 | } 224 | 225 | /* ------------------------------------------------------------------------ */ 226 | 227 | static void * 228 | static_malloc (size_t n) 229 | { 230 | char *res; 231 | int sizeof_size_t; 232 | size_t *where_to_store_size, aligned_size; 233 | 234 | aligned_size = n; 235 | sizeof_size_t = sizeof (sizeof_size_t); 236 | 237 | wrapper_align (aligned_size); 238 | wrapper_align (sizeof_size_t); 239 | wrapper_align (bottom_static_mem); 240 | 241 | where_to_store_size = (size_t *) bottom_static_mem; 242 | bottom_static_mem += sizeof_size_t; /* aligned + aligned = aligned */ 243 | res = bottom_static_mem; 244 | bottom_static_mem += aligned_size; 245 | 246 | if (bottom_static_mem >= top_static_mem) 247 | { 248 | print ("*** static memory in wrapper exceeded\n"); 249 | exit (1); 250 | } 251 | 252 | *where_to_store_size = n; 253 | 254 | return (void *) res; 255 | } 256 | 257 | /* ------------------------------------------------------------------------ */ 258 | 259 | static void 260 | static_free (void *p) 261 | { 262 | #ifndef NDEBUG 263 | { 264 | if (((char *) p) < static_mem || ((char *) p) >= top_static_mem) 265 | { 266 | print ("*** nonvalid arg for static_free() in wrapper\n"); 267 | kill (0, SIGSEGV); // simulate assert 268 | exit (1); 269 | } 270 | } 271 | #else 272 | (void) p; 273 | #endif 274 | } 275 | 276 | /* ------------------------------------------------------------------------ */ 277 | 278 | void 279 | libcwrapper_inc_semaphore () 280 | { 281 | semaphore++; 282 | } 283 | 284 | void 285 | libcwrapper_dec_semaphore () 286 | { 287 | semaphore--; 288 | } 289 | 290 | /* ------------------------------------------------------------------------ */ 291 | 292 | void * 293 | malloc (size_t n) 294 | { 295 | void *res; 296 | 297 | switch (wrapper_state) 298 | { 299 | case WRAPPER_UNINITIALIZED: 300 | 301 | wrapper_state = WRAPPER_INITIALIZING; 302 | load_libc (); 303 | wrapper_state = WRAPPER_INITIALIZED; 304 | 305 | /* !!!!!!! fall through !!!!!!! */ 306 | 307 | case WRAPPER_INITIALIZED: 308 | 309 | if (semaphore) 310 | { 311 | wrapper_num_allocated++; 312 | wrapper_bytes_allocated += n; 313 | res = (*libc_malloc) (n); 314 | } 315 | else 316 | { 317 | semaphore++; 318 | res = ccmalloc_malloc (n); 319 | semaphore--; 320 | } 321 | break; 322 | 323 | default: 324 | case WRAPPER_INITIALIZING: 325 | 326 | res = static_malloc (n); 327 | break; 328 | } 329 | 330 | # ifdef LOG_EXTERNAL_MALLOC 331 | { 332 | print ("::: 0x"); 333 | print_hex ((unsigned) res); 334 | if (wrapper_state == WRAPPER_INITIALIZING) 335 | print (" static "); 336 | else if (semaphore) 337 | print (" internal"); 338 | else 339 | print (" external"); 340 | print (" malloc("); 341 | print_dec (n); 342 | print (")\n"); 343 | } 344 | # endif 345 | 346 | /* Initialize with something weird 347 | */ 348 | if (res) 349 | memset (res, 0x42, n); 350 | 351 | return res; 352 | } 353 | 354 | /* ------------------------------------------------------------------------ */ 355 | 356 | void 357 | free (void *p) 358 | { 359 | # ifndef NDEBUG 360 | { 361 | if (wrapper_state != WRAPPER_INITIALIZING) 362 | { 363 | if (static_mem <= ((char *) p) && ((char *) p) < top_static_mem) 364 | { 365 | print ("*** free() in wrapper called for argument\n"); 366 | print ("*** that was allocated during initialization!\n"); 367 | } 368 | } 369 | } 370 | # endif 371 | 372 | switch (wrapper_state) 373 | { 374 | case WRAPPER_UNINITIALIZED: 375 | 376 | print ("*** free() in wrapper called before malloc()\n"); 377 | exit (1); 378 | break; 379 | 380 | case WRAPPER_INITIALIZED: 381 | 382 | if (semaphore) 383 | { 384 | wrapper_num_deallocated++; 385 | (*libc_free) (p); 386 | } 387 | else 388 | { 389 | semaphore++; 390 | ccmalloc_free (p); 391 | semaphore--; 392 | } 393 | break; 394 | 395 | default: 396 | case WRAPPER_INITIALIZING: 397 | 398 | static_free (p); 399 | break; 400 | } 401 | 402 | # ifdef LOG_EXTERNAL_MALLOC 403 | { 404 | print ("::: 0x"); 405 | print_hex ((unsigned) p); 406 | if (semaphore) 407 | print (" internal"); 408 | else 409 | print (" external"); 410 | print (" free\n"); 411 | } 412 | # endif 413 | } 414 | 415 | /* ------------------------------------------------------------------------ */ 416 | 417 | void * 418 | calloc (size_t nmemb, size_t size) 419 | { 420 | void *res; 421 | size *= nmemb; 422 | res = malloc (size); 423 | if (res) 424 | memset (res, 0, size); 425 | return res; 426 | } 427 | 428 | /* ------------------------------------------------------------------------ */ 429 | 430 | static void * 431 | _realloc (void *ptr, size_t size, size_t previous_size) 432 | { 433 | void *res; 434 | 435 | res = (void *) malloc (size); 436 | if (size < previous_size) 437 | (void) memcpy (res, ptr, size); 438 | else 439 | (void) memcpy (res, ptr, previous_size); 440 | free (ptr); 441 | 442 | return res; 443 | } 444 | 445 | /* ------------------------------------------------------------------------ */ 446 | 447 | void * 448 | realloc (void *ptr, size_t size) 449 | { 450 | size_t previous_size, sizeof_size_t; 451 | char *where_size_was_stored; 452 | void *res; 453 | 454 | if (ptr == 0) 455 | res = malloc (size); 456 | else if (size == 0) 457 | { 458 | free (ptr); 459 | res = 0; 460 | } 461 | else 462 | { 463 | switch (wrapper_state) 464 | { 465 | default: 466 | print ("*** ccmalloc: non valid wrapper state in realloc()\n"); 467 | exit (1); 468 | res = 0; 469 | break; 470 | 471 | case WRAPPER_UNINITIALIZED: 472 | print ("*** realloc() in wrapper called before malloc()\n"); 473 | exit (1); 474 | res = 0; 475 | break; 476 | 477 | case WRAPPER_INITIALIZING: 478 | sizeof_size_t = sizeof (size_t); 479 | wrapper_align (sizeof_size_t); 480 | where_size_was_stored = (char *) ptr; 481 | where_size_was_stored -= sizeof_size_t; 482 | previous_size = *(size_t *) where_size_was_stored; 483 | res = _realloc (ptr, size, previous_size); 484 | break; 485 | 486 | case WRAPPER_INITIALIZED: 487 | if (ccmalloc_size (ptr, &previous_size)) 488 | { 489 | res = _realloc (ptr, size, previous_size); 490 | } 491 | else 492 | { 493 | ccmalloc_die_or_continue 494 | ("*** realloc(0x%x) called with non valid argument\n", 495 | (unsigned) ptr); 496 | res = malloc (size); 497 | } 498 | break; 499 | } 500 | } 501 | 502 | return res; 503 | } 504 | 505 | /* ------------------------------------------------------------------------ */ 506 | 507 | const char * 508 | wrapper_stats () 509 | { 510 | static char buffer[200]; 511 | sprintf (buffer, 512 | "%ld allocations, %ld deallocations, %ld bytes allocated", 513 | wrapper_num_allocated, wrapper_num_deallocated, 514 | wrapper_bytes_allocated); 515 | return buffer; 516 | } 517 | -------------------------------------------------------------------------------- /ccmalloc/test/.cvsignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.log* 3 | .ccmalloc 4 | -------------------------------------------------------------------------------- /ccmalloc/test/Makefile: -------------------------------------------------------------------------------- 1 | LIBS=../obj/ccmalloc-$(CC).o -L../lib -lccmalloc -ldl 2 | 3 | .SUFFIXES: .exe .c .cc 4 | 5 | .cc.exe: $*.cc $(DEPS) 6 | $(CC) $(CFLAGS) -o $@ $*.cc $(LIBS) 7 | .c.exe: $*.c ../obj/ccmalloc-$(CC).o ../lib/libccmalloc.a 8 | $(CC) $(CFLAGS) -o $@ $*.c $(LIBS) 9 | .c.o: $*.c 10 | $(CC) $(CFLAGS) -c -o $@ $*.c 11 | all: 12 | ./testall 13 | clean: 14 | rm -f *.exe *.log *.log.gz *.log.* .ccmalloc core a.out 15 | rm -f lib_test_C_11.a lib_test_C_19.so *.o 16 | 17 | # always generate libraries 18 | # 19 | lib_test_C_11.a: # forced recompilation every time 20 | $(CC) $(CFLAGS) -c lib_test_C_11.c 21 | ar cr $@ lib_test_C_11.o 22 | ranlib $@ 23 | 24 | test_C_11.exe: lib_test_C_11.a test_C_11.c $(DEPS) 25 | $(CC) $(CFLAGS) -o $@ $*.c -L. -l_test_C_11 $(LIBS) 26 | 27 | test_C_13.exe: test_C_13.c $(DEPS) 28 | $(CC) -o $@ -O $*.c $(LIBS) 29 | 30 | # TODO generalize omit-frame-pointer flag to other compilers 31 | # 32 | test_C_14.exe: test_C_14.c $(DEPS) 33 | gcc -o $@ -fomit-frame-pointer -O2 $*.c $(LIBS) 34 | 35 | # TODO generalize dynamic linking flags to other linkers than gcc 36 | # 37 | lib_test_C_19.so: # forced recompilation every time 38 | gcc -fPIC -c -o lib_test_C_19.o lib_test_C_19.c 39 | gcc -shared -WL,-soname,$@ -o $@ lib_test_C_19.o 40 | 41 | test_C_19.exe: test_C_19.o lib_test_C_19.so $(DEPS) 42 | $(CC) $(CFLAGS) -o $@ test_C_19.o -L. -l_test_C_19 $(LIBS) 43 | -------------------------------------------------------------------------------- /ccmalloc/test/README: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | README: 3 | ------------------------------------------------------------------------------ 4 | 5 | *************************************************** 6 | * the C and C++ files in this directory have bugs * 7 | *************************************************** 8 | 9 | After executing './testall' you can find logs in test_C*.log*. 10 | To compile and execute one test type `./testone ', 11 | e.g. './testone test_C_01.c'. You have to inspect the tests 12 | manually. 13 | 14 | Here is a list of the different purposes of the tests: 15 | 16 | different settings of flags in .ccmalloc: 17 | 18 | test_C_01.c only count 19 | test_C_02.c normal 20 | test_C_03.c very verbose + statistics 21 | 22 | free called twice 23 | 24 | test_C_04.c 25 | 26 | overwrite of allocated data 27 | 28 | test_C_05.c 29 | 30 | underwrite of allocated data 31 | 32 | test_C_06.c 33 | 34 | corruption of free space (write access to deallocated data) 35 | 36 | test_C_07.c 37 | test_C_08.c but continue (-> no cruel world message) 38 | 39 | double free and leaks 40 | 41 | test_C_09.c 42 | 43 | test external check for integrity function 44 | 45 | test_C_10.c 46 | 47 | test combination with external libraries 48 | 49 | test_C_11.c lib_test_C_11.c 50 | 51 | test external call chains flag 52 | 53 | test_C_12.c 54 | 55 | compile with no debugging info 56 | 57 | test_C_13.c 58 | 59 | compile with no frame pointers and no debugging info 60 | 61 | test_C_14.c 62 | 63 | test strdup 64 | 65 | test_C_15.c 66 | 67 | test 8 byte alignment of doubles 68 | 69 | test_C_16.c 70 | 71 | test logpid (starts severaly copies of itselft) 72 | 73 | test_C_17.c 74 | 75 | test dont-log-chain and only-log-chain 76 | 77 | test_C_18.c 78 | 79 | test new read-dynlib-with-gdb 80 | 81 | test_C_19.c lib_test_C_19.c 82 | 83 | test static initializers and deinitializers of C++ 84 | 85 | test_C++_01.cc 86 | test_C++_02.cc 87 | 88 | ------------------------------------------------------------------------------ 89 | (C) 1997-1998 Armin Biere 90 | $Id: README,v 1.2 2000/12/20 07:58:46 biere Exp $ 91 | ------------------------------------------------------------------------------ 92 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C++_01: -------------------------------------------------------------------------------- 1 | file test_C++_01.exe 2 | log test_C++_01.log 3 | set keep-deallocated-data 4 | set statistics 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C++_02: -------------------------------------------------------------------------------- 1 | file test_C++_02.exe 2 | log test_C++_02.log 3 | set keep-deallocated-data 4 | set statistics 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_01: -------------------------------------------------------------------------------- 1 | file test_C_01.exe 2 | log test_C_01.log 3 | set only-count 4 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_02: -------------------------------------------------------------------------------- 1 | file test_C_02.exe 2 | log test_C_02.log 3 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_03: -------------------------------------------------------------------------------- 1 | file test_C_03.exe 2 | log test_C_03.log 3 | set statistics 4 | set keep-deallocated-data 1 5 | set print-addresses 6 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_04: -------------------------------------------------------------------------------- 1 | file test_C_04.exe 2 | log test_C_04.log 3 | set keep-deallocated-data 4 | set continue 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_05: -------------------------------------------------------------------------------- 1 | file test_C_05.exe 2 | log test_C_05.log 3 | set check-overwrites 4 | set continue 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_06: -------------------------------------------------------------------------------- 1 | file test_C_06.exe 2 | log test_C_06.log 3 | set continue 4 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_07: -------------------------------------------------------------------------------- 1 | set keep-deallocated-data 2 | set check-free-space 3 | file test_C_07.exe 4 | log test_C_07.log 5 | set continue 6 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_08: -------------------------------------------------------------------------------- 1 | set keep-deallocated-data 2 | set check-free-space 3 | set check-overwrites 10 4 | set check-underwrites 10 5 | set continue 6 | set check-interval 10 7 | set check-start 28 8 | file test_C_08.exe 9 | log test_C_08.log 10 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_09: -------------------------------------------------------------------------------- 1 | set keep-deallocated-data 2 | set continue 3 | set statistics 4 | set print-addresses 5 | file test_C_09.exe 6 | log test_C_09.log.gz 7 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_10: -------------------------------------------------------------------------------- 1 | set check-underwrites 2 2 | set continue 3 | file test_C_10.exe 4 | log test_C_10.log 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_11: -------------------------------------------------------------------------------- 1 | file test_C_11.exe 2 | log test_C_11.log 3 | set keep-deallocated-data 4 | set statistics 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_12: -------------------------------------------------------------------------------- 1 | set library-chains 2 | file test_C_12.exe 3 | log test_C_12.log 4 | set keep-deallocated-data 5 | set statistics 6 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_13: -------------------------------------------------------------------------------- 1 | file test_C_13.exe 2 | log test_C_13.log 3 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_14: -------------------------------------------------------------------------------- 1 | file test_C_14.exe 2 | set library-chains 3 | log test_C_14.log 4 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_15: -------------------------------------------------------------------------------- 1 | file test_C_15.exe 2 | set library-chains 3 | set statistics 4 | set keep-deallocated-data 5 | log test_C_15.log 6 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_16: -------------------------------------------------------------------------------- 1 | file test_C_16.exe 2 | log test_C_16.log 3 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_17: -------------------------------------------------------------------------------- 1 | logpid test_C_17.log 2 | file test_C_17.exe 3 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_18: -------------------------------------------------------------------------------- 1 | file test_C_18.exe 2 | log test_C_18.log 3 | dont-log-chain f;g;h 4 | only-log-chain h;i 5 | -------------------------------------------------------------------------------- /ccmalloc/test/ccmalloc_C_19: -------------------------------------------------------------------------------- 1 | file test_C_19.exe 2 | log test_C_19.log 3 | set load-dynlibs 1 4 | set library-chains 5 | -------------------------------------------------------------------------------- /ccmalloc/test/execute: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./$* || exit 0 3 | -------------------------------------------------------------------------------- /ccmalloc/test/lib_test_C_11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void * MALLOC(size_t n) 4 | { 5 | return malloc(n); 6 | } 7 | -------------------------------------------------------------------------------- /ccmalloc/test/lib_test_C_19.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void oops() { (void) malloc(4711); } 4 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C++_01.cc: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | #include 3 | #include 4 | #include 5 | }; 6 | 7 | class Wrong 8 | { 9 | protected: 10 | 11 | char * str; 12 | 13 | public: 14 | 15 | Wrong(const char * s) 16 | { 17 | strcpy(str = new char [ strlen(s) + 1 ], s); 18 | } 19 | }; 20 | 21 | class Right 22 | : 23 | public Wrong 24 | { 25 | public: 26 | 27 | Right(const char * s) : Wrong(s) { } 28 | ~Right() { delete [] str; } 29 | }; 30 | 31 | Wrong wrong("first test"); 32 | Right right("right"); 33 | 34 | int 35 | main() 36 | { 37 | Wrong a("a second test with a longer string"); 38 | Wrong b("short string"); 39 | (void) a; (void) b; 40 | 41 | return 0; 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C++_02.cc: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | #include 3 | }; 4 | 5 | class A 6 | { 7 | protected: 8 | 9 | char * s; 10 | 11 | public: 12 | 13 | A() : s(0) { } 14 | void operator = (const char * t) { s = strcpy(new char [strlen(t)+1], t); } 15 | }; 16 | 17 | class B 18 | : 19 | public A 20 | { 21 | public: 22 | 23 | void operator = (const char * t) { A::operator = (t); } 24 | ~B() { if(s) delete s; } 25 | }; 26 | 27 | A a; 28 | B b; 29 | 30 | int main() 31 | { 32 | a = "hallo"; 33 | b = "longer string"; 34 | exit(0); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char * mkstr(char * s) { return strcpy((char*)malloc(strlen(s)+1), s); } 6 | 7 | void f() { mkstr("asdfasdf"); } 8 | 9 | void g() 10 | { 11 | int i; 12 | char * a[100]; 13 | 14 | for(i=0; i<100; i++) 15 | a[i] = mkstr("in f"); 16 | 17 | free(a[2]); 18 | free(a[0]); 19 | } 20 | 21 | int 22 | main() 23 | { 24 | char * a = mkstr("Hallo"), *b; 25 | 26 | (void) mkstr("Test"); 27 | 28 | f(); 29 | 30 | b = mkstr("Test"); 31 | 32 | g(); 33 | 34 | a[6]=0; 35 | 36 | free(b); 37 | free(a); 38 | 39 | exit(0); 40 | return 1; 41 | } 42 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | char * a = (char*) malloc(15); 6 | free(a); 7 | a[0]=1; 8 | free(a); 9 | exit(0); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_05.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define S "Hello World" 5 | 6 | int main() 7 | { 8 | char * s = strcpy((char*) malloc(strlen(S)), S); 9 | free(s); 10 | exit(0); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_06.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | char * s = (char*) malloc(4); 6 | s[-1]='A'; 7 | free(s); 8 | exit(0); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_07.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | main() 5 | { 6 | char * a = (char*) malloc(10); 7 | free(a); 8 | a[2]=123; 9 | free(malloc(2)); 10 | 11 | exit(0); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_08.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | main() 5 | { 6 | char * a = (char*) malloc(100); 7 | char * b = (char*) malloc(100); 8 | char * c = (char*) malloc(100); 9 | char * d = (char*) malloc(100); 10 | char * e = (char*) malloc(100); 11 | char * f = (char*) malloc(100); 12 | char * g = (char*) malloc(100); 13 | char * h = (char*) malloc(100); 14 | char * i = (char*) malloc(100); 15 | char * j = (char*) malloc(100); 16 | char * k = (char*) malloc(100); 17 | char * l = (char*) malloc(100); 18 | char * m = (char*) malloc(100); 19 | char * n = (char*) malloc(100); 20 | char * o = (char*) malloc(100); 21 | char * p = (char*) malloc(100); 22 | char * q = (char*) malloc(100); 23 | 24 | free(q); 25 | free(p); 26 | free(o); 27 | free(n); 28 | free(m); 29 | 30 | a[120] = 2; /* BOOM */ 31 | 32 | free(l); 33 | free(k); 34 | free(j); 35 | free(i); 36 | free(h); 37 | 38 | g[-9] = 2; /* BOOM */ 39 | 40 | free(g); 41 | free(f); 42 | free(e); 43 | free(d); 44 | free(c); 45 | free(b); 46 | free(a); 47 | 48 | exit(0); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_09.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NUMBER_OF_RUNS 10000 5 | 6 | static char * strings_base[NUMBER_OF_RUNS], ** strings = strings_base; 7 | 8 | static void h(int r) 9 | { 10 | if(r<0) r = -r; 11 | *strings++ = (char*) malloc(r + 10); 12 | } 13 | 14 | static void g(int r) 15 | { 16 | int s; 17 | 18 | switch((s = (rand() % 10))) 19 | { 20 | default: 21 | case 0: h(r + s); break; 22 | case 1: h(r + s); break; 23 | case 2: h(r + s); break; 24 | case 3: h(r + s); break; 25 | case 4: h(r + s); break; 26 | case 5: h(r + s); break; 27 | case 6: h(r + s); break; 28 | case 7: h(r + s); break; 29 | case 8: h(r + s); break; 30 | case 9: h(r + s); break; 31 | } 32 | } 33 | 34 | static void f(int r) 35 | { 36 | int s; 37 | 38 | switch((s = (rand() % 10))) 39 | { 40 | default: 41 | case 0: g(r + s); break; 42 | case 1: g(r + s); break; 43 | case 2: g(r + s); break; 44 | case 3: g(r + s); break; 45 | case 4: g(r + s); break; 46 | case 5: g(r + s); break; 47 | case 6: g(r + s); break; 48 | case 7: f(r + s); break; 49 | case 8: g(r + s); break; 50 | case 9: g(r + s); break; 51 | } 52 | } 53 | 54 | int main() 55 | { 56 | int r, i; 57 | 58 | srand(47110815); 59 | 60 | printf(" allocating ....."); 61 | 62 | for(i=0; i 7 | 8 | int 9 | main() 10 | { 11 | char * a = (char*) malloc(100); 12 | a[-5]='0'; /* this is exactly in the second 13 | * word below `a' on 32 bit machines 14 | */ 15 | ccmalloc_check_for_integrity(); 16 | 17 | malloc(20); 18 | malloc(30); 19 | malloc(40); 20 | malloc(50); 21 | 22 | exit(0); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_11.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void * MALLOC(size_t n); 4 | 5 | int 6 | main() 7 | { 8 | void * v = MALLOC(15); 9 | free(v); 10 | 11 | v=malloc(18); 12 | free(v); 13 | 14 | exit(0); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_12.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | main() 6 | { 7 | char * s = (char*) malloc(15); 8 | FILE * file = fopen("/dev/null", "w"); 9 | free(s); 10 | fprintf(file, "hello world\n"); 11 | exit(0); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_15.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static const char * str = "this is a string"; 6 | 7 | int 8 | main() 9 | { 10 | char * s = strdup(str); 11 | s = strdup(s); 12 | free(s); 13 | 14 | exit(0); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_16.c: -------------------------------------------------------------------------------- 1 | /* Under SunOS and Solaris a double must be 8 Byte aligned. This means 2 | * we have to align all data to 8 Bytes :-( 3 | */ 4 | 5 | #include 6 | 7 | struct Test { double d; }; 8 | 9 | int main() 10 | { 11 | struct Test * test = (struct Test*) malloc(sizeof(struct Test)); 12 | test -> d = 0.0; 13 | free(test); 14 | 15 | exit(0); 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_17.c: -------------------------------------------------------------------------------- 1 | /* This is mainly a test for logpid 2 | */ 3 | 4 | #include 5 | #include 6 | 7 | #define NUM_PRG_TO_START 9 8 | 9 | int main(int argc, char ** argv) 10 | { 11 | int n; 12 | char buffer[20]; 13 | char * leak, * no_leak; 14 | 15 | if(argc == 1) 16 | { 17 | n = NUM_PRG_TO_START; 18 | printf(" started 0"); 19 | } 20 | else 21 | { 22 | n = atoi(argv[1]); 23 | printf("%d", NUM_PRG_TO_START - n); 24 | } 25 | 26 | fflush(stdout); 27 | 28 | leak = (char*) malloc(4711); 29 | no_leak = (char*) malloc(42); 30 | 31 | if(n > 0) 32 | { 33 | sprintf(buffer, "%s %d", argv[0], n - 1); 34 | system(buffer); 35 | } 36 | else printf("\n finished "); 37 | 38 | free(no_leak); 39 | 40 | printf("%d", n); 41 | if(n == NUM_PRG_TO_START) printf("\n"); 42 | fflush(stdout); 43 | 44 | exit(0); 45 | return 1; 46 | } 47 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_18.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int num() 4 | { 5 | int res; 6 | 7 | res = rand(); 8 | if(res < 0) res = -res; 9 | res %= 10; 10 | 11 | return res; 12 | } 13 | 14 | void i() 15 | { 16 | (void) malloc(10); 17 | } 18 | 19 | void j() 20 | { 21 | (void) malloc(11); 22 | } 23 | 24 | void h() 25 | { 26 | if(rand() % 2 == 0) i(); 27 | else j(); 28 | } 29 | 30 | void g() 31 | { 32 | switch(num()) 33 | { 34 | case 0: h(); break; 35 | case 1: i(); break; 36 | case 2: j(); break; 37 | case 3: h(); break; 38 | case 4: i(); break; 39 | case 5: j(); break; 40 | case 6: h(); break; 41 | case 7: i(); break; 42 | case 8: j(); break; 43 | default: h(); break; 44 | } 45 | } 46 | 47 | void f() 48 | { 49 | switch(num()) 50 | { 51 | case 0: g(); break; 52 | case 1: h(); break; 53 | case 2: i(); break; 54 | case 3: j(); break; 55 | case 4: g(); break; 56 | case 5: h(); break; 57 | case 6: i(); break; 58 | case 7: j(); break; 59 | case 8: g(); break; 60 | default: h(); break; 61 | } 62 | } 63 | 64 | int main() 65 | { 66 | int i; 67 | 68 | for(i=0; i<1000; i++) f(); 69 | 70 | exit(0); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /ccmalloc/test/test_C_19.c: -------------------------------------------------------------------------------- 1 | /* Test the new `read-dynlib-with-gdb' flag 2 | */ 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" 9 | #endif 10 | void oops(); 11 | 12 | int main() 13 | { 14 | char * a; 15 | 16 | a = (char*)malloc(13); 17 | free(a); 18 | a = strdup("oops"); /* if libc is compiled with `-g' this 19 | * should give you the strdup symbol 20 | */ 21 | oops(); 22 | 23 | exit(0); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ccmalloc/test/testall: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd `dirname $0` 4 | 5 | if [ ! -f test_C_02.c ]; then ln -s test_C_01.c test_C_02.c; fi 6 | if [ ! -f test_C_03.c ]; then ln -s test_C_01.c test_C_03.c; fi 7 | if [ ! -f test_C_13.c ]; then ln -s test_C_01.c test_C_13.c; fi 8 | if [ ! -f test_C_14.c ]; then ln -s test_C_01.c test_C_14.c; fi 9 | 10 | REMOVE_TEMPORARIES=1 11 | export REMOVE_TEMPORARIES 12 | 13 | os="`uname``uname -r`" 14 | case x"$os" in 15 | xSunOS4*) CTEST="01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18";; 16 | x*) CTEST="01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19";; 17 | esac 18 | 19 | CPPTEST="01 02" 20 | 21 | COMPILERS=`sed -e '/COMPILERS=/!d' -e 's,^COMPILERS=,,' ../Makefile` 22 | 23 | for CC in $COMPILERS 24 | do 25 | export CC 26 | 27 | for i in $CTEST 28 | do 29 | ./testone test_C_$i.c || exit 1 30 | done 31 | 32 | for i in $CPPTEST 33 | do 34 | ./testone test_C++_$i.cc || exit 1 35 | done 36 | done 37 | -------------------------------------------------------------------------------- /ccmalloc/test/testone: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ x"$LD_LIBRARY_PATH" = x ] 4 | then 5 | LD_LIBRARY_PATH=. 6 | else 7 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 8 | fi 9 | 10 | export LD_LIBRARY_PATH 11 | 12 | if [ ! "$CC" ] 13 | then 14 | echo "*** $0: no compiler specified in enviroment variable CC" 1>&2 15 | exit 1 16 | fi 17 | 18 | if [ "$CC" = CC ] 19 | then 20 | echo "*** $0: CC as linker is not supported yet" 1>&2 21 | echo "*** $0: (even compilation of test cases may fail)" 1>&2 22 | fi 23 | 24 | if test "x$1" = x 25 | then 26 | echo "*** $0: argument is missing" 1>&2 27 | exit 1 28 | fi 29 | 30 | if test ! -f "$1" 31 | then 32 | echo "*** $0: could not find $1" 1>&2 33 | exit 1 34 | fi 35 | 36 | base=`basename "$1" .c` 37 | if test ! "${base}.c" = "$1" 38 | then 39 | base=`basename "$1" .cc` 40 | if test ! "${base}.cc" = "$1" 41 | then 42 | echo "*** $0: could not recognize extension" 1>&2 43 | exit 1 44 | fi 45 | fi 46 | 47 | startupfile=`echo "$base" | sed -e 's,test,ccmalloc,'` 48 | if test ! -f "$startupfile" 49 | then 50 | echo "*** $0: could not find startup file $startupfile" 1>&2 51 | exit 1 52 | fi 53 | 54 | rm -f .ccmalloc 55 | cp $startupfile .ccmalloc 56 | ( echo '1,$s,^\(log.*\) test_,\1 '"${CC}_,";echo w; echo q ) | \ 57 | ed .ccmalloc 1>/dev/null 2>/dev/null 58 | 59 | target=${base}.exe 60 | 61 | # These object files may contain compiler dependent link information 62 | # 63 | case $base in 64 | test_C_19) rm -f lib_test_C_19.so lib_test_C_19.o;; 65 | test_C_11) rm -f lib_test_C_11.a lib_test_C_11.o;; 66 | esac 67 | 68 | echo "compiling" $1 " with $CC" 69 | make $target 1> /dev/null || exit 1 70 | 71 | if test ! "x$REMOVE_TEMPORARIES" = x 72 | then 73 | rm -f ${base}.o 74 | fi 75 | 76 | echo "running " $target 77 | ./execute $target 78 | 79 | if test ! "x$REMOVE_TEMPORARIES" = x 80 | then 81 | rm -f $target 82 | fi 83 | -------------------------------------------------------------------------------- /ccmalloc/util/install: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | src="$1" 3 | dst="$2" 4 | 5 | if [ ! "$src" ] 6 | then 7 | echo "*** $0: 1st argument is empty" 1>&2 8 | exit 1 9 | fi 10 | 11 | if [ ! "$dst" ] 12 | then 13 | echo "*** $0: 1st argument is empty" 1>&2 14 | exit 1 15 | fi 16 | 17 | if [ ! -f "$src" ] 18 | then 19 | echo "*** $0: 1st argument '$1' is no file" 1>&2 20 | exit 1 21 | fi 22 | 23 | case "$dst" in 24 | /*) 25 | ;; 26 | *) 27 | echo "*** $0: 2nd argument '$2' is not an absolute pathname" 2>&1 28 | exit 1 29 | ;; 30 | esac 31 | 32 | tmp=`echo "$dst" | sed -e 's,[ ],@,g'` 33 | if [ ! "$tmp" = $dst ] 34 | then 35 | echo "*** $0: 2nd argument contains white space characters" 2>&1 36 | exit 1 37 | fi 38 | 39 | parts=`echo "$dst" | sed -e 's,/[/]*, ,g'` 40 | src="`pwd`"/"$src" 41 | 42 | cd / 43 | 44 | if [ "$parts" ] 45 | then 46 | for p in $parts 47 | do 48 | [ -d $p ] || mkdir $p || exit 1 49 | cd $p || exit 1 50 | done 51 | fi 52 | 53 | cp $src $dst || exit 1 54 | 55 | exit 0 56 | -------------------------------------------------------------------------------- /doc/Linux应用程序内存错误自动化测试研究.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/Linux应用程序内存错误自动化测试研究.pdf -------------------------------------------------------------------------------- /doc/linux下内存泄漏的动态跟踪分析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/linux下内存泄漏的动态跟踪分析.pdf -------------------------------------------------------------------------------- /doc/一种内存泄漏检测技术的研究和实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/一种内存泄漏检测技术的研究和实现.pdf -------------------------------------------------------------------------------- /doc/一种有效的动态内存泄漏检测技术的研究与实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/一种有效的动态内存泄漏检测技术的研究与实现.pdf -------------------------------------------------------------------------------- /doc/内存泄漏检测工具与评估方法.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/内存泄漏检测工具与评估方法.pdf -------------------------------------------------------------------------------- /doc/基于C++的动态内存实时监测器①.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/基于C++的动态内存实时监测器①.pdf -------------------------------------------------------------------------------- /doc/嵌入式linux系统中的内存泄漏的研究.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/嵌入式linux系统中的内存泄漏的研究.pdf -------------------------------------------------------------------------------- /doc/嵌入式软件动态内存检测工具的研究与实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/嵌入式软件动态内存检测工具的研究与实现.pdf -------------------------------------------------------------------------------- /doc/用户态内存管理关键技术研究.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/doc/用户态内存管理关键技术研究.pdf -------------------------------------------------------------------------------- /malloc_hooks/The GNU C Library Hooks for Malloc.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/121786404/C_Memory/906001d3769a60a26447f7f2d3b3632cdebca756/malloc_hooks/The GNU C Library Hooks for Malloc.doc -------------------------------------------------------------------------------- /malloc_hooks/malloc_hooks.c: -------------------------------------------------------------------------------- 1 | /* malloc_hooks.c revision 8, 2012-03-15 by Stephen Kell */ 2 | /* See below for license. */ 3 | /* */ 4 | #ifndef _GNU_SOURCE 5 | #define _GNU_SOURCE 6 | #endif 7 | 8 | /* This file is a re-usable set of malloc hooks for glibc, intended to 9 | * enable easier creation of hooks. 10 | 11 | **** NOTE: this file has been superseded by libmallochooks! **** 12 | **** See . **** 13 | 14 | * It is based on the example hooks in the GNU C library manual, which are 15 | * Copyright (c) Free Software Foundation and released under the GNU Free 16 | * Documentation License. 17 | * 18 | * It provides the user with a more abstract selection of hook primitives. 19 | * These extensions were done by Stephen Kell , 20 | * and are released into the public domain. I have no idea how to license 21 | * this file as a whole, but I invite anyone wishing to use it to appropriately 22 | * respect the FSF copyright. 23 | * 24 | * Currently provided: 25 | * pre_alloc 26 | * post_successful_alloc 27 | * pre_nonnull_free 28 | * post_nonnull_free 29 | * pre_nonnull_nonzero_realloc 30 | * post_nonnull_nonzero_realloc 31 | * 32 | * Recommended usage of this file: 33 | * - #include it in a .c file; 34 | * - paste the signatures below into your C file, below the #include directives, 35 | * and provide a body for each one; 36 | * - compile! 37 | * 38 | * I left the printf statements in place from the example hooks, but commented 39 | * out, so it'll be easy to add your own debugging printouts if needed. 40 | * 41 | * It's fairly easy to link multiple sets of hooks by compiling and linking 42 | * this file multiple times. Each hook's __malloc_initialize_hook will look 43 | * for a weak symbol __malloc_previous_initialize_hook and call through that 44 | * if it's nonnull. You will need to do some symbol renaming though, probably 45 | * using objcopy, to correctly chain the initialization hooks. If anyone knows 46 | * a better way to do this, please let me know. 47 | * 48 | * TODO: 49 | * add missing post-instrumentation 50 | * allow post-instrumentation modification of returned values 51 | * some kind of thread-safety perhaps... 52 | */ 53 | 54 | #include 55 | /* Prototypes for __malloc_hook, __free_hook */ 56 | #include 57 | #include 58 | #include 59 | 60 | /* Prototypes for our hooks. */ 61 | static void my_init_hook (void); 62 | static void *my_malloc_hook (size_t, const void *); 63 | static void my_free_hook (void*, const void *); 64 | static void *my_memalign_hook (size_t alignment, size_t size, const void *caller); 65 | static void *my_realloc_hook(void *ptr, size_t size, const void *caller); 66 | 67 | /* Local variables to hold the next-in-chain hooks. */ 68 | static void *(*old_malloc_hook) (size_t, const void *); 69 | static void (*old_free_hook) (void*, const void *); 70 | static void *(*old_memalign_hook) (size_t alignment, size_t size, const void *caller); 71 | static void *(*old_realloc_hook)(void *ptr, size_t size, const void *caller); 72 | 73 | /* Declare the variables that point to the active hooks. This isn't necessary 74 | * on glibc... adding it here as a precursor to supporting more platforms. */ 75 | extern void *(*__malloc_hook) (size_t, const void *) __attribute__((weak)); 76 | extern void (*__free_hook) (void*, const void *) __attribute__((weak)); 77 | extern void *(*__memalign_hook) (size_t alignment, size_t size, const void *caller) __attribute__((weak)); 78 | extern void *(*__realloc_hook)(void *ptr, size_t size, const void *caller) __attribute__((weak)); 79 | 80 | /* Override initializing hook from the C library. */ 81 | void (*__malloc_initialize_hook) (void) = my_init_hook; 82 | extern void __prev_malloc_initialize_hook (void) __attribute__((weak)); /* NOT a pointer to it */ 83 | 84 | /* High-level hook prototypes */ 85 | static void init_hook(void); 86 | static void pre_alloc(size_t *p_size, const void *caller); 87 | static void post_successful_alloc(void *begin, size_t modified_size, const void *caller); 88 | static void pre_nonnull_free(void *ptr, size_t freed_usable_size); 89 | static void post_nonnull_free(void *ptr); 90 | static void pre_nonnull_nonzero_realloc(void *ptr, size_t size, const void *caller, void *__new); 91 | static void post_nonnull_nonzero_realloc(void *ptr, 92 | size_t modified_size, 93 | size_t old_usable_size, 94 | const void *caller, void *__new); 95 | 96 | static void 97 | my_init_hook (void) 98 | { 99 | if (__prev_malloc_initialize_hook) __prev_malloc_initialize_hook(); 100 | /* save old hooks */ 101 | old_malloc_hook = __malloc_hook; 102 | old_free_hook = __free_hook; 103 | old_memalign_hook = __memalign_hook; 104 | old_realloc_hook = __realloc_hook; 105 | /* do our initialization */ 106 | init_hook(); 107 | /* install our hooks */ 108 | __malloc_hook = my_malloc_hook; 109 | __free_hook = my_free_hook; 110 | __memalign_hook = my_memalign_hook; 111 | __realloc_hook = my_realloc_hook; 112 | } 113 | 114 | static void * 115 | my_malloc_hook (size_t size, const void *caller) 116 | { 117 | void *result; 118 | /* Restore all old hooks */ 119 | __malloc_hook = old_malloc_hook; 120 | __free_hook = old_free_hook; 121 | __memalign_hook = old_memalign_hook; 122 | __realloc_hook = old_realloc_hook; 123 | /* Call recursively */ 124 | #ifdef TRACE_MALLOC_HOOKS 125 | printf ("calling malloc (%u)\n", (unsigned int) size); 126 | #endif 127 | size_t modified_size = size; 128 | pre_alloc(&modified_size, caller); 129 | result = malloc (modified_size); 130 | if (result) post_successful_alloc(result, modified_size, caller); 131 | /* Save underlying hooks */ 132 | old_malloc_hook = __malloc_hook; 133 | old_free_hook = __free_hook; 134 | old_memalign_hook = __memalign_hook; 135 | old_realloc_hook = __realloc_hook; 136 | /* printf might call malloc, so protect it too. */ 137 | /* printf ("malloc (%u) returns %p (modified size: %zu)\n", 138 | (unsigned int) size, result, modified_size); */ 139 | /* Restore our own hooks */ 140 | __malloc_hook = my_malloc_hook; 141 | __free_hook = my_free_hook; 142 | __memalign_hook = my_memalign_hook; 143 | __realloc_hook = my_realloc_hook; 144 | return result; 145 | } 146 | 147 | static void 148 | my_free_hook (void *ptr, const void *caller) 149 | { 150 | /* Restore all old hooks */ 151 | __malloc_hook = old_malloc_hook; 152 | __free_hook = old_free_hook; 153 | __memalign_hook = old_memalign_hook; 154 | __realloc_hook = old_realloc_hook; 155 | /* Call recursively */ 156 | #ifdef TRACE_MALLOC_HOOKS 157 | if (ptr != NULL) printf ("freeing pointer %p\n", ptr); 158 | #endif 159 | if (ptr != NULL) pre_nonnull_free(ptr, malloc_usable_size(ptr)); 160 | free (ptr); 161 | if (ptr != NULL) post_nonnull_free(ptr); 162 | /* Save underlying hooks */ 163 | old_malloc_hook = __malloc_hook; 164 | old_free_hook = __free_hook; 165 | old_memalign_hook = __memalign_hook; 166 | old_realloc_hook = __realloc_hook; 167 | /* printf might call free, so protect it too. */ 168 | #ifdef TRACE_MALLOC_HOOKS 169 | printf ("freed pointer %p\n", ptr); 170 | #endif 171 | /* Restore our own hooks */ 172 | __malloc_hook = my_malloc_hook; 173 | __free_hook = my_free_hook; 174 | __memalign_hook = my_memalign_hook; 175 | __realloc_hook = my_realloc_hook; 176 | } 177 | 178 | static void * 179 | my_memalign_hook (size_t alignment, size_t size, const void *caller) 180 | { 181 | void *result; 182 | /* Restore all old hooks */ 183 | __malloc_hook = old_malloc_hook; 184 | __free_hook = old_free_hook; 185 | __memalign_hook = old_memalign_hook; 186 | __realloc_hook = old_realloc_hook; 187 | /* Call recursively */ 188 | size_t modified_size = size; 189 | pre_alloc(&modified_size, caller); 190 | result = memalign(alignment, modified_size); 191 | if (result) post_successful_alloc(result, modified_size, caller); 192 | /* Save underlying hooks */ 193 | old_malloc_hook = __malloc_hook; 194 | old_free_hook = __free_hook; 195 | old_memalign_hook = __memalign_hook; 196 | old_realloc_hook = __realloc_hook; 197 | /* printf might call free, so protect it too. */ 198 | #ifdef TRACE_MALLOC_HOOKS 199 | printf ("memalign (%u, %u) returns %p\n", (unsigned) alignment, (unsigned) size, result); 200 | #endif 201 | /* Restore our own hooks */ 202 | __malloc_hook = my_malloc_hook; 203 | __free_hook = my_free_hook; 204 | __memalign_hook = my_memalign_hook; 205 | __realloc_hook = my_realloc_hook; 206 | return result; 207 | } 208 | 209 | 210 | static void * 211 | my_realloc_hook(void *ptr, size_t size, const void *caller) 212 | { 213 | void *result; 214 | /* Restore all old hooks */ 215 | __malloc_hook = old_malloc_hook; 216 | __free_hook = old_free_hook; 217 | __memalign_hook = old_memalign_hook; 218 | __realloc_hook = old_realloc_hook; 219 | size_t old_usable_size; 220 | /* Split cases. First we eliminate the cases where 221 | * realloc() degenerates into either malloc or free. */ 222 | if (ptr == NULL) 223 | { 224 | /* We behave like malloc(). */ 225 | pre_alloc(&size, caller); 226 | } 227 | else if (size == 0) 228 | { 229 | /* We behave like free(). */ 230 | pre_nonnull_free(ptr, malloc_usable_size(ptr)); 231 | } 232 | else 233 | { 234 | /* We are doing a bone fide realloc. This might fail, leaving the 235 | * original block untouched. 236 | * If it changes, we'll need to know the old usable size to access 237 | * the old trailer. */ 238 | old_usable_size = malloc_usable_size(ptr); 239 | pre_nonnull_nonzero_realloc(ptr, size, caller, result); 240 | } 241 | 242 | /* Modify the size, as usual, *only if* size != 0 */ 243 | size_t modified_size = size; 244 | if (size != 0) 245 | { 246 | pre_alloc(&modified_size, caller); 247 | } 248 | 249 | result = realloc(ptr, modified_size); 250 | 251 | if (ptr == NULL) 252 | { 253 | /* like malloc() */ 254 | if (result) post_successful_alloc(result, modified_size, caller); 255 | } 256 | else if (size == 0) 257 | { 258 | /* like free */ 259 | post_nonnull_free(ptr); 260 | } 261 | else 262 | { 263 | /* bona fide realloc */ 264 | post_nonnull_nonzero_realloc(ptr, modified_size, old_usable_size, caller, result); 265 | } 266 | 267 | /* Save underlying hooks */ 268 | old_malloc_hook = __malloc_hook; 269 | old_free_hook = __free_hook; 270 | old_memalign_hook = __memalign_hook; 271 | old_realloc_hook = __realloc_hook; 272 | /* printf might call free, so protect it too. */ 273 | #ifdef TRACE_MALLOC_HOOKS 274 | printf ("realigned pointer %p to %p (requested size %u, modified size %u)\n", ptr, result, 275 | (unsigned) size, (unsigned) modified_size); 276 | #endif 277 | /* Restore our own hooks */ 278 | __malloc_hook = my_malloc_hook; 279 | __free_hook = my_free_hook; 280 | __memalign_hook = my_memalign_hook; 281 | __realloc_hook = my_realloc_hook; 282 | return result; 283 | } 284 | -------------------------------------------------------------------------------- /memwatch/FAQ: -------------------------------------------------------------------------------- 1 | Frequently Asked Questions for memwatch 2 | 3 | Q. I'm not getting any log file! What's wrong?? 4 | 5 | A. Did you define MEMWATCH when compiling all files? 6 | Did you include memwatch.h in all the files? 7 | If you did, then...: 8 | 9 | Memwatch creates the file when it initializes. If you're not 10 | getting the log file, it's because a) memwatch is not 11 | initializing or b) it's initializing, but can't create the 12 | file. 13 | 14 | Memwatch has two functions, mwInit() and mwTerm(), that 15 | initialize and terminate memwatch, respectively. They are 16 | nestable. You USUALLY don't need to call mwInit() and 17 | mwTerm(), since memwatch will auto-initialize on the first 18 | call to a memory function, and then add mwTerm() to the 19 | atexit() list. 20 | 21 | You can call mwInit() and mwTerm() manually, if it's not 22 | initializing properly or if your system doesn't support 23 | atexit(). Call mwInit() as soon as you can, and mwTerm() at 24 | the logical no-error ending of your program. Call mwAbort() 25 | if the program is stopping due to an error; this will 26 | terminate memwatch even if more than one call to mwTerm() is 27 | outstanding. 28 | 29 | If you are using C++, remember that global and static C++ 30 | objects constructors execute before main() when considering 31 | where to put mwInit(). Also, their destructors execute after 32 | main(). You may want to create a global object very early 33 | with mwInit() in the constructor and mwTerm() in the 34 | destructor. Too bad C++ does not guarantee initialization 35 | order for global objects. 36 | 37 | If this didn't help, try adding a call to mwDoFlush(1) after 38 | mwInit(). If THAT didn't help, then memwatch is unable to 39 | create the log file. Check write permissions. 40 | 41 | If you can't use a log file, you can still use memwatch by 42 | redirecting the output to a function of your choice. See the 43 | next question. 44 | 45 | Q. I'd like memwatch's output to pipe to my fave debugger! How? 46 | 47 | A. Call mwSetOutFunc() with the address of a "void func(int c)" 48 | function. You should also consider doing something about 49 | the ARI handler, see memwatch.h for more details about that. 50 | 51 | Q. Why isn't there any C++ support? 52 | 53 | A. Because C++ is for sissies! =) Just kidding. 54 | C++ comes with overridable allocation/deallocation 55 | built-in. You can define your own new/delete operators 56 | for any class, and thus circumvent memwatch, or confuse 57 | it to no end. Also, the keywords "new" and "delete" may 58 | appear in declarations in C++, making the preprocessor 59 | replacement approach shaky. You can do it, but it's not 60 | very stable. 61 | 62 | If someone were to write a rock solid new/delete checker 63 | for C++, there is no conflict with memwatch; use them both. 64 | 65 | Q. I'm getting "WILD free" errors, but the code is bug-free! 66 | 67 | A. If memwatch's free() recieves a pointer that wasn't allocated 68 | by memwatch, a "WILD free" message appears. If the source of 69 | the memory buffer is outside of memwatch (a non-standard 70 | library function, for instance), you can use mwFree_() to 71 | release it. mwFree_() calls free() on the pointer given if 72 | memwatch can't recognize it, instead of blocking it. 73 | 74 | Another source of "WILD free" messages is that if memwatch 75 | is terminated before all memory allocated is freed, memwatch 76 | will have forgotten about it, and thus generate the errors. 77 | This is commonly caused by having memwatch auto-initialize, 78 | and then using atexit() to clean up. When auto-initializing, 79 | memwatch registers mwTerm() with atexit(), but if mwTerm() 80 | runs before all memory is freed, then you will get "unfreed" 81 | and "WILD free" messages when your own atexit()-registered 82 | cleanup code runs, and frees the memory. 83 | 84 | Q. I'm getting "unfreed" errors, but the code is bug-free! 85 | 86 | A. You can get erroneous "unfreed" messages if memwatch 87 | terminates before all memory has been freed. Try using 88 | mwInit() and mwTerm() instead of auto-initialization. 89 | 90 | If you _are_ using mwInit() and mwTerm(), it may be that 91 | some code in your program executes before mwInit() or 92 | after mwTerm(). Make sure that mwInit() is the first thing 93 | executed, and mwTerm() the last. 94 | 95 | Q. When compiling memwatch I get these 'might get clobbered' 96 | errors, and something about a longjmp() inside memwatch. 97 | 98 | A. When using gcc or egcs with the optimization to inline 99 | functions, this warning occurs. This is because gcc and 100 | egcs inlines memwatch's functions with setjmp/longjmp, 101 | causing the calling functions to become unstable. 102 | 103 | The gcc/egcs maintainers have been informed of this 104 | problem, but until they modify the inline optimization 105 | so that it leaves setjmp functions alone, make sure to 106 | compile memwatch without inline function optimizations. 107 | 108 | gcc 2.95.2 can be patched for this, and I have been told 109 | it will be fixed in an upcoming version. 110 | 111 | Q. My program crashes with SIGSEGV or alignment errors, but 112 | only when I compile with memwatch enabled! 113 | 114 | A. You are using a 64-bit (or higher) platform, and memwatch 115 | was unable to detect and adjust for this. You'll have to 116 | either compile with a suitable define for mwROUNDALLOC, 117 | I suggest (number of bits / 8), or define mwROUNDALLOC 118 | directly in memwatch.c. 119 | 120 | Also, please check your limits.h file for the relevant 121 | #defines, and tell me what they are. 122 | 123 | Q. When I include string.h after memwatch.h, I get errors 124 | related to strdup(), what gives? 125 | 126 | A. Most, but probably not all, platforms are nice about 127 | including files multiple times, so I could probably 128 | avoid these errors by including string.h from memwatch.h. 129 | But since I want to be on the safe side, I don't. 130 | 131 | To fix this, simply include string.h before memwatch.h, 132 | or modify memwatch.h to include string.h. 133 | 134 | -------------------------------------------------------------------------------- /memwatch/Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | $(CC) -DMEMWATCH -DMW_STDIO test.c memwatch.c 3 | -------------------------------------------------------------------------------- /memwatch/README: -------------------------------------------------------------------------------- 1 | README for MEMWATCH 2.69 2 | 3 | This file should be enough to get you started, and should be 4 | enough for small projects. For more info, see the files USING 5 | and the FAQ. If this is not enough, see memwatch.h, which is 6 | well documented. 7 | 8 | Memwatch is licensed under the GPL from version 2.69 9 | onwards. Please read the file gpl.txt for more details. 10 | 11 | If you choose to use memwatch to validate your projects, I 12 | would like to hear about it. Please drop me a line at 13 | johan@linkdata.se about the project itself, the hardware, 14 | operating system, compiler and any URL(s) you feel is 15 | appropriate. 16 | 17 | ***** To run the test program: 18 | 19 | Look at the source code for test.c first. It does some really 20 | nasty things, and I want you to be aware of that. If memwatch 21 | can't capture SIGSEGV (General Protection Fault for Windoze), 22 | your program will dump core (crash for Windoze). 23 | 24 | Once you've done that, you can build the test program. 25 | 26 | Linux and other *nixes with gcc: 27 | 28 | gcc -o test -DMEMWATCH -DMEMWATCH_STDIO test.c memwatch.c 29 | 30 | Windows 95, Windows NT with MS Visual C++: 31 | 32 | cl -DMEMWATCH -DMEMWATCH_STDIO test.c memwatch.c 33 | 34 | Then simply run the test program. 35 | 36 | ./test 37 | 38 | 39 | ***** Quick-start instructions: 40 | 41 | 1. Make sure that memwatch.h is included in all of the 42 | source code files. If you have an include file that 43 | all of the source code uses, you might be able to include 44 | memwatch.h from there. 45 | 46 | 2. Recompile the program with MEMWATCH defined. See your 47 | compiler's documentation if you don't know how to do this. 48 | The usual switch looks like "-DMEMWATCH". To have MEMWATCH 49 | use stderr for some output (like, "Abort, Retry, Ignore?"), 50 | please also define MW_STDIO (or MEMWATCH_STDIO, same thing). 51 | 52 | 3. Run the program and examine the output in the 53 | log file "memwatch.log". If you didn't get a log file, 54 | you probably didn't do step 1 and 2 correctly, or your 55 | program crashed before memwatch flushed the file buffer. 56 | To have memwatch _always_ flush the buffer, add a call 57 | to "mwDoFlush(1)" at the top of your main function. 58 | 59 | 4. There is no fourth step... but remember that there 60 | are limits to what memwatch can do, and that you need 61 | to be aware of them: 62 | 63 | ***** Limits to memwatch: 64 | 65 | Memwatch cannot catch all wild pointer writes. It can catch 66 | those it could make itself due to your program trashing 67 | memwatch's internal data structures. It can catch, sort of, 68 | wild writes into No Mans Land buffers (see the header file for 69 | more info). Anything else and you're going to get core dumped, 70 | or data corruption if you're lucky. 71 | 72 | There are other limits of course, but that one is the most 73 | serious one, and the one that you're likely to be suffering 74 | from. 75 | 76 | ***** Can use memwatch with XXXXX? 77 | 78 | Probably the answer is yes. It's been tested with several 79 | different platforms and compilers. It may not work on yours 80 | though... but there's only one way to find out. 81 | 82 | ***** Need more assistance? 83 | 84 | I don't want e-mail on "how to program in C", or "I've got a 85 | bug, help me". I _do_ want you to send email to me if you 86 | find a bug in memwatch, or if it won't compile cleanly on your 87 | system (assuming it's an ANSI-C compiler of course). 88 | 89 | If you need help with using memwatch, read the header file. 90 | If, after reading the header file, you still can't resolve the 91 | problem, please mail me with the details. 92 | 93 | I can be reached at "johan@linkdata.se". 94 | 95 | The latest version of memwatch should be found at 96 | "http://www.linkdata.se/". 97 | 98 | Johan Lindh 99 | 100 | -------------------------------------------------------------------------------- /memwatch/USING: -------------------------------------------------------------------------------- 1 | Using memwatch 2 | ============== 3 | 4 | What is it? 5 | 6 | Memwatch is primarily a memory leak detector for C. Besides 7 | detecting leaks, it can do a bunch of other stuff, but lets 8 | stay to the basics. If you _really_ want to know all the 9 | gory details, you should check out the header file, 10 | memwatch.h, and the source code. It's actually got some 11 | comments! (Whoa, what a concept!) 12 | 13 | How do I get the latest version? 14 | 15 | http://www.linkdata.se/sourcecode.html 16 | ftp://ftp.linkdata.se/pub/memwatch/ 17 | 18 | How does it work? 19 | 20 | Using the C preprocessor, memwatch replaces all your 21 | programs calls to ANSI C memory allocation functions with 22 | calls to it's own functions, which keeps a record of all 23 | allocations. 24 | 25 | Memwatch is very unobtrusive; unless the define MEMWATCH is 26 | defined, memwatch removes all traces of itself from the 27 | code (using the preprocessor). 28 | 29 | Memwatch normally writes it's data to the file 30 | memwatch.log, but this can be overridden; see the section 31 | on I/O, later. 32 | 33 | Can I use it for my C++ sources? 34 | 35 | You can, but it's not recommended. C++ allows individual 36 | classes to have their own memory management, and the 37 | preprocessor approach used by memwatch can cause havoc 38 | with such class declarations if improperly used. 39 | 40 | If you have no such classes, or have them but still want 41 | to test it, you can give it a try. 42 | 43 | First, re-enable the C++ support code in memwatch. 44 | If you can't find it, you probably shouldn't be using 45 | it. Then, in your source code, after including ALL 46 | header files: 47 | 48 | #define new mwNew 49 | #define delete mwDelete 50 | 51 | This will cause calls to new and delete in that source file 52 | to be directed to memwatch. Also, be sure to read all the 53 | text in memwatch.h regarding C++ support. 54 | 55 | Is this stuff thread-safe? 56 | 57 | I doubt it. As of version 2.66, there is rudimentary support 58 | for threads, if you happen to be using Win32 or if you have 59 | pthreads. Define WIN32 or MW_PTHREADS to signify this fact. 60 | 61 | This will cause a global mutex to be created, and memwatch 62 | will lock it when accessing the global memory chain, but it's 63 | still far from certified threadsafe. 64 | 65 | Initialization and cleanup 66 | 67 | In order to do it's work in a timely fashion, memwatch 68 | needs to do some startup and cleanup work. mwInit() 69 | initializes memwatch and mwTerm() terminates it. Memwatch 70 | can auto-initialize, and will do so if you don't call 71 | mwInit() yourself. If this is the case, memwatch will use 72 | atexit() to register mwTerm() to the atexit-queue. 73 | 74 | The auto-init technique has a caveat; if you are using 75 | atexit() yourself to do cleanup work, memwatch may 76 | terminate before your program is done. To be on the safe 77 | side, use mwInit() and mwTerm(). 78 | 79 | mwInit() and mwTerm() is nestable, so you can call mwInit() 80 | several times, requiring mwTerm() to be called an equal 81 | number of times to terminate memwatch. 82 | 83 | In case of the program aborting in a controlled way, you 84 | may want to call mwAbort() instead of mwTerm(). mwAbort() 85 | will terminate memwatch even if there are outstanding calls 86 | to mwTerm(). 87 | 88 | I/O operations 89 | 90 | During normal operations, memwatch creates a file named 91 | memwatch.log. Sometimes, memwatch.log can't be created; 92 | then memwatch tries to create files name memwatNN.log, 93 | where NN is between 01 and 99. If that fails, no log will 94 | be produced. 95 | 96 | If you can't use a file log, or don't want to, no worry. 97 | Just call mwSetOutFunc() with the address of a "void 98 | func(int c)" function, and all output will be directed 99 | there, character by character. 100 | 101 | Memwatch also has an Abort/Retry/Ignore handler that is 102 | used when an ASSERT or VERIFY fails. The default handler 103 | does no I/O, but automatically aborts the program. You can 104 | use any handler you want; just send the address of a "int 105 | func(const char*)" to mwSetAriFunc(). For more details on 106 | that, see memwatch.h. 107 | 108 | TRACE/ASSERT/VERIFY macros 109 | 110 | Memwatch defines (if not already defined) the macros TRACE, 111 | ASSERT and VERIFY. If you are already using macros with 112 | these names, memwatch 2.61 and later will not override 113 | them. Memwatch 2.61 and later will also always define the 114 | macros mwTRACE, mwASSERT and mwVERIFY, so you can use these 115 | to make sure you're talking to memwatch. Versions prior 116 | to 2.61 will *OVERRIDE* existing TRACE, ASSERT and VERIFY. 117 | 118 | To make sure that existing TRACE, ASSERT and VERIFY macros 119 | are preserved, you can define MW_NOTRACE, MW_NOASSERT and 120 | MW_NOVERIFY. All versions of memwatch will abide by these. 121 | 122 | How slow can you go? 123 | 124 | Memwatch slows things down. Large allocations aren't 125 | affected so that you can measure it, but small allocations 126 | that would utilize a compilers small-allocator function 127 | suddenly cannot, and so gets slowed down alot. As a worst 128 | case, expect it to be 3-5 times slower. 129 | 130 | Free'ing gets hit worse, I'm afraid, as memwatch checks 131 | a lot of stuff when freeing. Expect it to be 5-7 times 132 | slower, no matter what the size of the allocation. 133 | 134 | Stress-testing the application 135 | 136 | You can simulate low-memory conditions using mwLimit(). 137 | mwLimit() takes the maximum number of bytes to be 138 | allocated; when the limit is hit, allocation requests will 139 | fail, and a "limit" message will be logged. 140 | 141 | If you hit a real low-memory situation, memwatch logs that 142 | too. Memwatch itself has some reserve memory tucked away so 143 | it should continue running even in the worst conditions. 144 | 145 | Hunting down wild writes and other Nasty Things 146 | 147 | Wild writes are usually caused by using pointers that arent 148 | initialized, or that were initialized, but then the memory 149 | they points to is moved or freed. The best way to avoid 150 | these kind of problems is to ALWAYS initialize pointers to 151 | NULL, and after freeing a memory buffer, setting all 152 | pointers that pointed to it to NULL. 153 | 154 | To aid in tracking down uninitialized pointers memwatch 155 | zaps all memory with certain values. Recently allocated 156 | memory (unless calloc'd, of course), contains 0xFE. 157 | Recently freed memory contains 0xFD. So if your program 158 | crashes when using memwatch and not without memwatch, it's 159 | most likely because you are not initializing your allocated 160 | buffers, or using the buffers after they've been freed. 161 | 162 | In the event that a wild pointer should damage memwatch's 163 | internal data structures, memwatch employs checksums, 164 | multiple copies of some values, and can also repair it's 165 | own data structures. 166 | 167 | If you are a paranoid person, and as programmer you should 168 | be, you can use memwatch's mwIsReadAddr() and 169 | mwIsSafeAddr() functions to check the accessibility of 170 | memory. These are implemented for both ANSI C systems and 171 | Win32 systems. Just put an mwASSERT() around the check and 172 | forget about it. 173 | 174 | Can I help? 175 | 176 | Well, sure. For instance, I like memwatch to compile 177 | without any warnings or errors. If you are using an ANSI C 178 | compliant compiler, and are getting warnings or errors, 179 | please mail me the details and instructions on how to fix 180 | them, if you can. 181 | 182 | Another thing you can do if you decide to use memwatch is 183 | to mail me the name of the project(s) (and URL, if any), 184 | hardware and operating system, compiler and what user 185 | (organization). I will then post this info on the list of 186 | memwatch users. 187 | (http://www.linkdata.se/memwatchusers.html) 188 | 189 | Top five problems using memwatch 190 | 191 | 5. Passed a non-memwatch allocated pointer to memwatch's 192 | free(). Symtom: Causes an erroneous "WILD free" log 193 | entry to appear. Cure: Either include memwatch.h for 194 | the file that allocates, or use mwFree_() to free it. 195 | 196 | 4. Relied on auto-initialization when using atexit(). 197 | Symptom: Causes incorrect "unfreed" and "WILD free" 198 | messages. Cure: Use mwInit() and mwTerm(). 199 | 200 | 3. Forgot to include memwatch.h in all files. Symptom: 201 | Tends to generate "WILD free" and "unfreed" messages. 202 | Cure: Make sure to include memwatch.h! 203 | 204 | 2. No write permissions in currect directory. Symptom: 205 | Seems like memwatch 'just aint working'. Cure: Use 206 | mwSetOutFunc() to redirect output. 207 | 208 | ...and the number one problem is... 209 | 210 | 1. Didn't define MEMWATCH when compiling. Symptom: 211 | Memwatch dutifully disables itself. Cure: Try adding 212 | -DMEMWATCH to the command line. 213 | 214 | -------------------------------------------------------------------------------- /memwatch/gpl.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /memwatch/memwatch.lsm: -------------------------------------------------------------------------------- 1 | Begin3 2 | Title: memwatch 3 | Version: 2.71 4 | Entered-date: 2002-09-18 5 | Description: fault tolerant ANSI-C source code memory leak and corruption detection 6 | Keywords: memwatch debugging library memory leak source code ansi c 7 | Author: johan@linkdata.se 8 | Maintained-by: johan@linkdata.se 9 | Primary-site: ftp.linkdata.se /pub/memwatch 10 | 42K memwatch-2.71.tar.gz 11 | Alternate-site: 12 | Original-site: ftp.linkdata.se /pub/memwatch 13 | Platforms: all 14 | Copying-policy: GPL 15 | End 16 | -------------------------------------------------------------------------------- /memwatch/test.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | ** NOTE: Running this program in a Win32 or Unix environment 4 | ** will probably result in a segmentation fault or protection 5 | ** error. These errors may be caused by MEMWATCH when it is 6 | ** looking at memory to see if it owns it, or may be caused by 7 | ** the test program writing to memory it does not own. 8 | ** 9 | ** MEMWATCH has two functions called 'mwIsReadAddr()' and 10 | ** 'mwIsSafeAddr()', which are system-specific. 11 | ** If they are implemented for your system, and works 12 | ** correctly, MEMWATCH will identify garbage pointers and 13 | ** avoid causing segmentation faults, GP's etc. 14 | ** 15 | ** If they are NOT implemented, count on getting the core 16 | ** dumped when running this test program! As of this writing, 17 | ** the safe-address checking has been implemented for Win32 18 | ** and ANSI-C compliant systems. The ANSI-C checking traps 19 | ** SIGSEGV and uses setjmp/longjmp to resume processing. 20 | ** 21 | ** Note for Win95 users: The Win32 IsBadReadPtr() and its 22 | ** similar functions can return incorrect values. This has 23 | ** not happened under WinNT, though, just Win95. 24 | ** 25 | ** 991009 Johan Lindh 26 | ** 27 | */ 28 | 29 | #include 30 | #include 31 | #include "memwatch.h" 32 | 33 | #ifndef SIGSEGV 34 | #error "SIGNAL.H does not define SIGSEGV; running this program WILL cause a core dump/crash!" 35 | #endif 36 | 37 | #ifndef MEMWATCH 38 | #error "You really, really don't want to run this without memwatch. Trust me." 39 | #endif 40 | 41 | #if !defined(MW_STDIO) && !defined(MEMWATCH_STDIO) 42 | #error "Define MW_STDIO and try again, please." 43 | #endif 44 | 45 | int main() 46 | { 47 | char *p; 48 | 49 | /* Collect stats on a line number basis */ 50 | mwStatistics( 2 ); 51 | 52 | /* Slows things down, but OK for this test prg */ 53 | /* mwAutoCheck( 1 ); */ 54 | 55 | TRACE("Hello world!\n"); 56 | 57 | p = malloc(210); 58 | free(p); 59 | p = malloc(20); 60 | p = malloc(200); /* causes unfreed error */ 61 | p[-1] = 0; /* causes underflow error */ 62 | free(p); 63 | 64 | p = malloc(100); 65 | p[ -(int)(sizeof(long)*8) ] = -1; /* try to damage MW's heap chain */ 66 | free( p ); /* should cause relink */ 67 | 68 | mwSetAriFunc( mwAriHandler ); 69 | ASSERT(1==2); 70 | 71 | mwLimit(1000000); 72 | mwNoMansLand( MW_NML_ALL ); 73 | 74 | /* These may cause a general protection fault (segmentation fault) */ 75 | /* They're here to help test the no-mans-land protection */ 76 | if( mwIsSafeAddr(p+50000,1) ) { 77 | TRACE("Killing byte at %p\n", p+50000); 78 | *(p+50000) = 0; 79 | } 80 | if( mwIsSafeAddr(p+30000,1) ) { 81 | TRACE("Killing byte at %p\n", p+30000); 82 | *(p+30000) = 0; 83 | } 84 | if( mwIsSafeAddr(p+1000,1) ) { 85 | TRACE("Killing byte at %p\n", p+1000); 86 | *(p+1000) = 0; 87 | } 88 | if( mwIsSafeAddr(p-100,1) ) { 89 | TRACE("Killing byte at %p\n", p-100); 90 | *(p-100) = 0; 91 | } 92 | 93 | /* This may cause a GP fault as well, since MW data buffers */ 94 | /* have been damaged in the above killing spree */ 95 | CHECK(); 96 | 97 | p = malloc(12000); 98 | p[-5] = 1; 99 | p[-10] = 2; 100 | p[-15] = 3; 101 | p[-20] = 4; 102 | 103 | /* This may cause a GP fault since MW's buffer list may have */ 104 | /* been damaged by above killing, and it will try to repair it. */ 105 | free(p); 106 | 107 | p = realloc(p,10); /* causes realloc: free'd from error */ 108 | 109 | /* May cause GP since MW will inspect the memory to see if it owns it. */ 110 | free( (void*)main ); 111 | 112 | return 0; 113 | } 114 | 115 | /* Comment out the following line to compile. */ 116 | #error "Hey! Don't just compile this program, read the comments first!" 117 | --------------------------------------------------------------------------------