diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 18:33:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 18:33:23 +0000 |
commit | 1d5cace9db9aef76f26b2d7ba54bbb76443b00b2 (patch) | |
tree | 314a15dd1aa103da13bdc83ba1d2105a290bc5ba /lib/malloc/watch.c | |
parent | Initial commit. (diff) | |
download | bash-upstream.tar.xz bash-upstream.zip |
Adding upstream version 5.0.upstream/5.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/malloc/watch.c')
-rw-r--r-- | lib/malloc/watch.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/malloc/watch.c b/lib/malloc/watch.c new file mode 100644 index 0000000..00c8a82 --- /dev/null +++ b/lib/malloc/watch.c @@ -0,0 +1,151 @@ +/* watch.c - watchpoint functions for malloc */ + +/* Copyright (C) 2001-2003 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> + +#include "imalloc.h" + +#ifdef MALLOC_WATCH +#include "watch.h" + +#define WATCH_MAX 32 + +int _malloc_nwatch; +static PTR_T _malloc_watch_list[WATCH_MAX]; + +static void +watch_warn (addr, file, line, type, data) + PTR_T addr; + const char *file; + int line, type; + unsigned long data; +{ + char *tag; + + if (type == W_ALLOC) + tag = "allocated"; + else if (type == W_FREE) + tag = "freed"; + else if (type == W_REALLOC) + tag = "requesting resize"; + else if (type == W_RESIZED) + tag = "just resized"; + else + tag = "bug: unknown operation"; + + fprintf (stderr, "malloc: watch alert: %p %s ", addr, tag); + if (data != (unsigned long)-1) + fprintf (stderr, "(size %lu) ", data); + fprintf (stderr, "from '%s:%d'\n", file ? file : "unknown", line); +} + +void +_malloc_ckwatch (addr, file, line, type, data) + PTR_T addr; + const char *file; + int line, type; + unsigned long data; +{ + register int i; + + for (i = _malloc_nwatch - 1; i >= 0; i--) + { + if (_malloc_watch_list[i] == addr) + { + watch_warn (addr, file, line, type, data); + return; + } + } +} +#endif /* MALLOC_WATCH */ + +PTR_T +malloc_watch (addr) + PTR_T addr; +{ + register int i; + PTR_T ret; + + if (addr == 0) + return addr; + ret = (PTR_T)0; + +#ifdef MALLOC_WATCH + for (i = _malloc_nwatch - 1; i >= 0; i--) + { + if (_malloc_watch_list[i] == addr) + break; + } + if (i < 0) + { + if (_malloc_nwatch == WATCH_MAX) /* full, take out first */ + { + ret = _malloc_watch_list[0]; + _malloc_nwatch--; + for (i = 0; i < _malloc_nwatch; i++) + _malloc_watch_list[i] = _malloc_watch_list[i+1]; + } + _malloc_watch_list[_malloc_nwatch++] = addr; + } +#endif + + return ret; +} + +/* Remove a watchpoint set on ADDR. If ADDR is NULL, remove all + watchpoints. Returns ADDR if everything went OK, NULL if ADDR was + not being watched. */ +PTR_T +malloc_unwatch (addr) + PTR_T addr; +{ +#ifdef MALLOC_WATCH + register int i; + + if (addr == 0) + { + for (i = 0; i < _malloc_nwatch; i++) + _malloc_watch_list[i] = (PTR_T)0; + _malloc_nwatch = 0; + return ((PTR_T)0); + } + else + { + for (i = 0; i < _malloc_nwatch; i++) + { + if (_malloc_watch_list[i] == addr) + break; + } + if (i == _malloc_nwatch) + return ((PTR_T)0); /* not found */ + /* shuffle everything from i+1 to end down 1 */ + _malloc_nwatch--; + for ( ; i < _malloc_nwatch; i++) + _malloc_watch_list[i] = _malloc_watch_list[i+1]; + return addr; + } +#else + return ((PTR_T)0); +#endif +} |