1/* watch.c - watchpoint functions for malloc */ 2 3/* Copyright (C) 2001-2003 Free Software Foundation, Inc. 4 5 This file is part of GNU Bash, the Bourne Again SHell. 6 7 Bash is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 2, or (at your option) any later 10 version. 11 12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with Bash; see the file COPYING. If not, write to the Free Software 19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 20#ifdef HAVE_CONFIG_H 21# include <config.h> 22#endif 23 24#include <stdio.h> 25 26#include "imalloc.h" 27 28#ifdef MALLOC_WATCH 29#include "watch.h" 30 31#define WATCH_MAX 32 32 33int _malloc_nwatch; 34static PTR_T _malloc_watch_list[WATCH_MAX]; 35 36static void 37watch_warn (addr, file, line, type, data) 38 PTR_T addr; 39 const char *file; 40 int line, type; 41 unsigned long data; 42{ 43 char *tag; 44 45 if (type == W_ALLOC) 46 tag = _("allocated"); 47 else if (type == W_FREE) 48 tag = _("freed"); 49 else if (type == W_REALLOC) 50 tag = _("requesting resize"); 51 else if (type == W_RESIZED) 52 tag = _("just resized"); 53 else 54 tag = _("bug: unknown operation"); 55 56 fprintf (stderr, _("malloc: watch alert: %p %s "), addr, tag); 57 if (data != (unsigned long)-1) 58 fprintf (stderr, "(size %lu) ", data); 59 fprintf (stderr, "from '%s:%d'\n", file ? file : "unknown", line); 60} 61 62void 63_malloc_ckwatch (addr, file, line, type, data) 64 PTR_T addr; 65 const char *file; 66 int line, type; 67 unsigned long data; 68{ 69 register int i; 70 71 for (i = _malloc_nwatch - 1; i >= 0; i--) 72 { 73 if (_malloc_watch_list[i] == addr) 74 { 75 watch_warn (addr, file, line, type, data); 76 return; 77 } 78 } 79} 80#endif /* MALLOC_WATCH */ 81 82PTR_T 83malloc_watch (addr) 84 PTR_T addr; 85{ 86 register int i; 87 PTR_T ret; 88 89 if (addr == 0) 90 return addr; 91 ret = (PTR_T)0; 92 93#ifdef MALLOC_WATCH 94 for (i = _malloc_nwatch - 1; i >= 0; i--) 95 { 96 if (_malloc_watch_list[i] == addr) 97 break; 98 } 99 if (i < 0) 100 { 101 if (_malloc_nwatch == WATCH_MAX) /* full, take out first */ 102 { 103 ret = _malloc_watch_list[0]; 104 _malloc_nwatch--; 105 for (i = 0; i < _malloc_nwatch; i++) 106 _malloc_watch_list[i] = _malloc_watch_list[i+1]; 107 } 108 _malloc_watch_list[_malloc_nwatch++] = addr; 109 } 110#endif 111 112 return ret; 113} 114 115/* Remove a watchpoint set on ADDR. If ADDR is NULL, remove all 116 watchpoints. Returns ADDR if everything went OK, NULL if ADDR was 117 not being watched. */ 118PTR_T 119malloc_unwatch (addr) 120 PTR_T addr; 121{ 122#ifdef MALLOC_WATCH 123 register int i; 124 125 if (addr == 0) 126 { 127 for (i = 0; i < _malloc_nwatch; i++) 128 _malloc_watch_list[i] = (PTR_T)0; 129 _malloc_nwatch = 0; 130 return ((PTR_T)0); 131 } 132 else 133 { 134 for (i = 0; i < _malloc_nwatch; i++) 135 { 136 if (_malloc_watch_list[i] == addr) 137 break; 138 } 139 if (i == _malloc_nwatch) 140 return ((PTR_T)0); /* not found */ 141 /* shuffle everything from i+1 to end down 1 */ 142 _malloc_nwatch--; 143 for ( ; i < _malloc_nwatch; i++) 144 _malloc_watch_list[i] = _malloc_watch_list[i+1]; 145 return addr; 146 } 147#else 148 return ((PTR_T)0); 149#endif 150} 151