Re: "gdb" by itself ought to put crash into a "gdb" mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux