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/14/12 06:37, Dave Anderson wrote:

Well, ok, I kept stumble fingering the gdb commands, so here's a working patch.
Under the covers, the "cmd_gdb" peeks into the command when it sees it is a
"set" command.  It already does this.  But if it is a "set gdb" command, then
it just redirects to the internal "cmd_set" function.  I also jiggered the
arguments to accommodate the fact that the first argument is no longer "gdb".
And I fixed the prompt to be "gdb> " to distinguish from both "crash> " and
"(gdb) ".  I also really hate procedures that go beyond 100 lines or so,
so I did not add to the cmd_set length.
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..ea5d9c1 100755
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -750,23 +750,35 @@ 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 (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 +946,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..a82a481 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);
@@ -1690,6 +1691,159 @@ backspace(int cnt)
 		fprintf(fp, "\b");
 }
 
+static bool
+cmd_set_opts(int runtime)
+{
+        for (;;) {
+                int c = getopt(argcnt, args, "pvc:a:");
+                int cpu;
+                ulong value;
+                struct task_context *tc;
+
+                switch(c)
+                {
+                case EOF: return false;
+
+                case 'c':
+                        if (XEN_HYPER_MODE() || (pc->flags & MINIMAL_MODE))
+                                option_not_supported(c);
+
+                        if (!runtime)
+                                return true;
+
+                        if (ACTIVE()) {
+                                error(INFO, "not allowed on a live system\n");
+                                argerrs++;
+                                break;
+                        }
+                        cpu = dtoi(optarg, FAULT_ON_ERROR, NULL);
+                        set_cpu(cpu);
+                        return true;
+
+                case 'p':
+                        if (XEN_HYPER_MODE() || (pc->flags & MINIMAL_MODE))
+                                option_not_supported(c);
+
+                        if (!runtime)
+                                return true;
+
+                        if (ACTIVE()) {
+                                set_context(NO_TASK, pc->program_pid);
+                                show_context(CURRENT_CONTEXT());
+                                return true;
+                        }
+
+                        if (!tt->panic_task) {
+                                error(INFO, "no panic task found!\n");
+                                return true;
+                        }
+                        set_context(tt->panic_task, NO_PID);
+                        show_context(CURRENT_CONTEXT());
+                        return true;
+
+                case 'v':
+                        if (!runtime)
+                                return true;
+
+                        show_options();
+                        return true;
+
+                case 'a':
+                        if (XEN_HYPER_MODE() || (pc->flags & MINIMAL_MODE))
+                                option_not_supported(c);
+
+                        if (!runtime)
+                                return true;
+
+                        if (ACTIVE())
+                                error(FATAL, 
+                                    "-a option not allowed on live systems\n");
+
+                        switch (str_to_context(optarg, &value, &tc))
+                        {
+                                int i;
+
+                        case STR_PID:
+                                if ((i = TASKS_PER_PID(value)) > 1)
+                                        error(FATAL, 
+                                            "pid %d has %d tasks: "
+                                            "use a task address\n",
+                                                value, i);
+                                break;
+        
+                        case STR_TASK:
+                                break;
+        
+                        case STR_INVALID:
+                                error(FATAL, "invalid task or pid value: %s\n",
+                                        optarg);
+                        }
+                
+                        cpu = tc->processor;
+                        tt->active_set[cpu] = tc->task;
+                        if (tt->panic_threads[cpu])
+                                tt->panic_threads[cpu] = tc->task;
+                        fprintf(fp, "\"%s\" task %lx has been marked as the "
+                                "active task on cpu %d\n",
+                                tc->comm, tc->task, cpu);
+                        return true;
+
+                default:
+                        argerrs++;
+                        break;
+                }
+        }
+}
+
+static bool
+set_on_or_off(char * arg, ulong * res)
+{
+        if (STREQ(arg, "on")) {
+                *res = 1;
+                return true;
+        }
+        if (STREQ(arg, "off")) {
+                *res = 0;
+                return true;
+        }
+        if (IS_A_NUMBER(arg))
+                return stol(arg, FAULT_ON_ERROR, NULL);
+        return false;
+}
+
+static bool
+do_set_gdb(void)
+{
+        static char * sv_p = NULL;
+
+        char * arg = args[optind];
+        ulong v;
+
+        if (arg == NULL)
+                return;
+
+        if (sv_p == NULL)
+                sv_p = pc->prompt;
+
+        optind++;
+
+        if (! set_on_or_off(args[optind], &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.
@@ -1725,10 +1879,9 @@ cmd_set(void)
 {
 	int i, c;
 	ulong value;
-	int cpu, runtime, from_rc_file;
+	int runtime, from_rc_file;
 	char buf[BUFSIZE];
 	char *extra_message;
-	struct task_context *tc;
 
 #define defer()  do { } while (0)
 #define already_done()  do { } while (0)
@@ -1736,97 +1889,8 @@ cmd_set(void)
 	extra_message = NULL;
 	runtime = pc->flags & RUNTIME ? TRUE : FALSE;
 	from_rc_file = pc->curcmd_flags & FROM_RCFILE ? TRUE : FALSE;
-
-        while ((c = getopt(argcnt, args, "pvc:a:")) != EOF) {
-                switch(c)
-		{
-		case 'c':
-			if (XEN_HYPER_MODE() || (pc->flags & MINIMAL_MODE))
-				option_not_supported(c);
-
-			if (!runtime)
-				return;
-
-		        if (ACTIVE()) {
-                		error(INFO, "not allowed on a live system\n");
-				argerrs++;
-				break;
-			}
-			cpu = dtoi(optarg, FAULT_ON_ERROR, NULL);
-			set_cpu(cpu);
-			return;
-
-		case 'p':
-			if (XEN_HYPER_MODE() || (pc->flags & MINIMAL_MODE))
-				option_not_supported(c);
-
-			if (!runtime)
-				return;
-
-			if (ACTIVE()) {
-				set_context(NO_TASK, pc->program_pid);
-				show_context(CURRENT_CONTEXT());
-				return;
-			}
-
-			if (!tt->panic_task) {
-                		error(INFO, "no panic task found!\n");
-				return;
-			}
-        		set_context(tt->panic_task, NO_PID);
-			show_context(CURRENT_CONTEXT());
-			return;
-
-		case 'v':
-			if (!runtime)
-				return;
-
-			show_options();
-			return;
-
-		case 'a':
-			if (XEN_HYPER_MODE() || (pc->flags & MINIMAL_MODE))
-				option_not_supported(c);
-
-			if (!runtime)
-				return;
-
-			if (ACTIVE())
-				error(FATAL, 
-				    "-a option not allowed on live systems\n");
-
-	                switch (str_to_context(optarg, &value, &tc))
-	                {
-	                case STR_PID:
-				if ((i = TASKS_PER_PID(value)) > 1)
-					error(FATAL, 
-					    "pid %d has %d tasks: "
-					    "use a task address\n",
-						value, i);
-	                        break;
-	
-	                case STR_TASK:
-	                        break;
-	
-	                case STR_INVALID:
-	                        error(FATAL, "invalid task or pid value: %s\n",
-	                                optarg);
-	                }
-		
-			cpu = tc->processor;
-			tt->active_set[cpu] = tc->task;
-			if (tt->panic_threads[cpu])
-				tt->panic_threads[cpu] = tc->task;
-			fprintf(fp, 
-			    "\"%s\" task %lx has been marked as the active task on cpu %d\n",
-				tc->comm, tc->task, cpu);
-			return;
-
-		default:
-			argerrs++;
-			break;
-		}
-	}
+        if (cmd_set_opts(runtime))
+                return;
 
 	if (argerrs) {
 		if (runtime)
@@ -1851,14 +1915,8 @@ cmd_set(void)
                                 optind++;
 				if (!runtime)
 					defer();
-                                else if (STREQ(args[optind], "on"))
-                                        pc->debug = 1;
-                                else if (STREQ(args[optind], "off"))
-                                        pc->debug = 0;
-				else if (IS_A_NUMBER(args[optind])) 
-					pc->debug = stol(args[optind], 
-						FAULT_ON_ERROR, NULL);
-				else
+                                else if (! set_on_or_off(args[optind],
+                                                         &pc->debug))
 					goto invalid_set_command;
                         }
 			if (runtime)
@@ -1870,22 +1928,16 @@ cmd_set(void)
 
                 } else if (STREQ(args[optind], "hash")) {
                         if (args[optind+1]) {
+                                ulong v;
                                 optind++;
 				if (!runtime)
 					defer();
-                                else if (STREQ(args[optind], "on"))
+                                else if (! set_on_or_off(args[++optind], &v))
+                                        goto invalid_set_command;
+                                else if (v)
                                         pc->flags |= HASH;
-                                else if (STREQ(args[optind], "off"))
+                                else
                                         pc->flags &= ~HASH;
-				else if (IS_A_NUMBER(args[optind])) {
-					value = stol(args[optind],
-                                    		FAULT_ON_ERROR, NULL);
-					if (value)
-						pc->flags |= HASH;
-					else
-						pc->flags &= ~HASH;
-				} else
-					goto invalid_set_command;
                         }
 
 			if (runtime)
@@ -2286,12 +2338,18 @@ 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) {
 			error(FATAL, "invalid argument in minimal mode\n");
 		} else if (runtime) {
 			ulong pid, task;
+                        struct task_context *tc;
 
 	                switch (str_to_context(args[optind], &value, &tc))
 	                {
@@ -2324,7 +2382,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 +4972,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