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 |
|
---|
33 | int _malloc_nwatch;
|
---|
34 | static PTR_T _malloc_watch_list[WATCH_MAX];
|
---|
35 |
|
---|
36 | static void
|
---|
37 | watch_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 |
|
---|
62 | void
|
---|
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 |
|
---|
82 | PTR_T
|
---|
83 | malloc_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. */
|
---|
118 | PTR_T
|
---|
119 | malloc_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 | }
|
---|