aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-08 11:48:57 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-08 11:48:57 +0000
commitc73b70c7013aa98a86653ad7e7d15bcca16622f2 (patch)
tree2f2534d588201af85d09335848cef63e93cc83c1
parent3dfb035d8df33e59492e78a97bf42e961ba178e4 (diff)
downloadbusybox-w32-c73b70c7013aa98a86653ad7e7d15bcca16622f2.tar.gz
busybox-w32-c73b70c7013aa98a86653ad7e7d15bcca16622f2.tar.bz2
busybox-w32-c73b70c7013aa98a86653ad7e7d15bcca16622f2.zip
hush: add leak detector helper; fix/add tests for it
function old new delta builtin_memleak - 92 +92 bltins 288 300 +12
-rw-r--r--shell/hush.c50
-rw-r--r--shell/hush_test/hush-z_slow/leak_all1.right3
-rwxr-xr-xshell/hush_test/hush-z_slow/leak_all1.tests61
-rw-r--r--shell/hush_test/hush-z_slow/leak_var.right2
-rwxr-xr-xshell/hush_test/hush-z_slow/leak_var.tests103
-rw-r--r--shell/hush_test/hush-z_slow/leak_var2.right3
-rwxr-xr-xshell/hush_test/hush-z_slow/leak_var2.tests37
7 files changed, 126 insertions, 133 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 5594aaea4..6075f514a 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -117,7 +117,10 @@
117#define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__ 117#define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
118#endif 118#endif
119 119
120/* Keep unconditionally on for now */ 120/* Enable/disable sanity checks. Ok to enable in production,
121 * only adds a bit of bloat.
122 * Keeping unconditionally on for now.
123 */
121#define HUSH_DEBUG 1 124#define HUSH_DEBUG 1
122/* In progress... */ 125/* In progress... */
123#define ENABLE_HUSH_FUNCTIONS 0 126#define ENABLE_HUSH_FUNCTIONS 0
@@ -524,6 +527,9 @@ struct globals {
524 char **traps; /* char *traps[NSIG] */ 527 char **traps; /* char *traps[NSIG] */
525 sigset_t blocked_set; 528 sigset_t blocked_set;
526 sigset_t inherited_set; 529 sigset_t inherited_set;
530#if HUSH_DEBUG
531 unsigned long memleak_value;
532#endif
527 char user_input_buf[ENABLE_FEATURE_EDITING ? BUFSIZ : 2]; 533 char user_input_buf[ENABLE_FEATURE_EDITING ? BUFSIZ : 2];
528#if ENABLE_FEATURE_SH_STANDALONE 534#if ENABLE_FEATURE_SH_STANDALONE
529 struct nofork_save_area nofork_save; 535 struct nofork_save_area nofork_save;
@@ -555,14 +561,17 @@ static int builtin_jobs(char **argv);
555#if ENABLE_HUSH_HELP 561#if ENABLE_HUSH_HELP
556static int builtin_help(char **argv); 562static int builtin_help(char **argv);
557#endif 563#endif
564#if HUSH_DEBUG
565static int builtin_memleak(char **argv);
566#endif
558static int builtin_pwd(char **argv); 567static int builtin_pwd(char **argv);
559static int builtin_read(char **argv); 568static int builtin_read(char **argv);
560static int builtin_test(char **argv);
561static int builtin_trap(char **argv);
562static int builtin_true(char **argv);
563static int builtin_set(char **argv); 569static int builtin_set(char **argv);
564static int builtin_shift(char **argv); 570static int builtin_shift(char **argv);
565static int builtin_source(char **argv); 571static int builtin_source(char **argv);
572static int builtin_test(char **argv);
573static int builtin_trap(char **argv);
574static int builtin_true(char **argv);
566static int builtin_umask(char **argv); 575static int builtin_umask(char **argv);
567static int builtin_unset(char **argv); 576static int builtin_unset(char **argv);
568static int builtin_wait(char **argv); 577static int builtin_wait(char **argv);
@@ -618,6 +627,9 @@ static const struct built_in_command bltins[] = {
618#if ENABLE_HUSH_JOB 627#if ENABLE_HUSH_JOB
619 BLTIN("jobs" , builtin_jobs , "List active jobs"), 628 BLTIN("jobs" , builtin_jobs , "List active jobs"),
620#endif 629#endif
630#if HUSH_DEBUG
631 BLTIN("memleak" , builtin_memleak , "Debug tool"),
632#endif
621 BLTIN("pwd" , builtin_pwd , "Print current directory"), 633 BLTIN("pwd" , builtin_pwd , "Print current directory"),
622 BLTIN("read" , builtin_read , "Input environment variable"), 634 BLTIN("read" , builtin_read , "Input environment variable"),
623// BLTIN("return" , builtin_return , "Return from a function"), 635// BLTIN("return" , builtin_return , "Return from a function"),
@@ -5962,6 +5974,36 @@ static int builtin_jobs(char **argv UNUSED_PARAM)
5962} 5974}
5963#endif 5975#endif
5964 5976
5977#if HUSH_DEBUG
5978static int builtin_memleak(char **argv UNUSED_PARAM)
5979{
5980 void *p;
5981 unsigned long l;
5982
5983 /* Crude attempt to find where "free memory" starts,
5984 * sans fragmentation. */
5985 p = malloc(240);
5986 l = (unsigned long)p;
5987 free(p);
5988 p = malloc(3400);
5989 if (l < (unsigned long)p) l = (unsigned long)p;
5990 free(p);
5991
5992 if (!G.memleak_value)
5993 G.memleak_value = l;
5994
5995 l -= G.memleak_value;
5996 if ((long)l < 0)
5997 l = 0;
5998 l /= 1024;
5999 if (l > 127)
6000 l = 127;
6001
6002 /* Exitcode is "how many kilobytes we leaked since 1st call" */
6003 return l;
6004}
6005#endif
6006
5965static int builtin_pwd(char **argv UNUSED_PARAM) 6007static int builtin_pwd(char **argv UNUSED_PARAM)
5966{ 6008{
5967 puts(set_cwd()); 6009 puts(set_cwd());
diff --git a/shell/hush_test/hush-z_slow/leak_all1.right b/shell/hush_test/hush-z_slow/leak_all1.right
new file mode 100644
index 000000000..c6f0334f3
--- /dev/null
+++ b/shell/hush_test/hush-z_slow/leak_all1.right
@@ -0,0 +1,3 @@
1Warm up
2Measuring memory leak...
3Ok
diff --git a/shell/hush_test/hush-z_slow/leak_all1.tests b/shell/hush_test/hush-z_slow/leak_all1.tests
new file mode 100755
index 000000000..6834d9a64
--- /dev/null
+++ b/shell/hush_test/hush-z_slow/leak_all1.tests
@@ -0,0 +1,61 @@
1# "Check many leaks" test #1
2# Cramming all kinds of weird commands in here.
3# As you find leaks, please create separate, small test
4# for each leak.
5# Narrowing down the leak using this large test may be difficult.
6# It is intended to be a blanket "is everything ok?" test
7
8echo "Warm up"
9i=1
10l=1
11t=1
12export t
13while test $i != 99; do
14 t=value1_$i; t=value2_$i true; t=value3_$i /bin/true; t=value4_$i exec 1>&1
15 { t=value3_$i /bin/true; } </dev/null
16 if true; t=valueA_$i false >>/dev/null; true; then
17 : << HERE >/dev/null; true <<HERE
18Hello builtin :
19HERE
20Hello true
21HERE
22 elif false; then
23 true; echo Doesnt run
24 else
25 { true; }; echo Doesnt run too >>/foo/bar
26 fi
27 : $((i++))
28done
29
30memleak
31
32echo "Measuring memory leak..."
33# Please copy the entire block from above verbatim
34i=1
35l=1
36t=1
37export t
38while test $i != 99; do
39 t=value1_$i; t=value2_$i true; t=value3_$i /bin/true; t=value4_$i exec 1>&1
40 { t=value3_$i /bin/true; } </dev/null
41 if true; t=valueA_$i false >>/dev/null; true; then
42 : << HERE >/dev/null; true <<HERE
43Hello builtin :
44HERE
45Hello true
46HERE
47 elif false; then
48 true; echo Doesnt run
49 else
50 { true; }; echo Doesnt run too >>/foo/bar
51 fi
52 : $((i++))
53done
54
55memleak
56kb=$?
57if test $kb -le 4; then
58 echo Ok #$kb
59else
60 echo "Bad: $kb kb (or more) leaked"
61fi
diff --git a/shell/hush_test/hush-z_slow/leak_var.right b/shell/hush_test/hush-z_slow/leak_var.right
index 7bccc1eef..1d4d6ff57 100644
--- a/shell/hush_test/hush-z_slow/leak_var.right
+++ b/shell/hush_test/hush-z_slow/leak_var.right
@@ -1,2 +1,2 @@
1Measuring memory leak... 1Measuring memory leak...
2vsz does not grow 2Ok
diff --git a/shell/hush_test/hush-z_slow/leak_var.tests b/shell/hush_test/hush-z_slow/leak_var.tests
index b3e13e308..41c09e478 100755
--- a/shell/hush_test/hush-z_slow/leak_var.tests
+++ b/shell/hush_test/hush-z_slow/leak_var.tests
@@ -1,96 +1,4 @@
1pid=$$
2
3# Warm up
4beg=`ps -o pid,vsz | grep "^ *$pid "`
5i=1
6while test $i != X; do
7 unset t
8 t=111111111111111111111111111111111111111111111111111111111111111111111111
9 export t
10 unset t
11 t=111111111111111111111111111111111111111111111111111111111111111111111111
12 export t
13 unset t
14 t=111111111111111111111111111111111111111111111111111111111111111111111111
15 export t
16 unset t
17 t=111111111111111111111111111111111111111111111111111111111111111111111111
18 export t
19 unset t
20 t=111111111111111111111111111111111111111111111111111111111111111111111111
21 export t
22 i=1$i
23 if test $i = 1111111111111111111111111111111111111111111111; then i=2; fi
24 if test $i = 1111111111111111111111111111111111111111111112; then i=3; fi
25 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi
26 if test $i = 1111111111111111111111111111111111111111111114; then i=5; fi
27 if test $i = 1111111111111111111111111111111111111111111115; then i=6; fi
28 if test $i = 1111111111111111111111111111111111111111111116; then i=7; fi
29 if test $i = 1111111111111111111111111111111111111111111117; then i=8; fi
30 if test $i = 1111111111111111111111111111111111111111111118; then i=9; fi
31 if test $i = 1111111111111111111111111111111111111111111119; then i=a; fi
32 if test $i = 111111111111111111111111111111111111111111111a; then i=b; fi
33 if test $i = 111111111111111111111111111111111111111111111b; then i=c; fi
34 if test $i = 111111111111111111111111111111111111111111111c; then i=d; fi
35 if test $i = 111111111111111111111111111111111111111111111d; then i=e; fi
36 if test $i = 111111111111111111111111111111111111111111111e; then i=f; fi
37 if test $i = 111111111111111111111111111111111111111111111f; then i=g; fi
38 if test $i = 111111111111111111111111111111111111111111111g; then i=h; fi
39 if test $i = 111111111111111111111111111111111111111111111h; then i=i; fi
40 if test $i = 111111111111111111111111111111111111111111111i; then i=j; fi
41 if test $i = 111111111111111111111111111111111111111111111j; then i=X; fi
42done
43end=`ps -o pid,vsz | grep "^ *$pid "`
44
45# Warm up again (I do need it on my machine)
46beg=`ps -o pid,vsz | grep "^ *$pid "`
47i=1
48while test $i != X; do
49 unset t
50 t=111111111111111111111111111111111111111111111111111111111111111111111111
51 export t
52 unset t
53 t=111111111111111111111111111111111111111111111111111111111111111111111111
54 export t
55 unset t
56 t=111111111111111111111111111111111111111111111111111111111111111111111111
57 export t
58 unset t
59 t=111111111111111111111111111111111111111111111111111111111111111111111111
60 export t
61 unset t
62 t=111111111111111111111111111111111111111111111111111111111111111111111111
63 export t
64 i=1$i
65 if test $i = 1111111111111111111111111111111111111111111111; then i=2; fi
66 if test $i = 1111111111111111111111111111111111111111111112; then i=3; fi
67 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi
68 if test $i = 1111111111111111111111111111111111111111111114; then i=5; fi
69 if test $i = 1111111111111111111111111111111111111111111115; then i=6; fi
70 if test $i = 1111111111111111111111111111111111111111111116; then i=7; fi
71 if test $i = 1111111111111111111111111111111111111111111117; then i=8; fi
72 if test $i = 1111111111111111111111111111111111111111111118; then i=9; fi
73 if test $i = 1111111111111111111111111111111111111111111119; then i=a; fi
74 if test $i = 111111111111111111111111111111111111111111111a; then i=b; fi
75 if test $i = 111111111111111111111111111111111111111111111b; then i=c; fi
76 if test $i = 111111111111111111111111111111111111111111111c; then i=d; fi
77 if test $i = 111111111111111111111111111111111111111111111d; then i=e; fi
78 if test $i = 111111111111111111111111111111111111111111111e; then i=f; fi
79 if test $i = 111111111111111111111111111111111111111111111f; then i=g; fi
80 if test $i = 111111111111111111111111111111111111111111111g; then i=h; fi
81 if test $i = 111111111111111111111111111111111111111111111h; then i=i; fi
82 if test $i = 111111111111111111111111111111111111111111111i; then i=j; fi
83 if test $i = 111111111111111111111111111111111111111111111j; then i=X; fi
84done
85end=`ps -o pid,vsz | grep "^ *$pid "`
86if test "$beg" != "$end"; then
87 true echo "vsz grows: $beg -> $end"
88else
89 true echo "vsz does not grow"
90fi
91
92echo "Measuring memory leak..." 1echo "Measuring memory leak..."
93beg=`ps -o pid,vsz | grep "^ *$pid "`
94i=1 2i=1
95while test $i != X; do 3while test $i != X; do
96 unset t 4 unset t
@@ -128,11 +36,12 @@ while test $i != X; do
128 if test $i = 111111111111111111111111111111111111111111111h; then i=i; fi 36 if test $i = 111111111111111111111111111111111111111111111h; then i=i; fi
129 if test $i = 111111111111111111111111111111111111111111111i; then i=j; fi 37 if test $i = 111111111111111111111111111111111111111111111i; then i=j; fi
130 if test $i = 111111111111111111111111111111111111111111111j; then i=X; fi 38 if test $i = 111111111111111111111111111111111111111111111j; then i=X; fi
39 memleak
131done 40done
132end=`ps -o pid,vsz | grep "^ *$pid "` 41memleak
133 42kb=$?
134if test "$beg" != "$end"; then 43if test $kb -le 4; then
135 echo "vsz grows: $beg -> $end" 44 echo Ok
136else 45else
137 echo "vsz does not grow" 46 echo "Bad: $kb kb (or more) leaked"
138fi 47fi
diff --git a/shell/hush_test/hush-z_slow/leak_var2.right b/shell/hush_test/hush-z_slow/leak_var2.right
index 7bccc1eef..c6f0334f3 100644
--- a/shell/hush_test/hush-z_slow/leak_var2.right
+++ b/shell/hush_test/hush-z_slow/leak_var2.right
@@ -1,2 +1,3 @@
1Warm up
1Measuring memory leak... 2Measuring memory leak...
2vsz does not grow 3Ok
diff --git a/shell/hush_test/hush-z_slow/leak_var2.tests b/shell/hush_test/hush-z_slow/leak_var2.tests
index 09f247552..0ab131552 100755
--- a/shell/hush_test/hush-z_slow/leak_var2.tests
+++ b/shell/hush_test/hush-z_slow/leak_var2.tests
@@ -1,10 +1,7 @@
1pid=$$
2
3t=1 1t=1
4export t 2export t
5 3
6# Warm up 4echo "Warm up"
7beg=`ps -o pid,vsz | grep "^ *$pid "`
8i=1 5i=1
9while test $i != X; do 6while test $i != X; do
10 t=111111111111111111111111111111111111111111111111111111111111111111111110$i 7 t=111111111111111111111111111111111111111111111111111111111111111111111110$i
@@ -17,31 +14,10 @@ while test $i != X; do
17 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi 14 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi
18 if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi 15 if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi
19done 16done
20end=`ps -o pid,vsz | grep "^ *$pid "`
21 17
22# Warm up again (I do need it on my machine) 18memleak
23beg=`ps -o pid,vsz | grep "^ *$pid "`
24i=1
25while test $i != X; do
26 t=111111111111111111111111111111111111111111111111111111111111111111111110$i
27 t=111111111111111111111111111111111111111111111111111111111111111111111111$i true
28 t=111111111111111111111111111111111111111111111111111111111111111111111112$i /bin/true
29 t=111111111111111111111111111111111111111111111111111111111111111111111113$i exec 1>&1
30 i=1$i
31 if test $i = 1111111111111111111111111111111111111111111111; then i=2; fi
32 if test $i = 1111111111111111111111111111111111111111111112; then i=3; fi
33 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi
34 if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi
35done
36end=`ps -o pid,vsz | grep "^ *$pid "`
37if test "$beg" != "$end"; then
38 true echo "vsz grows: $beg -> $end"
39else
40 true echo "vsz does not grow"
41fi
42 19
43echo "Measuring memory leak..." 20echo "Measuring memory leak..."
44beg=`ps -o pid,vsz | grep "^ *$pid "`
45i=1 21i=1
46while test $i != X; do 22while test $i != X; do
47 t=111111111111111111111111111111111111111111111111111111111111111111111110$i 23 t=111111111111111111111111111111111111111111111111111111111111111111111110$i
@@ -54,10 +30,11 @@ while test $i != X; do
54 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi 30 if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi
55 if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi 31 if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi
56done 32done
57end=`ps -o pid,vsz | grep "^ *$pid "`
58 33
59if test "$beg" != "$end"; then 34memleak
60 echo "vsz grows: $beg -> $end" 35kb=$?
36if test $kb -le 4; then
37 echo Ok
61else 38else
62 echo "vsz does not grow" 39 echo "Bad: $kb kb (or more) leaked"
63fi 40fi