aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2014-09-11 05:37:10 -0400
committerJason Wessel <jason.wessel@windriver.com>2015-02-19 13:39:03 -0500
commitfb6daa7520f9d17a97e84a3d5a947819e0313f28 (patch)
tree3495ac88045d5a21c72a2a43517980afa47774ca /kernel
parentab08e464a2cd8242fdc6e4f87f3480808364a97a (diff)
kdb: Provide forward search at more prompt
Currently kdb allows the output of comamnds to be filtered using the | grep feature. This is useful but does not permit the output emitted shortly after a string match to be examined without wading through the entire unfiltered output of the command. Such a feature is particularly useful to navigate function traces because these traces often have a useful trigger string *before* the point of interest. This patch reuses the existing filtering logic to introduce a simple forward search to kdb that can be triggered from the more prompt. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/debug/kdb/kdb_io.c22
-rw-r--r--kernel/debug/kdb/kdb_main.c7
-rw-r--r--kernel/debug/kdb/kdb_private.h2
3 files changed, 26 insertions, 5 deletions
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index a550afb99ebe..ca13e6215537 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -680,6 +680,12 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
680 size_avail = sizeof(kdb_buffer) - len; 680 size_avail = sizeof(kdb_buffer) - len;
681 goto kdb_print_out; 681 goto kdb_print_out;
682 } 682 }
683 if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH)
684 /*
685 * This was a interactive search (using '/' at more
686 * prompt) and it has completed. Clear the flag.
687 */
688 kdb_grepping_flag = 0;
683 /* 689 /*
684 * at this point the string is a full line and 690 * at this point the string is a full line and
685 * should be printed, up to the null. 691 * should be printed, up to the null.
@@ -798,11 +804,23 @@ kdb_printit:
798 kdb_nextline = linecount - 1; 804 kdb_nextline = linecount - 1;
799 kdb_printf("\r"); 805 kdb_printf("\r");
800 suspend_grep = 1; /* for this recursion */ 806 suspend_grep = 1; /* for this recursion */
807 } else if (buf1[0] == '/' && !kdb_grepping_flag) {
808 kdb_printf("\r");
809 kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN,
810 kdbgetenv("SEARCHPROMPT") ?: "search> ");
811 *strchrnul(kdb_grep_string, '\n') = '\0';
812 kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH;
813 suspend_grep = 1; /* for this recursion */
801 } else if (buf1[0] && buf1[0] != '\n') { 814 } else if (buf1[0] && buf1[0] != '\n') {
802 /* user hit something other than enter */ 815 /* user hit something other than enter */
803 suspend_grep = 1; /* for this recursion */ 816 suspend_grep = 1; /* for this recursion */
804 kdb_printf("\nOnly 'q' or 'Q' are processed at more " 817 if (buf1[0] != '/')
805 "prompt, input ignored\n"); 818 kdb_printf(
819 "\nOnly 'q', 'Q' or '/' are processed at "
820 "more prompt, input ignored\n");
821 else
822 kdb_printf("\n'/' cannot be used during | "
823 "grep filtering, input ignored\n");
806 } else if (kdb_grepping_flag) { 824 } else if (kdb_grepping_flag) {
807 /* user hit enter */ 825 /* user hit enter */
808 suspend_grep = 1; /* for this recursion */ 826 suspend_grep = 1; /* for this recursion */
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 420418360b81..4121345498e0 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -50,8 +50,7 @@
50static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE; 50static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE;
51module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); 51module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600);
52 52
53#define GREP_LEN 256 53char kdb_grep_string[KDB_GREP_STRLEN];
54char kdb_grep_string[GREP_LEN];
55int kdb_grepping_flag; 54int kdb_grepping_flag;
56EXPORT_SYMBOL(kdb_grepping_flag); 55EXPORT_SYMBOL(kdb_grepping_flag);
57int kdb_grep_leading; 56int kdb_grep_leading;
@@ -870,7 +869,7 @@ static void parse_grep(const char *str)
870 len = strlen(cp); 869 len = strlen(cp);
871 if (!len) 870 if (!len)
872 return; 871 return;
873 if (len >= GREP_LEN) { 872 if (len >= KDB_GREP_STRLEN) {
874 kdb_printf("search string too long\n"); 873 kdb_printf("search string too long\n");
875 return; 874 return;
876 } 875 }
@@ -1280,6 +1279,8 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
1280 kdb_nextline = 1; 1279 kdb_nextline = 1;
1281 KDB_STATE_CLEAR(SUPPRESS); 1280 KDB_STATE_CLEAR(SUPPRESS);
1282 kdb_grepping_flag = 0; 1281 kdb_grepping_flag = 0;
1282 /* ensure the old search does not leak into '/' commands */
1283 kdb_grep_string[0] = '\0';
1283 1284
1284 cmdbuf = cmd_cur; 1285 cmdbuf = cmd_cur;
1285 *cmdbuf = '\0'; 1286 *cmdbuf = '\0';
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
index eaacd1693954..da93894db7ba 100644
--- a/kernel/debug/kdb/kdb_private.h
+++ b/kernel/debug/kdb/kdb_private.h
@@ -196,7 +196,9 @@ extern int kdb_main_loop(kdb_reason_t, kdb_reason_t,
196 196
197/* Miscellaneous functions and data areas */ 197/* Miscellaneous functions and data areas */
198extern int kdb_grepping_flag; 198extern int kdb_grepping_flag;
199#define KDB_GREPPING_FLAG_SEARCH 0x8000
199extern char kdb_grep_string[]; 200extern char kdb_grep_string[];
201#define KDB_GREP_STRLEN 256
200extern int kdb_grep_leading; 202extern int kdb_grep_leading;
201extern int kdb_grep_trailing; 203extern int kdb_grep_trailing;
202extern char *kdb_cmds[]; 204extern char *kdb_cmds[];