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