Thread View: gnu.gdb.bug
1 messages
1 total messages
Started by root
Sat, 18 Mar 2006 23:16
GDB 6.4 Problems+Solutions
Author: root
Date: Sat, 18 Mar 2006 23:16
Date: Sat, 18 Mar 2006 23:16
433 lines
16321 bytes
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