Browse Source

* infrun.c, infcmd.c, breakpoint.c, main.c, symfile.c,

breakpoint.h, tm-sun4os4.h, tm-sparc.h, sparc-tdep.c, tm-mips.h,
mips-tdep.h, tm-sun3.h, tm-68k.h, m68k-tdep.h:  Add support for
stepping (and nexting) through longjmp().  Also, cleanup
breakpoint handling quite a bit by creating explicit breakpoint
types instead of using magic breakpoint numbers.
Makefile.in:  Update version to 4.4.3
gdb-4_18-branch
Stu Grossman 35 years ago
parent
commit
30875e1c4b
  1. 10
      gdb/ChangeLog
  2. 20
      gdb/Makefile.in
  3. 669
      gdb/breakpoint.c
  4. 216
      gdb/breakpoint.h
  5. 325
      gdb/infrun.c
  6. 190
      gdb/main.c
  7. 824
      gdb/symfile.c
  8. 6
      gdb/tm-68k.h
  9. 16
      gdb/tm-mips.h
  10. 1
      gdb/tm-sparc.h
  11. 31
      gdb/tm-sun3.h
  12. 25
      gdb/tm-sun4os4.h

10
gdb/ChangeLog

@ -1,3 +1,13 @@
Sat Feb 22 00:56:39 1992 Stu Grossman (grossman at cygnus.com)
* infrun.c, infcmd.c, breakpoint.c, main.c, symfile.c,
breakpoint.h, tm-sun4os4.h, tm-sparc.h, sparc-tdep.c, tm-mips.h,
mips-tdep.h, tm-sun3.h, tm-68k.h, m68k-tdep.h: Add support for
stepping (and nexting) through longjmp(). Also, cleanup
breakpoint handling quite a bit by creating explicit breakpoint
types instead of using magic breakpoint numbers.
Makefile.in: Update version to 4.4.3
Sat Feb 22 00:08:50 1992 John Gilmore (gnu at cygnus.com)
* xm-sun3os4.h, xm-sun4os4.h: Enable HAVE_MMAP.

20
gdb/Makefile.in

@ -1,4 +1,4 @@
##Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
#Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
# This file is part of GDB.
@ -49,9 +49,6 @@ RANLIB = ranlib
# This can be overridden in the host Makefile fragment file.
TERMCAP = -ltermcap
#### Host, target, and site specific Makefile fragments come in here.
###
# Host and target-dependent makefile fragments come in here.
####
# End of host and target-dependent makefile fragments
@ -161,7 +158,7 @@ CDEPS = ${XM_CDEPS} ${TM_CDEPS} ${BFD_LIB} ${LIBIBERTY} ${RL_LIB}
ADD_FILES = ${REGEX} ${ALLOCA} ${GNU_MALLOC} ${XM_ADD_FILES} ${TM_ADD_FILES}
ADD_DEPS = ${REGEX1} ${ALLOCA1} ${GNU_MALLOC} ${XM_ADD_FILES} ${TM_ADD_FILES}
VERSION = 4.5
VERSION = 4.4.3
DIST=gdb
LINT=/usr/5bin/lint
@ -173,12 +170,13 @@ LINTFLAGS= -I${BFD_DIR}
SFILES_MAINDIR = \
blockframe.c breakpoint.c command.c core.c \
environ.c eval.c expprint.c findvar.c infcmd.c inflow.c infrun.c \
main.c printcmd.c \
main.c printcmd.c gdbtypes.c \
remote.c source.c stack.c symmisc.c symtab.c symfile.c \
utils.c valarith.c valops.c valprint.c values.c c-exp.y m2-exp.y \
signame.c cplus-dem.c mem-break.c target.c inftarg.c \
dbxread.c coffread.c elfread.c dwarfread.c xcoffread.c \
ieee-float.c language.c parse.c buildsym.c
ieee-float.c language.c parse.c buildsym.c state.c objfiles.c \
minsyms.c mmap-alloc.c mmap-sbrk.c
# Source files in subdirectories (which will be handled separately by
# 'make gdb.tar.Z').
@ -221,9 +219,9 @@ SFILES_KGDB = $(SFILES) stuff.c kdb-start.c
# Header files that are not named in config/* Makefile fragments go here.
HFILES= breakpoint.h buildsym.h command.h defs.h environ.h \
expression.h frame.h gdbcmd.h gdbcore.h \
expression.h frame.h gdbcmd.h gdbcore.h gdbtypes.h \
ieee-float.h inferior.h minimon.h partial-stab.h \
signals.h signame.h symfile.h symtab.h \
signals.h signame.h symfile.h symtab.h state.h solib.h \
target.h terminal.h tm-68k.h tm-i960.h tm-sunos.h tm-sysv4.h \
xm-m68k.h xm-sysv4.h language.h parser-defs.h value.h
@ -263,10 +261,10 @@ TARFILES = ${TAGFILES_MAINDIR} ${OTHERS} ${REMOTE_EXAMPLES}
OBS = main.o blockframe.o breakpoint.o findvar.o stack.o source.o \
values.o eval.o valops.o valarith.o valprint.o printcmd.o \
symtab.o symfile.o symmisc.o infcmd.o infrun.o remote.o \
command.o utils.o expprint.o environ.o version.o \
command.o utils.o expprint.o environ.o version.o gdbtypes.o \
copying.o $(DEPFILES) signame.o cplus-dem.o mem-break.o target.o \
inftarg.o ieee-float.o putenv.o parse.o language.o $(YYOBJ) \
buildsym.o \
buildsym.o state.o objfiles.o minsyms.o mmap-alloc.o mmap-sbrk.o \
dbxread.o coffread.o elfread.o dwarfread.o xcoffread.o # mipsread.o
RAPP_OBS = rgdb.o rudp.o rserial.o serial.o udp.o $(XDEPFILES)

