summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko2009-04-08 11:48:57 +0000
committerDenis Vlasenko2009-04-08 11:48:57 +0000
commitc73b70c7013aa98a86653ad7e7d15bcca16622f2 (patch)
tree2f2534d588201af85d09335848cef63e93cc83c1 /shell/hush.c
parent3dfb035d8df33e59492e78a97bf42e961ba178e4 (diff)
downloadbusybox-c73b70c7013aa98a86653ad7e7d15bcca16622f2.zip
busybox-c73b70c7013aa98a86653ad7e7d15bcca16622f2.tar.gz
hush: add leak detector helper; fix/add tests for it
function old new delta builtin_memleak - 92 +92 bltins 288 300 +12
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 5594aae..6075f51 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -117,7 +117,10 @@
#define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
#endif
-/* Keep unconditionally on for now */
+/* Enable/disable sanity checks. Ok to enable in production,
+ * only adds a bit of bloat.
+ * Keeping unconditionally on for now.
+ */
#define HUSH_DEBUG 1
/* In progress... */
#define ENABLE_HUSH_FUNCTIONS 0
@@ -524,6 +527,9 @@ struct globals {
char **traps; /* char *traps[NSIG] */
sigset_t blocked_set;
sigset_t inherited_set;
+#if HUSH_DEBUG
+ unsigned long memleak_value;
+#endif
char user_input_buf[ENABLE_FEATURE_EDITING ? BUFSIZ : 2];
#if ENABLE_FEATURE_SH_STANDALONE
struct nofork_save_area nofork_save;
@@ -555,14 +561,17 @@ static int builtin_jobs(char **argv);
#if ENABLE_HUSH_HELP
static int builtin_help(char **argv);
#endif
+#if HUSH_DEBUG
+static int builtin_memleak(char **argv);
+#endif
static int builtin_pwd(char **argv);
static int builtin_read(char **argv);
-static int builtin_test(char **argv);
-static int builtin_trap(char **argv);
-static int builtin_true(char **argv);
static int builtin_set(char **argv);
static int builtin_shift(char **argv);
static int builtin_source(char **argv);
+static int builtin_test(char **argv);
+static int builtin_trap(char **argv);
+static int builtin_true(char **argv);
static int builtin_umask(char **argv);
static int builtin_unset(char **argv);
static int builtin_wait(char **argv);
@@ -618,6 +627,9 @@ static const struct built_in_command bltins[] = {
#if ENABLE_HUSH_JOB
BLTIN("jobs" , builtin_jobs , "List active jobs"),
#endif
+#if HUSH_DEBUG
+ BLTIN("memleak" , builtin_memleak , "Debug tool"),
+#endif
BLTIN("pwd" , builtin_pwd , "Print current directory"),
BLTIN("read" , builtin_read , "Input environment variable"),
// BLTIN("return" , builtin_return , "Return from a function"),
@@ -5962,6 +5974,36 @@ static int builtin_jobs(char **argv UNUSED_PARAM)
}
#endif
+#if HUSH_DEBUG
+static int builtin_memleak(char **argv UNUSED_PARAM)
+{
+ void *p;
+ unsigned long l;
+
+ /* Crude attempt to find where "free memory" starts,
+ * sans fragmentation. */
+ p = malloc(240);
+ l = (unsigned long)p;
+ free(p);
+ p = malloc(3400);
+ if (l < (unsigned long)p) l = (unsigned long)p;
+ free(p);
+
+ if (!G.memleak_value)
+ G.memleak_value = l;
+
+ l -= G.memleak_value;
+ if ((long)l < 0)
+ l = 0;
+ l /= 1024;
+ if (l > 127)
+ l = 127;
+
+ /* Exitcode is "how many kilobytes we leaked since 1st call" */
+ return l;
+}
+#endif
+
static int builtin_pwd(char **argv UNUSED_PARAM)
{
puts(set_cwd());