diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-04 13:07:27 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-04 13:07:27 +0000 |
| commit | 400c5b6fc6aea218fdfbc14ac709a848d9c696b0 (patch) | |
| tree | b3217aa77c02461415d67bed96d3599d96b796b4 /shell | |
| parent | 6e6d331d97aa230625c9b50c73f5df9251b8df4b (diff) | |
| download | busybox-w32-400c5b6fc6aea218fdfbc14ac709a848d9c696b0.tar.gz busybox-w32-400c5b6fc6aea218fdfbc14ac709a848d9c696b0.tar.bz2 busybox-w32-400c5b6fc6aea218fdfbc14ac709a848d9c696b0.zip | |
hush: add parse tree debug print
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/README | 4 | ||||
| -rw-r--r-- | shell/hush.c | 67 |
2 files changed, 66 insertions, 5 deletions
diff --git a/shell/README b/shell/README index 989587a4f..c3e7132ce 100644 --- a/shell/README +++ b/shell/README | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | Various bits of what is known about busybox shells, in no particular order. | 1 | Various bits of what is known about busybox shells, in no particular order. |
| 2 | 2 | ||
| 3 | 2007-05-03 | 3 | 2007-05-03 |
| 4 | hush: new bug spotted: Ctrl-C on "while true; do true; done" kills shell, | ||
| 5 | not just the loop. | ||
| 6 | |||
| 7 | 2007-05-03 | ||
| 4 | hush: update on "sleep 1 | exit 3; echo $?" bug. | 8 | hush: update on "sleep 1 | exit 3; echo $?" bug. |
| 5 | parse_stream_outer() repeatedly calls parse_stream(). | 9 | parse_stream_outer() repeatedly calls parse_stream(). |
| 6 | parse_stream() is now fixed to stop on ';' in this example, | 10 | parse_stream() is now fixed to stop on ';' in this example, |
diff --git a/shell/hush.c b/shell/hush.c index 4d5e41244..c51ed1a51 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -85,11 +85,12 @@ | |||
| 85 | 85 | ||
| 86 | /* If you comment out one of these below, it will be #defined later | 86 | /* If you comment out one of these below, it will be #defined later |
| 87 | * to perform debug printfs to stderr: */ | 87 | * to perform debug printfs to stderr: */ |
| 88 | #define debug_printf(...) do {} while (0) | 88 | #define debug_printf(...) do {} while (0) |
| 89 | /* Finer-grained debug switch */ | 89 | /* Finer-grained debug switches */ |
| 90 | #define debug_printf_jobs(...) do {} while (0) | 90 | #define debug_printf_jobs(...) do {} while (0) |
| 91 | #define debug_printf_exec(...) do {} while (0) | 91 | #define debug_printf_exec(...) do {} while (0) |
| 92 | #define debug_printf_parse(...) do {} while (0) | 92 | #define debug_printf_parse(...) do {} while (0) |
| 93 | #define debug_print_tree(a, b) do {} while (0) | ||
| 93 | 94 | ||
| 94 | 95 | ||
| 95 | #ifndef debug_printf | 96 | #ifndef debug_printf |
| @@ -1860,6 +1861,61 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1860 | return -1; | 1861 | return -1; |
| 1861 | } | 1862 | } |
| 1862 | 1863 | ||
| 1864 | #ifndef debug_print_tree | ||
| 1865 | static void debug_print_tree(struct pipe *pi, int lvl) | ||
| 1866 | { | ||
| 1867 | static const char *PIPE[] = { | ||
| 1868 | [PIPE_SEQ] = "SEQ", | ||
| 1869 | [PIPE_AND] = "AND", | ||
| 1870 | [PIPE_OR ] = "OR", | ||
| 1871 | [PIPE_BG ] = "BG", | ||
| 1872 | }; | ||
| 1873 | static const char *RES[] = { | ||
| 1874 | [RES_NONE ] = "NONE" , | ||
| 1875 | [RES_IF ] = "IF" , | ||
| 1876 | [RES_THEN ] = "THEN" , | ||
| 1877 | [RES_ELIF ] = "ELIF" , | ||
| 1878 | [RES_ELSE ] = "ELSE" , | ||
| 1879 | [RES_FI ] = "FI" , | ||
| 1880 | [RES_FOR ] = "FOR" , | ||
| 1881 | [RES_WHILE] = "WHILE", | ||
| 1882 | [RES_UNTIL] = "UNTIL", | ||
| 1883 | [RES_DO ] = "DO" , | ||
| 1884 | [RES_DONE ] = "DONE" , | ||
| 1885 | [RES_XXXX ] = "XXXX" , | ||
| 1886 | [RES_IN ] = "IN" , | ||
| 1887 | [RES_SNTX ] = "SNTX" , | ||
| 1888 | }; | ||
| 1889 | |||
| 1890 | int pin, prn; | ||
| 1891 | char **argv; | ||
| 1892 | pin = 0; | ||
| 1893 | while (pi) { | ||
| 1894 | fprintf(stderr, "%*spipe %d r_mode=%s followup=%d %s\n", lvl*2, "", | ||
| 1895 | pin, RES[pi->r_mode], pi->followup, PIPE[pi->followup]); | ||
| 1896 | prn = 0; | ||
| 1897 | while (prn < pi->num_progs) { | ||
| 1898 | fprintf(stderr, "%*s prog %d", lvl*2, "", prn); | ||
| 1899 | if (pi->progs[prn].group) { | ||
| 1900 | fprintf(stderr, " group: (argv=%p)\n", pi->progs[prn].argv); | ||
| 1901 | debug_print_tree(pi->progs[prn].group, lvl+1); | ||
| 1902 | prn++; | ||
| 1903 | continue; | ||
| 1904 | } | ||
| 1905 | argv = pi->progs[prn].argv; | ||
| 1906 | if (argv) while (*argv) { | ||
| 1907 | fprintf(stderr, " '%s'", *argv); | ||
| 1908 | argv++; | ||
| 1909 | } | ||
| 1910 | fprintf(stderr, "\n"); | ||
| 1911 | prn++; | ||
| 1912 | } | ||
| 1913 | pi = pi->next; | ||
| 1914 | pin++; | ||
| 1915 | } | ||
| 1916 | } | ||
| 1917 | #endif | ||
| 1918 | |||
| 1863 | // NB: called by pseudo_exec, and therefore must not modify any | 1919 | // NB: called by pseudo_exec, and therefore must not modify any |
| 1864 | // global data until exec/_exit (we can be a child after vfork!) | 1920 | // global data until exec/_exit (we can be a child after vfork!) |
| 1865 | static int run_list_real(struct pipe *pi) | 1921 | static int run_list_real(struct pipe *pi) |
| @@ -2088,7 +2144,7 @@ static int run_list(struct pipe *pi) | |||
| 2088 | /* free_pipe_list has the side effect of clearing memory | 2144 | /* free_pipe_list has the side effect of clearing memory |
| 2089 | * In the long run that function can be merged with run_list_real, | 2145 | * In the long run that function can be merged with run_list_real, |
| 2090 | * but doing that now would hobble the debugging effort. */ | 2146 | * but doing that now would hobble the debugging effort. */ |
| 2091 | free_pipe_list(pi,0); | 2147 | free_pipe_list(pi, 0); |
| 2092 | return rcode; | 2148 | return rcode; |
| 2093 | } | 2149 | } |
| 2094 | 2150 | ||
| @@ -3177,6 +3233,7 @@ static int parse_stream_outer(struct in_str *inp, int flag) | |||
| 3177 | done_word(&temp, &ctx); | 3233 | done_word(&temp, &ctx); |
| 3178 | done_pipe(&ctx, PIPE_SEQ); | 3234 | done_pipe(&ctx, PIPE_SEQ); |
| 3179 | debug_printf_exec("parse_stream_outer: run_list\n"); | 3235 | debug_printf_exec("parse_stream_outer: run_list\n"); |
| 3236 | debug_print_tree(ctx.list_head, 0); | ||
| 3180 | run_list(ctx.list_head); | 3237 | run_list(ctx.list_head); |
| 3181 | } else { | 3238 | } else { |
| 3182 | if (ctx.old_flag != 0) { | 3239 | if (ctx.old_flag != 0) { |
