[Top][All Lists]
[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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- GDB 6.4 Problems+Solutions,
root <=