🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gdb.bug
Article #1212

GDB 6.4 Problems+Solutions

#1212
From: root
Date: Sat, 18 Mar 2006 23:16
433 lines
16321 bytes
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: marovich@vmware.com                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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Technical Details
Message-ID: <mailman.12.1142765767.3796.bug-gdb@gnu.org>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!newsfeed.stanford.edu!shelby.stanford.edu!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: f5053,8532b07f950edba1,start
X-Google-Attributes: gidf5053,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!newsfeed.stanford.edu!shelby.stanford.edu!not-for-mail
From: root <root@vmware.com>
Newsgroups: gnu.gdb.bug
Subject: GDB 6.4 Problems+Solutions
Date: Sat, 18 Mar 2006 15:16:05 -0800
Lines: 435
Approved: bug-gdb@gnu.org
Message-ID: <mailman.12.1142765767.3796.bug-gdb@gnu.org>
Reply-To: marovich@vmware.com
NNTP-Posting-Host: lists.gnu.org
X-Trace: news.Stanford.EDU 1142765768 10645 199.232.76.165 (19 Mar 2006 10:56:08 GMT)
X-Complaints-To: news@news.stanford.edu
Cc: marovich@vmware.com
To: bug-gdb@gnu.org
Envelope-to: bug-gdb@gnu.org
X-Mailman-Approved-At: Sun, 19 Mar 2006 05:56:05 -0500
X-BeenThere: bug-gdb@gnu.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: "Bug reports for GDB, the GNU debugger" <bug-gdb.gnu.org>
List-Unsubscribe: <http://lists.gnu.org/mailman/listinfo/bug-gdb>,
 <mailto:bug-gdb-request@gnu.org?subject=unsubscribe>
List-Archive: <http://lists.gnu.org/pipermail/bug-gdb>
List-Post: <mailto:bug-gdb@gnu.org>
List-Help: <mailto:bug-gdb-request@gnu.org?subject=help>
List-Subscribe: <http://lists.gnu.org/mailman/listinfo/bug-gdb>,
 <mailto:bug-gdb-request@gnu.org?subject=subscribe>