669
gdb/breakpoint.c

File diff suppressed because it is too large

216
gdb/breakpoint.h

@ -1,69 +1,118 @@
/* Copyright (C) 1990 Free Software Foundation, Inc.
/* Copyright (C) 1992 Free Software Foundation, Inc.
This file is part of GDB.
GDB is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GDB is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GDB; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (BREAKPOINT_H)
#define BREAKPOINT_H 1
#include "frame.h"
#include "value.h"
/* This is the maximum number of bytes a breakpoint instruction can take.
Feel free to increase it. It's just used in a few places to size
arrays that should be independent of the target architecture. */
#define BREAKPOINT_MAX 10
extern void breakpoint_re_set ();
extern void clear_momentary_breakpoints ();
extern void set_momentary_breakpoint ();
extern void set_ignore_count ();
extern void set_default_breakpoint ();
typedef struct bpstat__struct *bpstat;
#ifdef __STDC__ /* Forward declarations for prototypes */
struct frame_info;
#endif
extern int
breakpoint_here_p PARAMS ((CORE_ADDR));
extern void
until_break_command PARAMS ((char *, int));
extern void
breakpoint_re_set PARAMS ((void));
extern void
clear_momentary_breakpoints PARAMS ((void));
/* FIXME: Prototype uses equivalence of "struct frame_info *" and FRAME */
extern struct breakpoint *
set_momentary_breakpoint PARAMS ((struct symtab_and_line,
struct frame_info *,
enum bptype));
extern void
set_ignore_count PARAMS ((int, int, int));
extern void
set_default_breakpoint PARAMS ((int, CORE_ADDR, struct symtab *, int));
extern void mark_breakpoints_out ();
extern void breakpoint_auto_delete ();
extern void breakpoint_clear_ignore_counts ();
extern void
mark_breakpoints_out PARAMS ((void));
extern void
delete_breakpoint PARAMS ((struct breakpoint *));
extern void
breakpoint_auto_delete PARAMS ((bpstat));
extern void
breakpoint_clear_ignore_counts PARAMS ((void));
extern void
break_command PARAMS ((char *, int));
extern int
insert_breakpoints PARAMS ((void));
extern int
remove_breakpoints PARAMS ((void));
/* The following are for displays, which aren't really breakpoints, but
here is as good a place as any for them. */
extern void disable_current_display ();
extern void do_displays ();
extern void disable_display ();
extern void clear_displays ();
extern void
disable_current_display PARAMS ((void));
extern void
do_displays PARAMS ((void));
extern void
disable_display PARAMS ((int));
extern void
clear_displays PARAMS ((void));
/* The follow stuff is an abstract data type "bpstat" ("breakpoint status").
This provides the ability to determine whether we have stopped at a
breakpoint, and what we should do about it. */
typedef struct bpstat__struct *bpstat;
/* Interface: */
/* Clear a bpstat so that it says we are not at any breakpoint.
Also free any storage that is part of a bpstat. */
void bpstat_clear();
extern void bpstat_clear PARAMS ((bpstat *));
/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
is part of the bpstat is copied as well. */
bpstat bpstat_copy();
extern bpstat bpstat_copy PARAMS ((bpstat));
/* Get a bpstat associated with having just stopped at address *PC
and frame address FRAME_ADDRESS. Update *PC to point at the
breakpoint (if we hit a breakpoint). */
bpstat bpstat_stop_status (/* CORE_ADDR *pc; FRAME_ADDR frame_address */);
/* FIXME: prototypes uses equivalence between FRAME_ADDR and CORE_ADDR */
extern bpstat bpstat_stop_status PARAMS ((CORE_ADDR *, CORE_ADDR));
/* Nonzero if we should print the frame. */
#define bpstat_should_print(bs) ((bs) != NULL && (bs)->print)
@ -71,6 +120,9 @@ bpstat bpstat_stop_status (/* CORE_ADDR *pc; FRAME_ADDR frame_address */);
/* Nonzero if we should stop. */
#define bpstat_stop(bs) ((bs) != NULL && (bs)->stop)
/* Find the bpstat associated with a breakpoint. NULL otherwise. */
bpstat bpstat_find_breakpoint(/* bpstat, breakpoint */);
/* Nonzero if we hit a momentary breakpoint. */
#define bpstat_momentary_breakpoint(bs) ((bs) != NULL && (bs)->momentary)
@ -82,29 +134,27 @@ bpstat bpstat_stop_status (/* CORE_ADDR *pc; FRAME_ADDR frame_address */);
/* Nonzero if we should step constantly (e.g. watchpoints on machines
without hardware support). This isn't related to a specific bpstat,
just to things like whether watchpoints are set. */
int bpstat_should_step (/* void */);
extern int bpstat_should_step PARAMS ((void));
/* Print a message indicating what happened. Returns nonzero to
say that only the source line should be printed after this (zero
return means print the frame as well as the source line). */
int bpstat_print (/* bpstat bs */);
extern int bpstat_print PARAMS ((bpstat));
/* Return the breakpoint number of the first breakpoint we are stopped
at. *BSP upon return is a bpstat which points to the remaining
breakpoints stopped at (but which is not guaranteed to be good for
anything but further calls to bpstat_num).
Return 0 if passed a bpstat which does not indicate any breakpoints. */
int bpstat_num (/* bpstat *bsp; */);
extern int bpstat_num PARAMS ((bpstat *));
/* Perform actions associated with having stopped at *BSP. */
void bpstat_do_actions (/* bpstat bs; */);
extern void bpstat_do_actions PARAMS ((bpstat *));
/* Modify BS so that the actions will not be performed. */
void bpstat_clear_actions (/* bpstat bs; */);
extern void bpstat_clear_actions PARAMS ((bpstat));
/* Implementation: */
#include "value.h"
struct bpstat__struct
{
/* Linked list because there can be two breakpoints at the
@ -126,4 +176,104 @@ struct bpstat__struct
first bpstat in the chain. */
char momentary;
};
#endif /* breakpoint.h not already included. */
/* Type of breakpoint. */
/* FIXME In the future, we should fold all other breakpoint-like things into
here. This includes:
1) single-step (for machines where we have to simulate single stepping),
2) step-resume (for 'next'ing over subroutine calls),
3) call-dummy (the breakpoint at the end of a subroutine stub that gdb
uses to call functions in the target).
*/
enum bptype {
bp_breakpoint, /* Normal breakpoint */
bp_until, /* used by until command */
bp_finish, /* used by finish command */
bp_watchpoint, /* Watchpoint */
bp_longjmp, /* secret breakpoint to find longjmp() */
bp_longjmp_resume, /* secret breakpoint to escape longjmp() */
};
/* States of enablement of breakpoint. */
enum enable { disabled, enabled};
/* Disposition of breakpoint. Ie: what to do after hitting it. */
enum bpdisp {
delete, /* Delete it */
disable, /* Disable it */
donttouch, /* Leave it alone */
};
/* Note that the ->silent field is not currently used by any commands
(though the code is in there if it was to be, and set_raw_breakpoint
does set it to 0). I implemented it because I thought it would be
useful for a hack I had to put in; I'm going to leave it in because
I can see how there might be times when it would indeed be useful */
/* This is for a breakpoint or a watchpoint. */
struct breakpoint
{
struct breakpoint *next;
/* Type of breakpoint. */
enum bptype type;
/* Zero means disabled; remember the info but don't break here. */
enum enable enable;
/* What to do with this breakpoint after we hit it. */
enum bpdisp disposition;
/* Number assigned to distinguish breakpoints. */
int number;
/* Address to break at, or NULL if not a breakpoint. */
CORE_ADDR address;
/* Line number of this address. Redundant. Only matters if address
is non-NULL. */
int line_number;
/* Symtab of file of this address. Redundant. Only matters if address
is non-NULL. */
struct symtab *symtab;
/* Non-zero means a silent breakpoint (don't print frame info
if we stop here). */
unsigned char silent;
/* Number of stops at this breakpoint that should
be continued automatically before really stopping. */
int ignore_count;
/* "Real" contents of byte where breakpoint has been inserted.
Valid only when breakpoints are in the program. Under the complete
control of the target insert_breakpoint and remove_breakpoint routines.
No other code should assume anything about the value(s) here. */
char shadow_contents[BREAKPOINT_MAX];
/* Nonzero if this breakpoint is now inserted. Only matters if address
is non-NULL. */
char inserted;
/* Nonzero if this is not the first breakpoint in the list
for the given address. Only matters if address is non-NULL. */
char duplicate;
/* Chain of command lines to execute when this breakpoint is hit. */
struct command_line *commands;
/* Stack depth (address of frame). If nonzero, break only if fp
equals this. */
FRAME_ADDR frame;
/* Conditional. Break only if this expression's value is nonzero. */
struct expression *cond;
/* String we used to set the breakpoint (malloc'd). Only matters if
address is non-NULL. */
char *addr_string;
/* String form of the breakpoint condition (malloc'd), or NULL if there
is no condition. */
char *cond_string;
/* The expression we are watching, or NULL if not a watchpoint. */
struct expression *exp;
/* The largest block within which it is valid, or NULL if it is
valid anywhere (e.g. consists just of global symbols). */
struct block *exp_valid_block;
/* Value of the watchpoint the last time we checked it. */
value val;
};
#endif /* !defined (BREAKPOINT_H) */

