diff options
author | Denis Vlasenko | 2009-04-08 11:48:57 +0000 |
---|---|---|
committer | Denis Vlasenko | 2009-04-08 11:48:57 +0000 |
commit | c73b70c7013aa98a86653ad7e7d15bcca16622f2 (patch) | |
tree | 2f2534d588201af85d09335848cef63e93cc83c1 /shell/hush.c | |
parent | 3dfb035d8df33e59492e78a97bf42e961ba178e4 (diff) | |
download | busybox-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.c | 50 |
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()); |