On 03/16/12 14:10, Dave Anderson wrote:
crash> set gdb Segmentation fault $
I guess it's a good hint that you typed in something incorrectly. Anyway, the problem is that I discovered that STREQ() detects a NULL pointer and does something reasonable if it is NULL. That was not the case with IS_A_NUMBER(). It is now. :) crash> set gdb gdb> set gdb crash> set gdb gdb> set gdb crash> set gdb off crash> set gdb gdb> set gdb on gdb> set gdb off crash> quit
diff --git a/cmdline.c b/cmdline.c index f5fd133..ae7edb5 100755 --- a/cmdline.c +++ b/cmdline.c @@ -131,7 +131,6 @@ process_command_line(void) check_special_handling(pc->command_line); } else { - fflush(fp); if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL) clean_exit(1); strcpy(pc->orig_line, pc->command_line); diff --git a/defs.h b/defs.h index bddf2bc..2aa0348 100755 --- a/defs.h +++ b/defs.h @@ -437,12 +437,13 @@ struct program_context { off_t ifile_offset; /* current offset into input file */ char *runtime_ifile_cmd; /* runtime command using input file */ char *kvmdump_mapfile; /* storage of physical to file offsets */ - ulonglong flags2; /* flags overrun */ -#define FLAT (0x1ULL) -#define ELF_NOTES (0x2ULL) -#define GET_OSRELEASE (0x4ULL) -#define REMOTE_DAEMON (0x8ULL) + ulonglong flags2; /* flags overrun */ +#define FLAT (0x01ULL) +#define ELF_NOTES (0x02ULL) +#define GET_OSRELEASE (0x04ULL) +#define REMOTE_DAEMON (0x08ULL) #define ERASEINFO_DATA (0x10ULL) +#define GDB_CMD_MODE (0x20ULL) #define FLAT_FORMAT() (pc->flags2 & FLAT) #define ELF_NOTES_VALID() (pc->flags2 & ELF_NOTES) char *cleanup; diff --git a/gdb_interface.c b/gdb_interface.c index fa642bb..7601799 100755 --- a/gdb_interface.c +++ b/gdb_interface.c @@ -750,23 +750,40 @@ void cmd_gdb(void) { char buf[BUFSIZE]; + char ** av = args; - if (!args[optind]) + if ((pc->flags2 & GDB_CMD_MODE) == 0) + av++; + + if (*av == NULL) cmd_usage(pc->curcmd, SYNOPSIS); - /* - * Intercept set commands in case something has to be done here. - */ - if (STREQ(args[1], "set")) { - if (args[2] && args[3] && STREQ(args[2], "output-radix")) { - pc->output_radix = stol(args[3], FAULT_ON_ERROR, NULL); - } - } + if (STREQ(*av, "set")) { + if (av[1] == NULL) { + fprintf(stderr, "argument to 'set' required\n"); + return; + } + + if (STREQ(av[1], "gdb")) { + /* + * someone typed "set gdb". We do it, not GDB. + */ + cmd_set(); + return; + } + + /* + * Intercept set commands in case something has to be done here. + */ + if (STREQ(av[1], "output-radix") && av[2]) { + pc->output_radix = stol(av[2], FAULT_ON_ERROR, NULL); + } + } /* * If the command is not restricted, pass it on. */ - if (!is_restricted_command(args[1], FAULT_ON_ERROR)) { + if (!is_restricted_command(*av, FAULT_ON_ERROR)) { if (STREQ(pc->command_line, "gdb")) { strcpy(buf, &pc->orig_line[3]); strip_beginning_whitespace(buf); @@ -934,6 +951,12 @@ get_frame_offset(ulong pc) return (error(FATAL, "get_frame_offset: invalid request for non-alpha systems!\n")); } -#endif /* !ALPHA */ - - +#endif /* !ALPHA */ +/* + * Local Variables: + * mode: C + * c-file-style: "k&r" + * indent-tabs-mode: nil + * c-basic-offset: 8 + * End: + */ diff --git a/main.c b/main.c index 043f9f0..6de1808 100755 --- a/main.c +++ b/main.c @@ -798,6 +798,9 @@ get_command_table_entry(char *name) { struct command_table_entry *cp; struct extension_table *ext; + + if (pc->flags2 & GDB_CMD_MODE) + name = "gdb"; if ((pc->flags & MINIMAL_MODE) && !minimal_functions(name)) return NULL; @@ -1721,3 +1724,11 @@ get_osrelease(char *dumpfile) clean_exit(retval); } +/* + * Local Variables: + * mode: C + * c-file-style: "k&r" + * indent-tabs-mode: nil + * c-basic-offset: 8 + * End: + */ diff --git a/tools.c b/tools.c index 78fc493..9ee05b0 100755 --- a/tools.c +++ b/tools.c @@ -17,6 +17,7 @@ #include "defs.h" #include <ctype.h> +#include <stdbool.h> static void print_number(struct number_option *, int, int); static long alloc_hq_entry(void); @@ -388,7 +389,7 @@ strip_comma(char *line) { char *p; - if ((p = strstr(line, ","))) + if ((p = strchr(line, ','))) *p = NULLCHAR; return(line); @@ -554,6 +555,9 @@ stol(char *s, int flags, int *errptr) return(htol(s, flags, errptr)); } + if (s == NULL) + s = "(NULL)"; + if (!(flags & QUIET)) error(INFO, "not a valid number: %s\n", s); @@ -583,6 +587,9 @@ stoll(char *s, int flags, int *errptr) return(htoll(s, flags, errptr)); } + if (s == NULL) + s = "(NULL)"; + if (!(flags & QUIET)) error(INFO, "not a valid number: %s\n", s); @@ -1020,6 +1027,9 @@ decimal(char *s, int count) char *p; int cnt; + if (s == NULL) + return FALSE; + if (!count) { strip_line_end(s); cnt = 0; @@ -1125,6 +1135,9 @@ hexadecimal(char *s, int count) char *p; int cnt; + if (s == NULL) + return FALSE; + if (!count) { strip_line_end(s); cnt = 0; @@ -1187,6 +1200,9 @@ hexadecimal_only(char *s, int count) char *p; int cnt, only; + if (s == NULL) + return FALSE; + if (!count) { strip_line_end(s); cnt = 0; @@ -1690,6 +1706,55 @@ backspace(int cnt) fprintf(fp, "\b"); } +static bool +set_on_or_off(char * arg, ulong * res) +{ + if ((arg == NULL) || STREQ(arg, "on")) { + *res = 1; + return true; + } + if (STREQ(arg, "off")) { + *res = 0; + return true; + } + if (IS_A_NUMBER(arg)) { + *res = stol(arg, FAULT_ON_ERROR, NULL); + return true; + } + return false; +} + +static bool +do_set_gdb(void) +{ + static char * sv_p = NULL; + + char * arg = args[optind+1]; + ulong v; + + if (sv_p == NULL) + sv_p = pc->prompt; + + if (arg == NULL) + v = ! (pc->flags2 & GDB_CMD_MODE); + + else if (! set_on_or_off(arg, &v)) + return false; + + if (v) { + pc->flags2 |= GDB_CMD_MODE; + pc->prompt = "gdb> "; + + } else { + pc->flags2 &= ~GDB_CMD_MODE; + + if (sv_p != NULL) + pc->prompt = sv_p; + } + + return true; +} + /* * Set/display process context or internal variables. Processes are set * by their task or PID number, or to the panic context with the -p flag. @@ -2286,6 +2351,11 @@ cmd_set(void) "on" : "off"); return; + } else if (STREQ(args[optind], "gdb")) { + if (! do_set_gdb()) + goto invalid_set_command; + return; + } else if (XEN_HYPER_MODE()) { error(FATAL, "invalid argument for the Xen hypervisor\n"); } else if (pc->flags & MINIMAL_MODE) { @@ -2324,7 +2394,7 @@ cmd_set(void) invalid_set_command: - sprintf(buf, "invalid command"); + strcpy(buf, "invalid command"); if (!runtime) sprintf(&buf[strlen(buf)], " in .%src file", pc->program_name); strcat(buf, ": "); @@ -4914,3 +4984,11 @@ make_cpumask_error: return UNUSED; } +/* + * Local Variables: + * mode: C + * c-file-style: "k&r" + * indent-tabs-mode: nil + * c-basic-offset: 8 + * End: + */
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility