🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by root Sat, 18 Mar 2006 23:16
GDB 6.4 Problems+Solutions
#1212
Author: 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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads