Dear friends, I recently downloaded GDB 6.4 source code from "www.gnu.org" and built it for IA-32 RedHat Enterprise Linux Version 3 with GCC, and I found several minor gremlins, which the attached patch tries to repair. I suspect that some of these problems aren't new, but perhaps you might wish to include the repairs (in some form) in a future release. For easy recognition, they're delimited by "#ifdef MAROVICH", but feel free to remove that. The rest of this note briefly describes my problems and changes.
[s390-tdep.c] I assume that '#include "../bfd/bfd.h"' should have been just '#include "bfd.h"', since all other uses of "bfd.h" in this distribution employ the latter form. [top.c] Like many other GDB users, we also use it for remote debugging of operating-system kernels through an RS-232 interface, but most such users here need slightly different initialization commands than are ordinarily used in a "$HOME/.gdbinit" file for debugging UNIX application programs. Instead of playing clumsy games with the GDB "-nx" and "-x" command options in a "wrapper" shell script (or Bash/"C" shell "alias"), I think that a simpler solution is to: * Create a file-system link from "gdb" to an "alias" name, such as "kgdb". * Use that and "argv[0]" to dynamically construct the name of a corresponding alternate initialization file (which could obviously also be a file-system link, if desired), such as "$HOME/.kgdbinit". My patch implements this idea, and I commend it to your attention. [cli/cli-decode.c, fork-child.c] I use "-xdb" mode, and I prefer the classical use of "!" instead of "shell" to invoke a subshell command; but GDB's requirement for an extra Space after "!"; e.g., (gdb) ! command is clumsy and unnecessary when "set history expansion on" is not used. My changes parse "!" at the beginning of a command line as a 1-character "word", so that (gdb) !command then works in the traditional UNIX manner. [source.c] These changes repair an uglier problem: If a "$PATH" environment variable happens to contain an embedded null directory field (e.g., the time-honored Bourne shell idiom for "."), then GDB doesn't always correctly parse and search the current working directory; for example, consider: PATH="$HOME/bin::/bin" GDB also doesn't handle Tilde-prefix syntax that Bash and "C" shell users often use, such as: PATH="~/bin:~friend/bin:/bin" My changes fix both of these weaknesses. [cli/cli-cmds.c] These changes address an even uglier problem, involving an interaction with the Curses Library in "-tui" mode: When running a subshell command (using "!" or "shell" as above), one desires that a Carriage Return and Line Feed character be emitted both before and after the command, so that any output produced by the command will appear on separate GDB command-window lines. Unfortunately, this doesn't always happen. First, one must call the Curses "reset_{prog,shell}_mode()" subroutines around the the subprocess, but if a user doesn't employ something like "stty onlcr" before running GDB, that might not quite do the trick. A safer bet is to make GDB and Curses emit the end-of-line characters explicitly, but one must be careful about such code because (A) Curses apparently tries to avoid emitting extra end-of- line characters when it thinks that the cursor is already positioned in column 1 of a line, and (B) trying to make the Curses Library emit separate end-of-line sequences in "parent" and "child" processes is tricky if one's operating-system implements old BSD UNIX "vfork(2)" memory-sharing semantics. The code sequence shown below requires "fork(2)" instead, and it seems to solve the related headaches as well. It includes a long comment about all of this. -- Scott Marovich VMware, Inc. E-mail: [EMAIL PROTECTED] 3145 Porter Drive Tel. (650)475-5000 x522/FAX (650)475-5005 Palo Alto, California 94304 U.S.A. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *** fork-child.c.orig Wed Jul 6 07:54:33 2005 --- fork-child.c Wed Jul 6 07:54:33 2005 *************** *** 100,113 **** and tcsh. This should be good enough for now. */ if (shell_file_len < 3) return 0; ! if (shell_file[shell_file_len - 3] == 'c' && shell_file[shell_file_len - 2] == 's' && shell_file[shell_file_len - 1] == 'h') return 1; - return 0; } /* Start an inferior Unix child process and sets inferior_ptid to its --- 100,117 ---- and tcsh. This should be good enough for now. */ if (shell_file_len < 3) return 0; ! #ifdef MAROVICH ! if ( shell_file_len == 4 ! && (((shell_file[0]<<8|shell_file[1])<<8|shell_file[2])<<8|shell_file[3]) ! == ((('b'<<8|'a')<<8|'s')<<8|'h')) ! return 1; ! #endif /* MAROVICH */ if (shell_file[shell_file_len - 3] == 'c' && shell_file[shell_file_len - 2] == 's' && shell_file[shell_file_len - 1] == 'h') return 1; return 0; } /* Start an inferior Unix child process and sets inferior_ptid to its *** s390-tdep.c.orig Mon Aug 15 10:36:48 2005 --- s390-tdep.c Mon Aug 15 10:36:48 2005 *************** *** 32,40 **** #include "gdbcore.h" #include "gdbcmd.h" #include "objfiles.h" #include "tm.h" ! #include "../bfd/bfd.h" #include "floatformat.h" #include "regcache.h" #include "trad-frame.h" #include "frame-base.h" --- 32,40 ---- #include "gdbcore.h" #include "gdbcmd.h" #include "objfiles.h" #include "tm.h" ! #include "bfd.h" #include "floatformat.h" #include "regcache.h" #include "trad-frame.h" #include "frame-base.h" *** source.c.orig Mon Aug 29 05:57:49 2005 --- source.c Mon Aug 29 05:57:49 2005 *************** *** 19,26 **** --- 19,29 ---- along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifdef MAROVICH + #include <pwd.h> + #endif #include "defs.h" #include "symtab.h" #include "expression.h" #include "language.h" *************** *** 728,744 **** strcpy (filename, current_directory); } else { /* Normal file name in path -- just use it. */ strncpy (filename, p, len); filename[len] = 0; } /* Remove trailing slashes */ while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1])) filename[--len] = 0; ! strcat (filename + len, SLASH_STRING); strcat (filename, string); if (is_regular_file (filename)) --- 731,784 ---- strcpy (filename, current_directory); } else { + #ifdef MAROVICH + if (len == 0) /* change null path component to "." directory */ + { + filename[0] = '.'; + len = 1; + } + else + #endif /* MAROVICH */ /* Normal file name in path -- just use it. */ strncpy (filename, p, len); filename[len] = 0; } /* Remove trailing slashes */ while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1])) filename[--len] = 0; ! #ifdef MAROVICH ! if (filename[0] == '~') /* uh-oh! More UNIX canonicalization: */ ! { struct passwd *pw; ! char *suffix; ! ! if ((p1 = strchr (filename, '/'))) /* save directory suffix */ ! { ! *(char *)p1++ = '\0'; ! suffix = xmalloc (strlen(p1) + 1); ! strcpy (suffix, p1); ! } ! else suffix = ""; ! pw = filename[1] ? getpwnam (filename + 1) : getpwuid (getuid ()); ! if (!pw) ! { ! endpwent (); ! error (_("Can't find %s home directory"), filename); ! if (suffix[0]) xfree (suffix); ! continue; ! } ! strcpy (filename, pw->pw_dir); ! endpwent (); ! if (suffix[0]) ! { ! strcat (filename, SLASH_STRING); ! strcat (filename, suffix); ! xfree (suffix); ! } ! } ! #endif /* MAROVICH */ strcat (filename + len, SLASH_STRING); strcat (filename, string); if (is_regular_file (filename)) *** top.c.orig Tue Nov 22 11:26:41 2005 --- top.c Tue Nov 22 11:26:41 2005 *************** *** 79,90 **** --- 79,96 ---- # define PATH_MAX 512 # endif #endif + #ifdef MAROVICH + #undef GDBINIT_FILENAME + #define GDBINIT_FILENAME ".%sinit" + char gdbinit[PATH_MAX + 1]; + #else /* not MAROVICH */ #ifndef GDBINIT_FILENAME #define GDBINIT_FILENAME ".gdbinit" #endif char gdbinit[PATH_MAX + 1] = GDBINIT_FILENAME; + #endif /* MAROVICH */ int inhibit_gdbinit = 0; /* If nonzero, and GDB has been configured to be able to use windows, *************** *** 1530,1537 **** --- 1536,1550 ---- void gdb_init (char *argv0) { + #ifdef MAROVICH + register char *p = argv0 - 1; + + while (*++p); /* Scan to end of string */ + while (--p >= argv0 && *p != '/'); /* Back up over file name */ + sprintf (gdbinit, GDBINIT_FILENAME, argv0 = ++p); + #endif /* MAROVICH */ if (pre_init_ui_hook) pre_init_ui_hook (); /* Run the init function of each source file */ *** cli/cli-cmds.c.orig Tue Mar 14 17:51:50 2006 --- cli/cli-cmds.c Tue Mar 14 17:51:50 2006 *************** *** 46,53 **** --- 46,54 ---- #include "cli/cli-setshow.h" #include "cli/cli-cmds.h" #ifdef TUI + #include "gdb_curses.h" #include "tui/tui.h" /* For tui_active et.al. */ #endif /* Prototypes for local command functions */ *************** *** 482,493 **** --- 483,508 ---- shell_escape (char *arg, int from_tty) { #if defined(CANT_FORK) || \ (!defined(HAVE_WORKING_VFORK) && !defined(HAVE_WORKING_FORK)) + #ifdef MAROVICH + int rc; + + gdb_flush (gdb_stderr); + putchar_unfiltered ('\r'); + gdb_flush (gdb_stdout); + reset_shell_mode (); + /* If ARG is NULL, they want an inferior shell, but `system' just + reports if the shell is available when passed a NULL arg. */ + rc = system (arg ? arg : ""); + gdb_flush (gdb_stdout); + reset_prog_mode (); + #else /* not MAROVICH */ /* If ARG is NULL, they want an inferior shell, but `system' just reports if the shell is available when passed a NULL arg. */ int rc = system (arg ? arg : ""); + #endif /* MAROVICH */ if (!arg) arg = "inferior shell"; if (rc == -1) *************** *** 508,519 **** --- 523,565 ---- #endif #else /* Can fork. */ int rc, status, pid; + #ifdef MAROVICH + /* + * BEWARE: The following code is tricky. When using the Curses Library, we + * must force it to issue a Carriage Return character both before and + * after the command that we're about to execute, so that any command output + * appears on separate lines of the command window. (Upon arrival here, the + * cursor should be positioned just after our user's GDB command line, and + * when we're done, it should be positioned in Column 1 of a new command- + * window line.) But Curses--under RHEL3 at least--apparently won't issue a + * Carriage Return if it thinks that the cursor is already in Column 1, so we + * must separately force out a Carriage Return character in both the "parent" + * and "child" processes. But that, in turn, won't work if our host operating- + * system implements BSD UNIX "vfork(2)" semantics, where the "child" shares + * the "parent" address space until an "exec(2)" or "exit(2)" occurs. Hence, + * we really must insist upon a true "fork(2)" here, unless--as under Linux-- + * "vfork(2)" is only an alias for "fork(2)". If our host operating-system + * doesn't provide true "fork(2)" semantics somehow, we're hosed. + * --Scott Marovich, VMware Inc., March 2006. + */ + gdb_flush (gdb_stderr); + #ifndef HAVE_FORK + #error "fork(2) semantics required" + #endif /* HAVE_FORK */ + if ((pid = fork ()) == 0) + #else /* not MAROVICH */ if ((pid = vfork ()) == 0) + #endif /* MAROVICH */ { char *p, *user_shell; + #ifdef MAROVICH + putchar_unfiltered ('\r'); + gdb_flush (gdb_stdout); + reset_shell_mode (); + #endif if ((user_shell = (char *) getenv ("SHELL")) == NULL) user_shell = "/bin/sh"; /* Get the name of the shell for arg0 */ *************** *** 533,542 **** --- 579,596 ---- _exit (0177); } if (pid != -1) + #ifdef MAROVICH + { + while ((rc = wait (&status)) != pid && rc != -1); + gdb_flush (gdb_stdout); + reset_prog_mode (); + } + #else /* not MAROVICH */ while ((rc = wait (&status)) != pid && rc != -1) ; + #endif /* MAROVICH */ else error (_("Fork failed")); #endif /* Can fork. */ } *** cli/cli-decode.c.orig Thu May 26 13:49:02 2005 --- cli/cli-decode.c Tue Mar 14 17:26:36 2006 *************** *** 1023,1031 **** char *line = *text; while (**text == ' ' || **text == '\t') (*text)++; ! /* Treating underscores as part of command words is important so that "set args_foo()" doesn't get interpreted as "set args _foo()". */ /* NOTE: cagney/2003-02-13 The `tui_active' was previously --- 1023,1035 ---- char *line = *text; while (**text == ' ' || **text == '\t') (*text)++; ! #ifdef MAROVICH ! /* Special case for "!shell_command..." */ ! if (**text == '!') p = *text + 1; ! else ! #endif /* Treating underscores as part of command words is important so that "set args_foo()" doesn't get interpreted as "set args _foo()". */ /* NOTE: cagney/2003-02-13 The `tui_active' was previously *************** *** 1397,1405 **** prev_cmd = *cmd; while (*text == ' ' || *text == '\t') (text)++; ! /* Treating underscores as part of command words is important so that "set args_foo()" doesn't get interpreted as "set args _foo()". */ /* NOTE: cagney/2003-02-13 The `tui_active' was previously --- 1401,1414 ---- prev_cmd = *cmd; while (*text == ' ' || *text == '\t') (text)++; ! ! #ifdef MAROVICH ! /* Special case for "!shell_command..." */ ! if (*text == '!') p = text + 1; ! else ! #endif /* Treating underscores as part of command words is important so that "set args_foo()" doesn't get interpreted as "set args _foo()". */ /* NOTE: cagney/2003-02-13 The `tui_active' was previously - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _______________________________________________ Bug-gdb mailing list Bug-gdb@gnu.org http://lists.gnu.org/mailman/listinfo/bug-gdb