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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility