From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18386 invoked by alias); 5 Jul 2006 21:58:01 -0000 Received: (qmail 18373 invoked by uid 22791); 5 Jul 2006 21:58:00 -0000 X-Spam-Check-By: sourceware.org Received: from nile.gnat.com (HELO nile.gnat.com) (205.232.38.5) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 05 Jul 2006 21:57:58 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-nile.gnat.com (Postfix) with ESMTP id 14D0048CDAA for ; Wed, 5 Jul 2006 17:56:08 -0400 (EDT) Received: from nile.gnat.com ([127.0.0.1]) by localhost (nile.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 07835-01-10 for ; Wed, 5 Jul 2006 17:56:07 -0400 (EDT) Received: from takamaka.act-europe.fr (S0106000625ac85e1.vs.shawcable.net [70.71.27.110]) by nile.gnat.com (Postfix) with ESMTP id 5E8A648CC53 for ; Wed, 5 Jul 2006 17:56:07 -0400 (EDT) Received: by takamaka.act-europe.fr (Postfix, from userid 507) id C39BC47E7F; Wed, 5 Jul 2006 14:56:06 -0700 (PDT) Date: Wed, 05 Jul 2006 21:58:00 -0000 From: Joel Brobecker To: gdb-patches@sources.redhat.com Subject: [RFA] New substitute-path commands Message-ID: <20060705215606.GF3580@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="ikeVEW9yuYc//A+q" Content-Disposition: inline User-Agent: Mutt/1.4i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00014.txt.bz2 --ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 3983 Hello, Following up on a discussing that took place on the gdb@ mailing list: http://sources.redhat.com/ml/gdb/2006-06/msg00192.html I implemented a new set of commands that should be useful in the case when a developer debugs a program of which the source tree has been moved to a different location from where it was compiled. The new commands are: (gdb) substitute-path add (gdb) substitute-path remove (gdb) substitute-path * "substitute-path add" adds a substitution rule, where the first instance of is replaced by . * "substitute-path remove" removes the current substitution rule if one was specified. No effect otherwise. * "substitute-path" prints the current substitution rule. Some users argued that "substitute-path show" should also be added. I think it's mostly aesthetic, and hence passed on this suggestion, but I can do that as well if others think it'd be nice to have it. At least one user suggested that we provide the possibility of applying a list of substitution rules as opposed to one. I'm not against that idea, but this makes the design and implementation slightly more complex for something that I think will be little used. I suspect that most people will use it in a very specific context where the entire source tree has been moved - so one substitution rule should be enough. Nonetheless, should anybody require this feature, there is an upward compatible way of enhancing my implementation later on. The "add" command remains the same. The "remove" command without any argument would delete all substitution rules. And with a "from" argument, it would remove the rule that matches "from". The "substitute-path" command would print all substitution rules, not just the one. Here is how I tested it: * In a root directory, I have some sources in src/ * cd to src/, and compile the sources * cd , cp -R src dup * cd src/, modify one line of my source file * gdb dup/my_program (gdb) substitute-path add src dup (gdb) list my_program.c:1 With the current debugger, GDB will list src/my_program.c. But in fact, this is no longer the file that was used to build the program we're actually debugging. With the patch I am suggesting, the debugger lists dup/my_program.c. The "substitute-path" has two uses that I can see, each of them when the path to the source tree available to GDB is different from the path when the program was built: . 1: The path to the source tree is no longer valid for whatever reason. In that case, the "dir" command can be used to point GDB to the current location. But larger programs may use a full tree of directories, making it painful because one has to use a series of "dir" commands, one per directory. This new command makes it easier. . 2: The path to the source tree is still valid. This is the case I explained in my message on gdb@. Please refer to it for more details. In this case, this new command is the only way to make sure GDB uses the right sources. Question: Is a MI equivalent needed? 2006-07-05 Joel Brobecker = 0) return result; @@ -869,6 +931,27 @@ find_and_open_source (struct objfile *ob if (dirname != NULL) { + /* If necessary, rewrite the compilation directory name according + to the source path substitution rules specified by the user. + + Normally, we should really try to do the rewrite on the entire + path as opposed to just the directory name, but that's making + things much more complicated since we now have to concat the + dirname and filename, apply the substitution rule, and then do + [...] ??? How do we split the path back into dirname and filename? + In practice, the source path substitution feature should be used + when the entire tree has been moved, in which case only the root + part of the tree path will need to be rewritten. So this should + not be a problem in practice. */ + + char *rewritten_dirname = xrewrite_source_path (dirname); + + if (rewritten_dirname != NULL) + { + make_cleanup (xfree, rewritten_dirname); + dirname = rewritten_dirname; + } + /* Replace a path entry of $cdir with the compilation directory name */ #define cdir_len 5 /* We cast strstr's result in case an ANSIhole has made it const, @@ -1587,6 +1670,129 @@ reverse_search_command (char *regex, int fclose (stream); return; } + +/* Print the current source path substitution rule. */ + +static void +substitute_path_command (char *args, int from_tty) +{ + if (substitute_path_from == NULL) + printf_filtered (_("No source path substitution rule specified.\n")); + else + printf_filtered (_("`%s' in source paths now substituted with `%s'.\n"), + substitute_path_from, substitute_path_to); +} + +/* Extract the first argument (possibly quoted) from ARGS, and return it. + ARGS is updated to point right after that first argument. + The returned value must be deallocated afterwards. + + Return NULL is an argument could not be found. */ + +static char * +xextract_path_argument (char **args) +{ + int is_quoted; + char *p; + int arg_len; + char *path; + + /* First, skip any leading white spaces, and check that we have + at least one character left after the trimming. */ + + while (isspace (**args)) + (*args)++; + + if (**args == '\0') + return NULL; + + /* Find the first character after the first argument. */ + + p = skip_quoted_chars (*args, NULL, " \t"); + arg_len = p - *args; + + /* If the path was quoted, then remove the quotes. */ + + is_quoted = (strchr (get_gdb_completer_quote_characters (), **args) != NULL); + if (is_quoted) + { + if (strchr (get_gdb_completer_quote_characters (), + (*args)[arg_len - 1]) == NULL) + error (_("missing closing quote in argument: %s"), *args); + + arg_len -= 2; + (*args)++; + } + + /* If the argument is empty, then there is no real path, and hence + treat this as if the argumet was missing. */ + + if (arg_len < 1) + return NULL; + + path = (char *) xmalloc ((arg_len + 1) * sizeof (char)); + strncpy (path, *args, arg_len); + path[arg_len] = '\0'; + + *args = p; + + return path; +} + +/* Delete the current source path substitution rule. */ + +static void +substitute_path_remove_command (char *args, int from_tty) +{ + if (substitute_path_from != NULL) + { + xfree (substitute_path_from); + substitute_path_from = NULL; + } + + if (substitute_path_to != NULL) + { + xfree (substitute_path_to); + substitute_path_to = NULL; + } +} + +/* Add a new source path substitution rule. */ + +static void +substitute_path_add_command (char *args, int from_tty) +{ + char *from_path, *to_path; + + /* Extract the arguments from the command line. */ + + if (args == NULL) + error (_("Argument missing in command")); + + from_path = xextract_path_argument (&args); + if (from_path == NULL) + error (_("Argument missing in command")); + + to_path = xextract_path_argument (&args); + if (to_path == NULL) + { + xfree (from_path); + error (_("Argument missing in command")); + } + + /* Remove any previous substitution rule. */ + + substitute_path_remove_command (NULL, from_tty); + + /* Insert the new substitution rule, and print a confirmation message + to the user. */ + + substitute_path_from = from_path; + substitute_path_to = to_path; + + substitute_path_command (NULL, from_tty); +} + void _initialize_source (void) @@ -1666,4 +1872,22 @@ Show number of source lines gdb will lis NULL, show_lines_to_list, &setlist, &showlist); + + add_prefix_cmd ("substitute-path", class_files, substitute_path_command, + _("Show the current source path substitution rule."), + &substitute_path_cmdlist, "substitute-path ", + 0 /* allow-unknown */, &cmdlist); + + add_cmd ("add", class_files, substitute_path_add_command, + _("\ +Add a source path substitution rule. If a substitution rule was previously\n\ +set, it is overridden."), + &substitute_path_cmdlist); + + add_cmd ("remove", class_files, substitute_path_remove_command, + _("\ +Remove the current source path substitution rule. Has no effect\n\ +if no path substitution rule was previously specified."), + &substitute_path_cmdlist); + } --ikeVEW9yuYc//A+q--