325
gdb/infrun.c

@ -1,5 +1,5 @@
/* Start (run) and stop the inferior process, for GDB.
Copyright (C) 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
Copyright 1986, 1987, 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
This file is part of GDB.
@ -146,13 +146,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
extern int original_stack_limit;
#endif /* SET_STACK_LIMIT_HUGE */
extern char *getenv ();
extern char **environ;
/* Prototypes for local functions */
extern void new_tty_prefork (); /* In inflow.c */
static void
signals_info PARAMS ((char *));
extern struct target_ops child_ops; /* In inftarg.c */
static void
handle_command PARAMS ((char *, int));
static void
sig_print_info PARAMS ((int));
static void
sig_print_header PARAMS ((void));
static void
remove_step_breakpoint PARAMS ((void));
static void
insert_step_breakpoint PARAMS ((void));
static void
resume PARAMS ((int, int));
static void
resume_cleanups PARAMS ((int));
extern char **environ;
extern struct target_ops child_ops; /* In inftarg.c */
/* Sigtramp is a routine that the kernel calls (which then calls the
signal handler). On most machines it is a library routine that
@ -170,6 +192,13 @@ extern struct target_ops child_ops; /* In inftarg.c */
(name && !strcmp ("_sigtramp", name))
#endif
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
program. It needs to examine the jmp_buf argument and extract the PC
from it. The return value is non-zero on success, zero otherwise. */
#ifndef GET_LONGJMP_TARGET
#define GET_LONGJMP_TARGET(PC_ADDR) 0
#endif
/* Tables of how to react to signals; the user sets them. */
static char signal_stop[NSIG];
@ -250,12 +279,6 @@ extern int one_stepped; /* From machine dependent code */
extern void single_step (); /* Same. */
#endif /* NO_SINGLE_STEP */
static void insert_step_breakpoint ();
static void remove_step_breakpoint ();
/*static*/ void wait_for_inferior ();
void init_wait_for_inferior ();
void normal_stop ();
/* Things to clean up if we QUIT out of resume (). */
/* ARGSUSED */
@ -529,11 +552,15 @@ child_create_inferior (exec_file, allargs, env)
#ifdef TIOCGPGRP
/* Run inferior in a separate process group. */
#ifdef NEED_POSIX_SETPGID
debug_setpgrp = setpgid (0, 0);
#else
#ifdef USG
debug_setpgrp = setpgrp ();
#else
debug_setpgrp = setpgrp (getpid (), getpid ());
#endif
#endif /* USG */
#endif /* NEED_POSIX_SETPGID */
if (debug_setpgrp == -1)
perror("setpgrp failed in child");
#endif /* TIOCGPGRP */
@ -598,10 +625,6 @@ child_create_inferior (exec_file, allargs, env)
clear_proceed_status ();
#if defined (START_INFERIOR_HOOK)
START_INFERIOR_HOOK ();
#endif
/* We will get a trace trap after one instruction.
Continue it automatically. Eventually (after shell does an exec)
it will get another trace trap. Then insert breakpoints and continue. */
@ -718,7 +741,7 @@ child_attach (args, from_tty)
if (target_has_execution)
{
if (query ("A program is being debugged already. Kill it? "))
target_kill ((char *)0, from_tty);
target_kill ();
else
error ("Inferior not killed.");
}
@ -770,16 +793,7 @@ wait_for_inferior ()
struct symtab_and_line sal;
int remove_breakpoints_on_following_step = 0;
int current_line;
#if 0
/* This no longer works now that read_register is lazy;
it might try to ptrace when the process is not stopped. */
prev_pc = read_pc ();
(void) find_pc_partial_function (prev_pc, &prev_func_name,
&prev_func_start);
prev_func_start += FUNCTION_START_OFFSET;
prev_sp = read_register (SP_REGNUM);
#endif /* 0 */
int handling_longjmp = 0; /* FIXME */
sal = find_pc_line(prev_pc, 0);
current_line = sal.line;
@ -816,7 +830,7 @@ wait_for_inferior ()
stop_print_frame = 0;
stop_signal = WTERMSIG (w);
target_terminal_ours (); /* Must do this before mourn anyway */
target_kill ((char *)0, 0); /* kill mourns as well */
target_kill (); /* kill mourns as well */
#ifdef PRINT_RANDOM_SIGNAL
printf ("\nProgram terminated: ");
PRINT_RANDOM_SIGNAL (stop_signal);
@ -902,28 +916,30 @@ wait_for_inferior ()
will be set and we should check whether we've hit the
step breakpoint. */
if (stop_signal == SIGTRAP && trap_expected
&& step_resume_break_address == 0)
&& step_resume_break_address == NULL)
bpstat_clear (&stop_bpstat);
else
{
/* See if there is a breakpoint at the current PC. */
#if DECR_PC_AFTER_BREAK
/* Notice the case of stepping through a jump
that leads just after a breakpoint.
that lands just after a breakpoint.
Don't confuse that with hitting the breakpoint.
What we check for is that 1) stepping is going on
and 2) the pc before the last insn does not match
the address of the breakpoint before the current pc. */
if (!(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
&& step_range_end && !step_resume_break_address))
if (prev_pc == stop_pc - DECR_PC_AFTER_BREAK
|| !step_range_end
|| step_resume_break_address
|| handling_longjmp /* FIXME */)
#endif /* DECR_PC_AFTER_BREAK not zero */
{
/* See if we stopped at the special breakpoint for
stepping over a subroutine call. If both are zero,
this wasn't the reason for the stop. */
if (stop_pc - DECR_PC_AFTER_BREAK
== step_resume_break_address
&& step_resume_break_address)
if (step_resume_break_address
&& stop_pc - DECR_PC_AFTER_BREAK
== step_resume_break_address)
{
stop_step_resume_break = 1;
if (DECR_PC_AFTER_BREAK)
@ -1008,64 +1024,131 @@ wait_for_inferior ()
one (now fixed) bug was caused by this -- a !random_signal was
missing in one of the tests below. */
}
/* Handle cases caused by hitting a breakpoint. */
if (!random_signal
&& (bpstat_explains_signal (stop_bpstat) || stop_step_resume_break))
{
/* Does a breakpoint want us to stop? */
if (bpstat_stop (stop_bpstat))
{
stop_print_frame = bpstat_should_print (stop_bpstat);
break;
}
/* But if we have hit the step-resumption breakpoint,
remove it. It has done its job getting us here.
The sp test is to make sure that we don't get hung
up in recursive calls in functions without frame
pointers. If the stack pointer isn't outside of
where the breakpoint was set (within a routine to be
stepped over), we're in the middle of a recursive
call. Not true for reg window machines (sparc)
because the must change frames to call things and
the stack pointer doesn't have to change if it
the bp was set in a routine without a frame (pc can
be stored in some other window).
The removal of the sp test is to allow calls to
alloca. Nasty things were happening. Oh, well,
gdb can only handle one level deep of lack of
frame pointer. */
if (stop_step_resume_break
&& (step_frame_address == 0
|| (stop_frame_address == step_frame_address)))
{
remove_step_breakpoint ();
step_resume_break_address = 0;
/* If were waiting for a trap, hitting the step_resume_break
doesn't count as getting it. */
if (trap_expected)
another_trap = 1;
}
/* Otherwise, must remove breakpoints and single-step
to get us past the one we hit. */
else
{
remove_breakpoints ();
remove_step_breakpoint ();
breakpoints_inserted = 0;
another_trap = 1;
}
/* We come here if we hit a breakpoint but should not
stop for it. Possibly we also were stepping
and should stop for that. So fall through and
test for stepping. But, if not stepping,
do not stop. */
}
if (!random_signal)
if (bpstat_explains_signal (stop_bpstat))
{
CORE_ADDR jmp_buf_pc;
switch (stop_bpstat->breakpoint_at->type) /* FIXME */
{
/* If we hit the breakpoint at longjmp, disable it for the
duration of this command. Then, install a temporary
breakpoint at the target of the jmp_buf. */
case bp_longjmp:
disable_longjmp_breakpoint();
remove_breakpoints ();
breakpoints_inserted = 0;
if (!GET_LONGJMP_TARGET(&jmp_buf_pc)) goto keep_going;
/* Need to blow away step-resume breakpoint, as it
interferes with us */
remove_step_breakpoint ();
step_resume_break_address = NULL;
stop_step_resume_break = 0;
#if 0 /* FIXME - Need to implement nested temporary breakpoints */
if (step_over_calls > 0)
set_longjmp_resume_breakpoint(jmp_buf_pc,
get_current_frame());
else
#endif /* 0 */
set_longjmp_resume_breakpoint(jmp_buf_pc, NULL);
handling_longjmp = 1; /* FIXME */
goto keep_going;
case bp_longjmp_resume:
remove_breakpoints ();
breakpoints_inserted = 0;
#if 0 /* FIXME - Need to implement nested temporary breakpoints */
if (step_over_calls
&& (stop_frame_address
INNER_THAN step_frame_address))
{
another_trap = 1;
goto keep_going;
}
#endif /* 0 */
disable_longjmp_breakpoint();
handling_longjmp = 0; /* FIXME */
break;
default:
fprintf(stderr, "Unknown breakpoint type %d\n",
stop_bpstat->breakpoint_at->type);
case bp_watchpoint:
case bp_breakpoint:
case bp_until:
case bp_finish:
/* Does a breakpoint want us to stop? */
if (bpstat_stop (stop_bpstat))
{
stop_print_frame = bpstat_should_print (stop_bpstat);
goto stop_stepping;
}
/* Otherwise, must remove breakpoints and single-step
to get us past the one we hit. */
else
{
remove_breakpoints ();
remove_step_breakpoint ();
breakpoints_inserted = 0;
another_trap = 1;
}
break;
}
}
else if (stop_step_resume_break)
{
/* But if we have hit the step-resumption breakpoint,
remove it. It has done its job getting us here.
The sp test is to make sure that we don't get hung
up in recursive calls in functions without frame
pointers. If the stack pointer isn't outside of
where the breakpoint was set (within a routine to be
stepped over), we're in the middle of a recursive
call. Not true for reg window machines (sparc)
because the must change frames to call things and
the stack pointer doesn't have to change if it
the bp was set in a routine without a frame (pc can
be stored in some other window).
The removal of the sp test is to allow calls to
alloca. Nasty things were happening. Oh, well,
gdb can only handle one level deep of lack of
frame pointer. */
/*
Disable test for step_frame_address match so that we always stop even if the
frames don't match. Reason: if we hit the step_resume_breakpoint, there is
no way to temporarily disable it so that we can step past it. If we leave
the breakpoint in, then we loop forever repeatedly hitting, but never
getting past the breakpoint. This change keeps nexting over recursive
function calls from hanging gdb.
*/
#if 0
if (* step_frame_address == 0
|| (step_frame_address == stop_frame_address))
#endif 0
{
remove_step_breakpoint ();
step_resume_break_address = 0;
/* If were waiting for a trap, hitting the step_resume_break
doesn't count as getting it. */
if (trap_expected)
another_trap = 1;
}
}
/* We come here if we hit a breakpoint but should not
stop for it. Possibly we also were stepping
and should stop for that. So fall through and
test for stepping. But, if not stepping,
do not stop. */
/* If this is the breakpoint at the end of a stack dummy,
just stop silently. */
if (!random_signal
@ -1147,9 +1230,9 @@ wait_for_inferior ()
/* ==> See comments at top of file on this algorithm. <==*/
else if (stop_pc == stop_func_start
&& (stop_func_start != prev_func_start
|| prologue_pc != stop_func_start
|| stop_sp != prev_sp))
&& (stop_func_start != prev_func_start
|| prologue_pc != stop_func_start
|| stop_sp != prev_sp))
{
/* It's a subroutine call */
if (step_over_calls > 0
@ -1157,9 +1240,12 @@ wait_for_inferior ()
{
/* A subroutine call has happened. */
/* Set a special breakpoint after the return */
step_resume_break_address =
ADDR_BITS_REMOVE
(SAVED_PC_AFTER_CALL (get_current_frame ()));
ADDR_BITS_REMOVE (
SAVED_PC_AFTER_CALL (
get_current_frame ()));
step_resume_break_duplicate
= breakpoint_here_p (step_resume_break_address);
if (breakpoints_inserted)
@ -1229,19 +1315,22 @@ wait_for_inferior ()
step_range_start and step_range_end, and just continue. */
sal = find_pc_line(stop_pc, 0);
if (step_range_end == 1 || /* Don't do this for stepi/nexti */
sal.line == 0 || /* Stop now if no line # info */
(current_line != sal.line
&& stop_pc == sal.pc)) {
stop_step = 1;
break;
} else {
/* This is probably not necessary, but it probably makes
stepping more efficient, as we avoid calling find_pc_line()
for each instruction we step over. */
step_range_start = sal.pc;
step_range_end = sal.end;
}
if (step_range_end == 1 /* Don't do this for stepi/nexti */
|| sal.line == 0 /* Stop now if no line # info */
|| (current_line != sal.line
&& stop_pc == sal.pc))
{
stop_step = 1;
break;
}
else if (sal.line != 0)
{
/* This is probably not necessary, but it probably makes
stepping more efficient, as we avoid calling
find_pc_line() for each instruction we step over. */
step_range_start = sal.pc;
step_range_end = sal.end;
}
}
}
@ -1267,6 +1356,13 @@ wait_for_inferior ()
another_trap = 1;
}
/* My apologies to the gods of structured programming. */
/* Come to this label when you need to resume the inferior. It's really much
cleaner at this time to do a goto than to try and figure out what the
if-else chain ought to look like!! */
keep_going:
/* Save the pc before execution, to compare with pc after stop. */
prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */
prev_func_start = stop_func_start; /* Ok, since if DECR_PC_AFTER
@ -1313,7 +1409,7 @@ wait_for_inferior ()
breakpoints_inserted = 0;
}
else if (!breakpoints_inserted &&
(step_resume_break_address != 0 || !another_trap))
(step_resume_break_address != NULL || !another_trap))
{
insert_step_breakpoint ();
breakpoints_failed = insert_breakpoints ();
@ -1346,12 +1442,16 @@ wait_for_inferior ()
}
#endif /* SHIFT_INST_REGS */
resume ((step_range_end && !step_resume_break_address)
|| (trap_expected && !step_resume_break_address)
resume ((!step_resume_break_address
&& !handling_longjmp
&& (step_range_end
|| trap_expected))
|| bpstat_should_step (),
stop_signal);
}
}
stop_stepping:
if (target_has_execution)
{
/* Assuming the inferior still exists, set these up for next
@ -1801,4 +1901,3 @@ Pass and Stop may be combined.");
signal_print[SIGURG] = 0;
#endif /* SIGURG */
}

190
gdb/main.c

@ -18,7 +18,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
int fclose ();
#include "defs.h"
#include "gdbcmd.h"
#include "symtab.h"
@ -26,6 +25,8 @@ int fclose ();
#include "signals.h"
#include "target.h"
#include "breakpoint.h"
#include "gdbtypes.h"
#include "expression.h"
#include "language.h"
#include "getopt.h"
@ -58,6 +59,103 @@ int fclose ();
int original_stack_limit;
#endif
/* Prototypes for local functions */
static char *
symbol_completion_function PARAMS ((char *, int));
static void
command_loop PARAMS ((void));
static void
command_loop_marker PARAMS ((int));
static void
print_gdb_version PARAMS ((void));
static void
quit_command PARAMS ((char *, int));
static void
initialize_main PARAMS ((void));
static void
initialize_history PARAMS ((void));
static void
initialize_cmd_lists PARAMS ((void));
static void
float_handler PARAMS ((int));
static void
source_command PARAMS ((char *, int));
static void
cd_command PARAMS ((char *, int));
static void
print_gnu_advertisement PARAMS ((void));
static void
init_signals PARAMS ((void));
static void
read_command_file PARAMS ((FILE *));
static void
set_verbose PARAMS ((char *, int, struct cmd_list_element *));
static void
show_history PARAMS ((char *, int));
static void
set_history PARAMS ((char *, int));
static void
set_history_size_command PARAMS ((char *, int, struct cmd_list_element *));
static void
show_commands PARAMS ((char *, int));
static void
dump_me_command PARAMS ((char *, int));
static void
echo_command PARAMS ((char *, int));
static void
pwd_command PARAMS ((char *, int));
static void
show_version PARAMS ((char *, int));
static void
document_command PARAMS ((char *, int));
static void
define_command PARAMS ((char *, int));
static void
validate_comname PARAMS ((char *));
static void
help_command PARAMS ((char *, int));
static void
show_command PARAMS ((char *, int));
static void
info_command PARAMS ((char *, int));
static void
do_nothing PARAMS ((int));
static void
disconnect PARAMS ((int));
static void
source_cleanup PARAMS ((FILE *));
/* If this definition isn't overridden by the header files, assume
that isatty and fileno exist on this system. */
@ -153,43 +251,12 @@ static char dirbuf[1024];
The function receives two args: an input stream,
and a prompt string. */
void (*window_hook) ();
void (*window_hook) PARAMS ((FILE *, char *));
extern int frame_file_full_name;
int epoch_interface;
int xgdb_verbose;
/* The external commands we call... */
extern void init_source_path ();
extern void directory_command ();
extern void exec_file_command ();
extern void symbol_file_command ();
extern void core_file_command ();
extern void tty_command ();
extern void help_list ();
extern void initialize_all_files ();
extern void init_malloc ();
/* Forward declarations for this file */
void free_command_lines ();
char *gdb_readline ();
char *command_line_input ();
static void initialize_history ();
static void initialize_main ();
static void initialize_cmd_lists ();
static void init_signals ();
static void quit_command ();
void command_loop ();
static void source_command ();
static void print_gdb_version ();
static void print_gnu_advertisement ();
static void float_handler ();
static void cd_command ();
static void read_command_file ();
char *getenv ();
/* gdb prints this when reading a command interactively */
static char *prompt;
@ -209,6 +276,7 @@ char *baud_rate;
#ifndef STOP_SIGNAL
#ifdef SIGTSTP
#define STOP_SIGNAL SIGTSTP
static void stop_sig PARAMS ((int));
#endif
#endif
@ -225,16 +293,15 @@ char *baud_rate;
jmp_buf to_top_level;
void
NORETURN void
return_to_top_level ()
{
quit_flag = 0;
immediate_quit = 0;
bpstat_clear_actions(stop_bpstat); /* Clear queued breakpoint commands */
clear_momentary_breakpoints ();
disable_current_display ();
do_cleanups (ALL_CLEANUPS);
longjmp (to_top_level, 1);
(NORETURN void) longjmp (to_top_level, 1);
}
/* Call FUNC with arg ARGS, catching any errors.
@ -244,7 +311,7 @@ return_to_top_level ()
int
catch_errors (func, args, errstring)
int (*func) ();
int (*func) PARAMS ((char *));
char *args;
char *errstring;
{
@ -274,7 +341,8 @@ catch_errors (func, args, errstring)
/* Handler for SIGHUP. */
static void
disconnect ()
disconnect (signo)
int signo;
{
kill_inferior_fast ();
signal (SIGHUP, SIG_DFL);
@ -618,15 +686,13 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
/* Set the initial language. */
{
extern enum language deduce_language_from_filename ();
extern struct partial_symtab *find_main_psymtab ();
struct partial_symtab *pst = find_main_psymtab ();
enum language lang = language_unknown;
if (pst == NULL) ;
#if 0
/* A better solution would set the language when reading the psymtab.
This would win for symbol file formats that encode the langauge,
such as dwarf. But, we don't do that yet. FIXME */
such as DWARF. But, we don't do that yet. FIXME */
else if (pst->language != language_unknown)
lang = pst->language;
#endif
@ -793,10 +859,10 @@ execute_command (p, from_tty)
}
else if (c->type == set_cmd || c->type == show_cmd)
do_setshow_command (arg, from_tty & caution, c);
else if (c->function == NO_FUNCTION)
else if (c->function.cfunc == NO_FUNCTION)
error ("That is not a command, just a help topic.");
else
(*c->function) (arg, from_tty & caution);
(*c->function.cfunc) (arg, from_tty & caution);
}
/* Tell the user if the language has changed (except first time). */
@ -829,7 +895,7 @@ execute_command (p, from_tty)
}
/* ARGSUSED */
void
static void
command_loop_marker (foo)
int foo;
{
@ -837,7 +903,7 @@ command_loop_marker (foo)
/* Read commands from `instream' and execute them
until end of file or error reading instream. */
void
static void
command_loop ()
{
struct cleanup *old_chain;
@ -853,7 +919,7 @@ command_loop ()
if (instream == stdin && stdin_is_tty)
reinitialize_more_filter ();
old_chain = make_cleanup (command_loop_marker, 0);
command = command_line_input (instream == stdin ? prompt : 0,
command = command_line_input (instream == stdin ? prompt : (char *) NULL,
instream == stdin);
if (command == 0)
return;
@ -927,9 +993,6 @@ gdb_readline (prrompt)
return result;
}
/* Declaration for fancy readline with command line editing. */
char *readline ();
/* Variables which control command line editing and history
substitution. These variables are given default values at the end
of this file. */
@ -963,7 +1026,8 @@ noop_completer (text)
the cursor. You should pretend that the line ends at RL_POINT.
The result is NULL if there are no more completions, else a char
string which is a possible completion. */
char *
static char *
symbol_completion_function (text, state)
char *text;
int state;
@ -1094,7 +1158,8 @@ symbol_completion_function (text, state)
#ifdef STOP_SIGNAL
static void
stop_sig ()
stop_sig (signo)
int signo;
{
#if STOP_SIGNAL == SIGTSTP
signal (SIGTSTP, SIG_DFL);
@ -1114,15 +1179,14 @@ stop_sig ()
/* Initialize signal handlers. */
static void
do_nothing ()
do_nothing (signo)
int signo;
{
}
static void
init_signals ()
{
extern void request_quit ();
signal (SIGINT, request_quit);
/* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get
@ -1160,7 +1224,7 @@ command_line_input (prrompt, repeat)
int repeat;
{
static char *linebuffer = 0;
static int linelength = 0;
static unsigned linelength = 0;
register char *p;
char *p1;
char *rl;
@ -1354,7 +1418,7 @@ read_command_lines ()
while (1)
{
dont_repeat ();
p = command_line_input (0, instream == stdin);
p = command_line_input ((char *) NULL, instream == stdin);
if (p == NULL)
/* Treat end of file like "end". */
break;
@ -1419,7 +1483,7 @@ free_command_lines (lptr)
void
add_info (name, fun, doc)
char *name;
void (*fun) ();
void (*fun) PARAMS ((char *, int));
char *doc;
{
add_cmd (name, no_class, fun, doc, &infolist);
@ -1466,7 +1530,7 @@ void
add_com (name, class, fun, doc)
char *name;
enum command_class class;
void (*fun) ();
void (*fun) PARAMS ((char *, int));
char *doc;
{
add_cmd (name, class, fun, doc, &cmdlist);
@ -1529,7 +1593,6 @@ define_command (comname, from_tty)
register struct command_line *cmds;
register struct cmd_list_element *c, *newc;
char *tem = comname;
extern void not_just_help_class_command ();
validate_comname (comname);
@ -1856,7 +1919,7 @@ show_commands (args, from_tty)
than the number of the last command). Relative to history_base. */
int hist_len;
struct _hist_entry *history_get();
extern struct _hist_entry *history_get PARAMS ((int));
extern int history_base;
/* Print out some of the commands from the command history. */
@ -1979,7 +2042,8 @@ set_verbose (args, from_tty, c)
}
static void
float_handler ()
float_handler (signo)
int signo;
{
/* This message is based on ANSI C, section 4.7. Note that integer
divide by zero causes this, so "float" is a misnomer. */
@ -2138,7 +2202,7 @@ when gdb is started.");
"Set ",
&setlist),
add_show_from_set (c, &showlist);
c->function = set_verbose;
c->function.sfunc = set_verbose;
set_verbose (NULL, 0, c);
add_com ("dump-me", class_obscure, dump_me_command,
@ -2176,7 +2240,7 @@ Without an argument, saving is enabled.", &sethistlist),
"Set the size of the command history, \n\
ie. the number of previous commands to keep a record of.", &sethistlist);
add_show_from_set (c, &showhistlist);
c->function = set_history_size_command;
c->function.sfunc = set_history_size_command;
add_show_from_set
(add_set_cmd ("filename", no_class, var_filename, (char *)&history_filename,

824
gdb/symfile.c

File diff suppressed because it is too large

6
gdb/tm-68k.h

@ -535,10 +535,12 @@ extern const struct ext_format ext_format_68881;
extern void m68k_push_dummy_frame PARAMS ((void));
extern void m68k_pop_frame PARAMS ((void));
/* Discard from the stack the innermost frame, restoring all registers. */
#define POP_FRAME { m68k_pop_frame (); }
extern void m68k_pop_frame PARAMS ((void));
/* Offset from SP to first arg on stack at first instruction of a function */
#define SP_ARG0 (1 * 4)

16
gdb/tm-mips.h

@ -1,5 +1,5 @@
/* Definitions to make GDB run on a mips box under 4.3bsd.
Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
Copyright (C) 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
Contributed by Per Bothner (bothner@cs.wisc.edu) at U.Wisconsin
and by Alessandro Forin (af@cs.cmu.edu) at CMU.
@ -121,6 +121,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
but do serve to get the desired values when passed to read_register. */
#define ZERO_REGNUM 0 /* read-only register, always 0 */
#define A0_REGNUM 4 /* Lo of first arg during a subr call */
#define SP_REGNUM 29 /* Contains address of top of stack */
#define RA_REGNUM 31 /* Contains return address value */
#define PS_REGNUM 32 /* Contains processor status */
@ -346,3 +347,16 @@ typedef struct mips_extra_func_info {
#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci)
#define STAB_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32)
/* Size of elements in jmpbuf */
#define JB_ELEMENT_SIZE 4
/* Figure out where the longjmp will land. We expect that we have just entered
longjmp and haven't yet setup the stack frame, so the args are still in the
argument regs. a0 (CALL_ARG0) points at the jmp_buf structure from which we
extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
This routine returns true on success */
/* Note that caller must #include <setjmp.h> in order to get def of JB_* */
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)

1
gdb/tm-sparc.h

@ -579,4 +579,3 @@ extern void single_step ();
print_floating (doublereg, builtin_type_double, stdout); \
} \
}

31
gdb/tm-sun3.h

@ -1,5 +1,5 @@
/* Parameters for execution on a Sun, for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of GDB.
@ -37,3 +37,32 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define STACK_END_ADDR USRSTACK
#include "tm-68k.h"
/* Offsets (in target ints) into jmp_buf. Not defined by Sun, but at least
documented in a comment in <machine/setjmp.h>! */
#define JB_ELEMENT_SIZE 4
#define JB_ONSSTACK 0
#define JB_SIGMASK 1
#define JB_SP 2
#define JB_PC 3
#define JB_PSL 4
#define JB_D2 5
#define JB_D3 6
#define JB_D4 7
#define JB_D5 8
#define JB_D6 9
#define JB_D7 10
#define JB_A2 11
#define JB_A3 12
#define JB_A4 13
#define JB_A5 14
#define JB_A6 15
/* Figure out where the longjmp will land. Slurp the args out of the stack.
We expect the first arg to be a pointer to the jmp_buf structure from which
we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
This routine returns true on success */
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)

25
gdb/tm-sun4os4.h

@ -1,5 +1,5 @@
/* Macro definitions for GDB for a Sun 4 running sunos 4.
Copyright (C) 1989, Free Software Foundation, Inc.
Copyright (C) 1989, 1992 Free Software Foundation, Inc.
This file is part of GDB.
@ -22,3 +22,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef STACK_END_ADDRESS
#define STACK_END_ADDRESS 0xf8000000
/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a
comment in <machine/setjmp.h>! */
#define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */
#define JB_ONSSTACK 0
#define JB_SIGMASK 1
#define JB_SP 2
#define JB_PC 3
#define JB_NPC 4
#define JB_PSR 5
#define JB_G1 6
#define JB_O0 7
#define JB_WBCNT 8
/* Figure out where the longjmp will land. We expect that we have just entered
longjmp and haven't yet setup the stack frame, so the args are still in the
output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
This routine returns true on success */
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)

Loading…
Cancel
Save