diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-08 11:48:57 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-08 11:48:57 +0000 |
commit | c73b70c7013aa98a86653ad7e7d15bcca16622f2 (patch) | |
tree | 2f2534d588201af85d09335848cef63e93cc83c1 | |
parent | 3dfb035d8df33e59492e78a97bf42e961ba178e4 (diff) | |
download | busybox-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.c | 50 | ||||
-rw-r--r-- | shell/hush_test/hush-z_slow/leak_all1.right | 3 | ||||
-rwxr-xr-x | shell/hush_test/hush-z_slow/leak_all1.tests | 61 | ||||
-rw-r--r-- | shell/hush_test/hush-z_slow/leak_var.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-z_slow/leak_var.tests | 103 | ||||
-rw-r--r-- | shell/hush_test/hush-z_slow/leak_var2.right | 3 | ||||
-rwxr-xr-x | shell/hush_test/hush-z_slow/leak_var2.tests | 37 |
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 |
556 | static int builtin_help(char **argv); | 562 | static int builtin_help(char **argv); |
557 | #endif | 563 | #endif |
564 | #if HUSH_DEBUG | ||
565 | static int builtin_memleak(char **argv); | ||
566 | #endif | ||
558 | static int builtin_pwd(char **argv); | 567 | static int builtin_pwd(char **argv); |
559 | static int builtin_read(char **argv); | 568 | static int builtin_read(char **argv); |
560 | static int builtin_test(char **argv); | ||
561 | static int builtin_trap(char **argv); | ||
562 | static int builtin_true(char **argv); | ||
563 | static int builtin_set(char **argv); | 569 | static int builtin_set(char **argv); |
564 | static int builtin_shift(char **argv); | 570 | static int builtin_shift(char **argv); |
565 | static int builtin_source(char **argv); | 571 | static int builtin_source(char **argv); |
572 | static int builtin_test(char **argv); | ||
573 | static int builtin_trap(char **argv); | ||
574 | static int builtin_true(char **argv); | ||
566 | static int builtin_umask(char **argv); | 575 | static int builtin_umask(char **argv); |
567 | static int builtin_unset(char **argv); | 576 | static int builtin_unset(char **argv); |
568 | static int builtin_wait(char **argv); | 577 | static 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 | ||
5978 | static 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 | |||
5965 | static int builtin_pwd(char **argv UNUSED_PARAM) | 6007 | static 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 @@ | |||
1 | Warm up | ||
2 | Measuring memory leak... | ||
3 | Ok | ||
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 | |||
8 | echo "Warm up" | ||
9 | i=1 | ||
10 | l=1 | ||
11 | t=1 | ||
12 | export t | ||
13 | while 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 | ||
18 | Hello builtin : | ||
19 | HERE | ||
20 | Hello true | ||
21 | HERE | ||
22 | elif false; then | ||
23 | true; echo Doesnt run | ||
24 | else | ||
25 | { true; }; echo Doesnt run too >>/foo/bar | ||
26 | fi | ||
27 | : $((i++)) | ||
28 | done | ||
29 | |||
30 | memleak | ||
31 | |||
32 | echo "Measuring memory leak..." | ||
33 | # Please copy the entire block from above verbatim | ||
34 | i=1 | ||
35 | l=1 | ||
36 | t=1 | ||
37 | export t | ||
38 | while 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 | ||
43 | Hello builtin : | ||
44 | HERE | ||
45 | Hello true | ||
46 | HERE | ||
47 | elif false; then | ||
48 | true; echo Doesnt run | ||
49 | else | ||
50 | { true; }; echo Doesnt run too >>/foo/bar | ||
51 | fi | ||
52 | : $((i++)) | ||
53 | done | ||
54 | |||
55 | memleak | ||
56 | kb=$? | ||
57 | if test $kb -le 4; then | ||
58 | echo Ok #$kb | ||
59 | else | ||
60 | echo "Bad: $kb kb (or more) leaked" | ||
61 | fi | ||
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 @@ | |||
1 | Measuring memory leak... | 1 | Measuring memory leak... |
2 | vsz does not grow | 2 | Ok |
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 @@ | |||
1 | pid=$$ | ||
2 | |||
3 | # Warm up | ||
4 | beg=`ps -o pid,vsz | grep "^ *$pid "` | ||
5 | i=1 | ||
6 | while 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 | ||
42 | done | ||
43 | end=`ps -o pid,vsz | grep "^ *$pid "` | ||
44 | |||
45 | # Warm up again (I do need it on my machine) | ||
46 | beg=`ps -o pid,vsz | grep "^ *$pid "` | ||
47 | i=1 | ||
48 | while 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 | ||
84 | done | ||
85 | end=`ps -o pid,vsz | grep "^ *$pid "` | ||
86 | if test "$beg" != "$end"; then | ||
87 | true echo "vsz grows: $beg -> $end" | ||
88 | else | ||
89 | true echo "vsz does not grow" | ||
90 | fi | ||
91 | |||
92 | echo "Measuring memory leak..." | 1 | echo "Measuring memory leak..." |
93 | beg=`ps -o pid,vsz | grep "^ *$pid "` | ||
94 | i=1 | 2 | i=1 |
95 | while test $i != X; do | 3 | while 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 | ||
131 | done | 40 | done |
132 | end=`ps -o pid,vsz | grep "^ *$pid "` | 41 | memleak |
133 | 42 | kb=$? | |
134 | if test "$beg" != "$end"; then | 43 | if test $kb -le 4; then |
135 | echo "vsz grows: $beg -> $end" | 44 | echo Ok |
136 | else | 45 | else |
137 | echo "vsz does not grow" | 46 | echo "Bad: $kb kb (or more) leaked" |
138 | fi | 47 | fi |
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 @@ | |||
1 | Warm up | ||
1 | Measuring memory leak... | 2 | Measuring memory leak... |
2 | vsz does not grow | 3 | Ok |
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 @@ | |||
1 | pid=$$ | ||
2 | |||
3 | t=1 | 1 | t=1 |
4 | export t | 2 | export t |
5 | 3 | ||
6 | # Warm up | 4 | echo "Warm up" |
7 | beg=`ps -o pid,vsz | grep "^ *$pid "` | ||
8 | i=1 | 5 | i=1 |
9 | while test $i != X; do | 6 | while 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 |
19 | done | 16 | done |
20 | end=`ps -o pid,vsz | grep "^ *$pid "` | ||
21 | 17 | ||
22 | # Warm up again (I do need it on my machine) | 18 | memleak |
23 | beg=`ps -o pid,vsz | grep "^ *$pid "` | ||
24 | i=1 | ||
25 | while 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 | ||
35 | done | ||
36 | end=`ps -o pid,vsz | grep "^ *$pid "` | ||
37 | if test "$beg" != "$end"; then | ||
38 | true echo "vsz grows: $beg -> $end" | ||
39 | else | ||
40 | true echo "vsz does not grow" | ||
41 | fi | ||
42 | 19 | ||
43 | echo "Measuring memory leak..." | 20 | echo "Measuring memory leak..." |
44 | beg=`ps -o pid,vsz | grep "^ *$pid "` | ||
45 | i=1 | 21 | i=1 |
46 | while test $i != X; do | 22 | while 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 |
56 | done | 32 | done |
57 | end=`ps -o pid,vsz | grep "^ *$pid "` | ||
58 | 33 | ||
59 | if test "$beg" != "$end"; then | 34 | memleak |
60 | echo "vsz grows: $beg -> $end" | 35 | kb=$? |
36 | if test $kb -le 4; then | ||
37 | echo Ok | ||
61 | else | 38 | else |
62 | echo "vsz does not grow" | 39 | echo "Bad: $kb kb (or more) leaked" |
63 | fi | 40 | fi |