Sharyathi Nagesh wrote:
Hi
Sachin and myself have worked on this patch. In case the memory dump
is corrupted crash tool exits from execution and we don't have any means
to debug the problem. This feature provides minimalistic features to
crash and help in debugging even if dump is corrupted.
Description of the patch:
This patch will provide the minimal functionality in crash tool.
This patch has been generated against crash-4.0.6.2.
This feature will read the dump, even if it is corrupted. It
provides minimal debugging features, as provided by lcrash tool earlier.
It provides access to dmesg, symbol information, disassembly and memory
read features.
You can get into minimal mode by providing "--minimal" option while
starting crash
eg: crash --minimal <vmlinux> <dump>
========================================================================
Testing:
This patch has been tested on the corrupted dump images on z-series
machine.
'help' command in the minimal mode gives out put in a line, not like
the way out put is generated in the normal mode of operation.
Please go through the features and let us know your thoughts
========================================================================
It seems safe enough to apply, and I like the idea. I'm just amazed that
the wholesale removal of all of the xxx_init() routines allows the restricted
command list to work properly!
- } else {
+ } else if(!(pc->flags & MINIMAL_MODE)){
read_in_kernel_config(IKCFG_INIT);
kernel_init();
machdep_init(POST_GDB);
I haven't walked through all the restricted command list code paths to
verify that they can work properly for all architectures without, say,
kernel_init(), the 3 machdep_init() calls, vm_init() etc. having run.
Certainly trying to rd or dis vmalloc addresses would display garbage
data or just fail, but that's to be expected.
I quickly tried this on a x86 and x86_64 -- but have you tried this on
an ia64 or ppc64?
The only thing I'm not excited about is all the re-tinkering with the
help screen output. Why bother? I'd prefer to keep things simple.
During initialization, display a WARNING message that lists the supported
commands just prior to the first prompt. And then just leave the help
screen alone, and let your command-restriction mechanism display the
per-command message:
error(INFO, "command: %s not available in minimal mode\n", args[0]);
...and then perhaps followed up immediately with the acceptable command
list again.
Another minor suggestion -- I think you can put the "eval" command in
the supported list. I use it all the time, and in this minimal environment
it may come in very handy. (There may be others, but they're probably not
worth having...)
But this is pretty cool. If I had known that you could get this basic
functionality so simply, I would have done this long ago! Nice job.
Dave
------------------------------------------------------------------------
diff -Naurp crash-old/cmdline.c crash-new/cmdline.c
--- crash-old/cmdline.c 2008-03-31 22:58:31.000000000 +0530
+++ crash-new/cmdline.c 2008-08-01 16:36:44.000000000 +0530
@@ -2137,3 +2137,11 @@ wait_for_children(ulong waitflag)
stall(1000);
}
}
+
+int minimal_functions(char *name)
+{
+ return STREQ("log", name) || STREQ("help",name) || \
+ STREQ("dis", name) || STREQ("q", name) || \
+ STREQ("sym", name) || STREQ("exit", name)|| \
+ STREQ("rd", name);
+}
diff -Naurp crash-old/defs.h crash-new/defs.h
--- crash-old/defs.h 2008-03-31 22:58:31.000000000 +0530
+++ crash-new/defs.h 2008-08-04 13:36:23.000000000 +0530
@@ -183,6 +183,7 @@ struct number_option {
#define PLEASE_WAIT (0x200000000000000ULL)
#define IFILE_ERROR (0x400000000000000ULL)
#define KERNTYPES (0x800000000000000ULL)
+#define MINIMAL_MODE (0x1000000000000000ULL)
#define ACTIVE() (pc->flags & LIVE_SYSTEM)
#define DUMPFILE() (!(pc->flags & LIVE_SYSTEM))
@@ -3129,6 +3130,7 @@ int received_SIGINT(void);
void debug_redirect(char *);
int CRASHPAGER_valid(void);
char *setup_scroll_command(void);
+int minimal_functions(char *);
/*
* tools.c
diff -Naurp crash-old/help.c crash-new/help.c
--- crash-old/help.c 2008-08-01 16:49:16.000000000 +0530
+++ crash-new/help.c 2008-08-01 16:52:28.000000000 +0530
@@ -420,12 +420,14 @@ display_help_screen(char *indent)
for (i = 0; i < rows; i++) {
namep = &pc->cmdlist[i];
for (j = 0; j < HELP_COLUMNS; j++) {
- fprintf(fp,"%-15s", *namep);
+ if(!((pc->flags & MINIMAL_MODE)&&!(minimal_functions(*namep))))
+ fprintf(fp,"%-15s", *namep);
namep += rows;
if ((namep - pc->cmdlist) >= pc->ncmds)
break;
}
- fprintf(fp,"\n%s", indent);
+ if(!(pc->flags & MINIMAL_MODE))
+ fprintf(fp,"\n%s", indent);
}
fprintf(fp, "\n%s%s version: %-6s gdb version: %s\n", indent,
diff -Naurp crash-old/main.c crash-new/main.c
--- crash-old/main.c 2008-03-31 22:58:31.000000000 +0530
+++ crash-new/main.c 2008-08-04 13:38:33.000000000 +0530
@@ -56,6 +56,7 @@ static struct option long_options[] = {
{"no_scroll", 0, 0, 0},
{"reloc", required_argument, 0, 0},
{"active", 0, 0, 0},
+ {"minimal", 0, 0, 0},
{0, 0, 0, 0}
};
@@ -197,6 +198,9 @@ main(int argc, char **argv)
kt->flags |= RELOC_SET;
}
+ else if (STREQ(long_options[option_index].name, "minimal"))
+ pc->flags |= MINIMAL_MODE;
+
else {
error(INFO, "internal error: option %s unhandled\n",
long_options[option_index].name);
@@ -492,7 +496,7 @@ main_loop(void)
#else
error(FATAL, XEN_HYPERVISOR_NOT_SUPPORTED);
#endif
- } else {
+ } else if(!(pc->flags & MINIMAL_MODE)){
read_in_kernel_config(IKCFG_INIT);
kernel_init();
machdep_init(POST_GDB);
@@ -520,7 +524,7 @@ main_loop(void)
#else
error(FATAL, XEN_HYPERVISOR_NOT_SUPPORTED);
#endif
- } else {
+ } else if(!(pc->flags & MINIMAL_MODE)){
display_sys_stats();
show_context(CURRENT_CONTEXT());
}
@@ -610,7 +614,10 @@ reattempt:
return;
pc->curcmd = pc->program_name;
- error(INFO, "command not found: %s\n", args[0]);
+ if (!(pc->flags & MINIMAL_MODE))
+ error(INFO, "command not found: %s\n", args[0]);
+ else
+ error(INFO, "command: %s not available in minimal mode\n", args[0]);
if (pc->curcmd_flags & REPEAT)
pc->curcmd_flags &= ~REPEAT;
@@ -625,6 +632,9 @@ get_command_table_entry(char *name)
{
struct command_table_entry *cp;
struct extension_table *ext;
+
+ if ((pc->flags & MINIMAL_MODE) && !minimal_functions(name))
+ return NULL;
for (cp = pc->cmd_table; cp->name; cp++) {
if (STREQ(cp->name, name))