bug-gdb
[Top][All Lists]
Advanced

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

GDB 6.4 Problems+Solutions


From: root
Subject: GDB 6.4 Problems+Solutions
Date: Sat, 18 Mar 2006 15:16:05 -0800

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: address@hidden                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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -




reply via email to

[Prev in Thread] Current Thread [Next in Thread]