Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com)

* Makefile.in (CLIBS):  Reorder to make Lynx ld happy.
	* (HFILES):  New file thread.h.
	* (OBS):  New file thread.c.
	* configure.in:  Host config for Lynx/386.
	* fork-child.c (fork_inferior):  Call init_thread_list().
	* infrun.c (resume):  Add pid to invocation of target_resume().
	* (wait_for_inferior): Pay attention to pid from target_wait().
	Multi-threading code now uses this to determine what to do.
	* inftarg.c (child_wait):  Conditionalize based on CHILD_WAIT macro.
	Use target_pid_to_str() macro throughout when printing pid.
	* inferior.h (child_resume):  Add pid to prototype.
	* hppab-nat.c hppah-nat.c infptrace.c (child_resume):  Pass in pid as
	argument, instead of using inferior_pid.
	* procfs.c (procfs_resume):  Pass in pid as argument.  Ignored for
	now.  Use target_pid_to_str() macro throughout for printing process id.
	* remote-adapt.c (adapt_resume):  Pass in pid as argument.
	* remote-eb.c (eb_resume):  Pass in pid as argument.
	* remote-es.c (es1800_resume):  Pass in pid as argument.
	* remote-hms.c (hms_resume):  Pass in pid as argument.
	* remote-mips.c (mips_resume):  Pass in pid as argument.
	* remote-mm.c (mm_resume):  Pass in pid as argument.
	* remote-monitor.c (monitor_resume):  Pass in pid as argument.
	* remote-nindy.c (nindy_resume):  Pass in pid as argument.
	* remote-sa.sparc.c (remote_resume):  Pass in pid as argument.
	* remote-sim.c (rem_resume):  Pass in pid as argument.
	* remote-sp64sim.c (simif_resume):  Pass in pid as argument.
	* remote-st.c (st2000_resume):  Pass in pid as argument.
	* remote-udi.c (udi_resume):  Pass in pid as argument.
	* remote-vx.c (vx_resume):  Pass in pid as argument.
	* remote-z8k.c (rem_resume):  Pass in pid as argument.
	* remote.c (remote_resume):  Pass in pid as argument.
	* solib.c (solid_create_inferior_hook):  Pass inferior_pid to
	target_resume().
	* target.c (normal_pid_to_str):  New routine to print out process
	ID normally.
	* target.h (struct target_ops):  Add pid to prototype at
	to_resume().  (target_resume):  Add pid argument.
	* (target_pid_to_str):  Default definition for normal type pids.
	* thread.c, thread.c:  New modules for multi thread/process control.
This commit is contained in:
Stu Grossman 1993-08-02 06:25:36 +00:00
parent 3481ad9a11
commit 25286543da
25 changed files with 674 additions and 55 deletions

View File

@ -1,3 +1,45 @@
Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com)
* Makefile.in (CLIBS): Reorder to make Lynx ld happy.
* (HFILES): New file thread.h.
* (OBS): New file thread.c.
* configure.in: Host config for Lynx/386.
* fork-child.c (fork_inferior): Call init_thread_list().
* infrun.c (resume): Add pid to invocation of target_resume().
* (wait_for_inferior): Pay attention to pid from target_wait().
Multi-threading code now uses this to determine what to do.
* inftarg.c (child_wait): Conditionalize based on CHILD_WAIT macro.
Use target_pid_to_str() macro throughout when printing pid.
* inferior.h (child_resume): Add pid to prototype.
* hppab-nat.c hppah-nat.c infptrace.c (child_resume): Pass in pid as
argument, instead of using inferior_pid.
* procfs.c (procfs_resume): Pass in pid as argument. Ignored for
now. Use target_pid_to_str() macro throughout for printing process id.
* remote-adapt.c (adapt_resume): Pass in pid as argument.
* remote-eb.c (eb_resume): Pass in pid as argument.
* remote-es.c (es1800_resume): Pass in pid as argument.
* remote-hms.c (hms_resume): Pass in pid as argument.
* remote-mips.c (mips_resume): Pass in pid as argument.
* remote-mm.c (mm_resume): Pass in pid as argument.
* remote-monitor.c (monitor_resume): Pass in pid as argument.
* remote-nindy.c (nindy_resume): Pass in pid as argument.
* remote-sa.sparc.c (remote_resume): Pass in pid as argument.
* remote-sim.c (rem_resume): Pass in pid as argument.
* remote-sp64sim.c (simif_resume): Pass in pid as argument.
* remote-st.c (st2000_resume): Pass in pid as argument.
* remote-udi.c (udi_resume): Pass in pid as argument.
* remote-vx.c (vx_resume): Pass in pid as argument.
* remote-z8k.c (rem_resume): Pass in pid as argument.
* remote.c (remote_resume): Pass in pid as argument.
* solib.c (solid_create_inferior_hook): Pass inferior_pid to
target_resume().
* target.c (normal_pid_to_str): New routine to print out process
ID normally.
* target.h (struct target_ops): Add pid to prototype at
to_resume(). (target_resume): Add pid argument.
* (target_pid_to_str): Default definition for normal type pids.
* thread.c, thread.c: New modules for multi thread/process control.
Sun Aug 1 13:02:42 1993 John Gilmore (gnu@cygnus.com)
* README: Say that bug-gdb is also the place to send requests

View File

@ -162,8 +162,8 @@ INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
# you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS='
INSTALLED_LIBS=-lbfd -lreadline $(TERMCAP) -lopcodes -lmmalloc \
-liberty $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS)
CLIBS = $(BFD) $(READLINE) $(TERMCAP) $(OPCODES) $(MMALLOC) \
$(LIBIBERTY) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS)
CLIBS = $(BFD) $(READLINE) $(OPCODES) $(MMALLOC) \
$(LIBIBERTY) $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS)
CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) \
$(BFD) $(READLINE) $(OPCODES) $(MMALLOC) $(LIBIBERTY)
@ -371,7 +371,7 @@ HFILES = buildsym.h call-cmds.h defs.h environ.h $(gdbcmd_h) \
nindy-share/env.h nindy-share/stop.h \
vx-share/dbgRpcLib.h vx-share/ptrace.h vx-share/vxTypes.h \
vx-share/vxWorks.h vx-share/wait.h vx-share/xdr_ld.h \
vx-share/xdr_ptrace.h vx-share/xdr_rdb.h
vx-share/xdr_ptrace.h vx-share/xdr_rdb.h thread.h
# GDB "info" files, which should be included in their entirety
INFOFILES = gdb.info*
@ -401,7 +401,7 @@ TARFILES = $(SFILES) $(HFILES) $(NONSRC) $(ALLDEPFILES) $(ALLCONFIG) \
$(ALLPARAM) $(INFOFILES) $(POSSLIBS) $(REMOTE_EXAMPLES)
OBS = version.o main.o blockframe.o breakpoint.o findvar.o stack.o \
OBS = version.o main.o blockframe.o breakpoint.o findvar.o stack.o thread.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 command.o \
utils.o expprint.o environ.o gdbtypes.o copying.o $(DEPFILES) \
@ -1282,6 +1282,8 @@ tahoe-pinsn.o: tahoe-pinsn.c $(OP_INCLUDE)/tahoe.h $(defs_h) \
target.o: target.c $(bfd_h) $(defs_h) $(gdbcmd_h) $(inferior_h) \
objfiles.h symfile.h target.h
thread.o: thread.c $(defs_h) thread.h
typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
$(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
$(value_h)

View File

@ -42,6 +42,7 @@ i[34]86-*-aix*) gdb_host=i386aix ;;
i[34]86-*-bsd*) gdb_host=i386bsd ;;
i[34]86-*-go32) gdb_host=go32 ;;
i[34]86-*-linux) gdb_host=linux ;;
i[34]86-*-lynx*) gdb_host=i386lynx ;;
i[34]86-*-mach) gdb_host=i386mach ;;
i[34]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
i[34]86-*-sco*) gdb_host=i386sco ;;
@ -177,7 +178,7 @@ i[34]86-*-elf) gdb_target=i386v ;;
i[34]86-*-aix*) gdb_target=i386aix ;;
i[34]86-*-bsd*) gdb_target=i386bsd ;;
i[34]86-*-go32) gdb_target=i386aout ;;
i[34]86-*-lynxos*) gdb_target=i386lynx
i[34]86-*-lynx*) gdb_target=i386lynx
configdirs="${configdirs} gdbserver"
;;
i[34]86-*-solaris*) gdb_target=i386sol2 ;;

View File

@ -242,6 +242,8 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
initialize anything target-vector-specific that needs initializing. */
(*init_trace_fun)(pid);
init_thread_list();
#ifdef CREATE_INFERIOR_HOOK
CREATE_INFERIOR_HOOK (pid);
#endif

View File

@ -255,12 +255,13 @@ store_inferior_registers (regno)
return;
}
/* Resume execution of the inferior process.
/* Resume execution of process PID.
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
void
child_resume (step, signal)
child_resume (pid, step, signal)
int pid;
int step;
int signal;
{
@ -271,9 +272,9 @@ child_resume (step, signal)
written a new PC value to the child.) */
if (step)
ptrace (PT_STEP, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1, signal);
else
ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1, signal);
if (errno)
perror_with_name ("ptrace");

View File

@ -200,12 +200,13 @@ fetch_register (regno)
error_exit:;
}
/* Resume execution of the inferior process.
/* Resume execution of process PID.
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
void
child_resume (step, signal)
child_resume (pid, step, signal)
int pid;
int step;
int signal;
{

303
gdb/i386lynx-nat.c Normal file
View File

@ -0,0 +1,303 @@
/* Native-dependent code for Lynx running on i386's, for GDB.
Copyright 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
This file is part of GDB.
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 2 of the License, or
(at your option) any later version.
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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "gdbcore.h"
#include "target.h"
#include <sys/ptrace.h>
#include "/usr/include/sys/wait.h"
/* these values indicate the offset of the named register in the econtext
structure */
#define EAX 10
#define ECX 9
#define EDX 8
#define EBX 7
#define ESP 16
#define EBP 5
#define ESI 4
#define EDI 3
#define EIP 13
#define EFL 15
#define CS 14
#define SS 17
#define DS 2
#define ES 1
/* Currently these are not being used. So set them to 0 */
#define FS 0
#define GS 0
/* this table must line up with REGISTER_NAMES in m-i386.h */
static unsigned int regmap[] =
{
EAX, ECX, EDX, EBX,
ESP, EBP, ESI, EDI,
EIP, EFL, CS, SS,
DS, ES, FS, GS,
};
/* Return the address in the core dump or inferior of register REGNO.
BLOCKEND is the address of the econtext structure */
static unsigned int
register_addr (regno, blockend)
int regno, blockend;
{
if (regno < 0 || regno >= NUM_REGS)
error ("Invalid register number %d.", regno);
return (blockend + regmap[regno] * sizeof (long));
}
/* Fetch one register. */
static void
fetch_register (regno, offset, bpid)
int regno, bpid;
unsigned int offset;
{
unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
char mess[128]; /* For messages */
int i;
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
errno = 0;
*(int *) &buf[i] = ptrace (PTRACE_PEEKTHREAD, bpid,
(PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (int);
if (errno != 0)
{
sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
perror_with_name (mess);
}
}
supply_register (regno, buf);
}
/* Store our register values back into the inferior.
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
static void
store_register (regno, offset, bpid)
int regno, bpid;
unsigned int offset;
{
unsigned int regaddr;
char mess[128];
extern char registers[];
int i;
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
{
errno = 0;
ptrace (PTRACE_POKEUSER, bpid, (PTRACE_ARG3_TYPE) regaddr,
*(int *) &registers[REGISTER_BYTE (regno) + i]);
if (errno != 0)
{
sprintf (mess, "writing register number %d(%d)", regno, i);
perror_with_name (mess);
}
regaddr += sizeof(int);
}
}
/* return an offset for use with register_addr() */
static unsigned int
fetch_offset (pid)
int pid;
{
struct st_entry s;
unsigned int specpage_off, offset = (char *) &s.ecp - (char *) &s;
errno = 0;
specpage_off = ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, 0);
if (errno != 0)
perror_with_name ("ptrace");
errno = 0;
offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0)
- specpage_off;
if (errno != 0)
perror_with_name ("ptrace");
return offset;
}
/* Fetch all registers, or just one, from the child process. */
void
fetch_inferior_registers (regno)
int regno;
{
unsigned int offset = fetch_offset (inferior_pid);
if (regno == -1)
{
for (regno = 0; regno < NUM_REGS; regno++)
fetch_register (regno, offset, inferior_pid);
}
else
fetch_register (regno, offset, inferior_pid);
}
/* Store all registers, or just one, to the child process. */
void
store_inferior_registers (regno)
int regno;
{
unsigned int offset = fetch_offset (inferior_pid);
if (regno == -1)
{
for (regno = 0; regno < NUM_REGS; regno++)
store_register (regno, offset, inferior_pid);
}
else
store_register (regno, offset, inferior_pid);
}
/* Extract the register values out of the core file and store
them where `read_register' will find them.
CORE_REG_SECT points to the register values themselves, read into memory.
CORE_REG_SIZE is the size of that area.
WHICH says which set of registers we are handling (0 = int, 2 = float
on machines where they are discontiguous).
REG_ADDR is the offset from u.u_ar0 to the register values relative to
core_reg_sect. This is used with old-fashioned core files to
locate the registers in a large upage-plus-stack ".reg" section.
Original upage address X is at location core_reg_sect+x+reg_addr.
*/
void
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
unsigned reg_addr;
{
struct st_entry s;
unsigned int regno, addr;
for (regno = 0; regno < NUM_REGS; regno++)
{
addr = register_addr (regno, (char *) &s.ec - (char *) &s);
supply_register (regno, core_reg_sect + addr);
}
}
/* Wait for child to do something. Return pid of child, or -1 in case
of error; store status through argument pointer STATUS. */
int
child_wait (status)
int *status;
{
int pid;
int save_errno;
int thread;
while (1)
{
int sig;
if (attach_flag)
set_sigint_trap(); /* Causes SIGINT to be passed on to the
attached process. */
pid = wait (status);
save_errno = errno;
if (attach_flag)
clear_sigint_trap();
if (pid == -1)
{
if (save_errno == EINTR)
continue;
fprintf (stderr, "Child process unexpectedly missing: %s.\n",
safe_strerror (save_errno));
*status = 42; /* Claim it exited with signal 42 */
return -1;
}
if (pid != PIDGET (inferior_pid)) /* Some other process?!? */
continue;
/* thread = WIFTID (*status);*/
thread = *status >> 16;
/* Initial thread value can only be acquired via wait, so we have to
resort to this hack. */
if (TIDGET (inferior_pid) == 0)
{
inferior_pid = BUILDPID (inferior_pid, thread);
add_thread (inferior_pid);
}
pid = BUILDPID (pid, thread);
return pid;
}
}
/* Return the PC of the caller from the call frame. Assumes the subr prologue
has already been executed, and the frame pointer setup. If this is the
outermost frame, we check to see if we are in a system call by examining the
previous instruction. If so, then the return PC is actually at SP+4 because
system calls use a different calling sequence. */
CORE_ADDR
i386lynx_saved_pc_after_call (frame)
struct frame_info *frame;
{
char opcode[7];
static const char call_inst[] = {0x9a, 0, 0, 0, 0, 8, 0}; /* lcall 0x8,0x0 */
read_memory (frame->pc - 7, opcode, 7);
if (memcmp (opcode, call_inst, 7) == 0)
return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
return read_memory_integer (read_register (SP_REGNUM), 4);
}
/* Convert a Lynx process ID to a string. Returns the string in a static
buffer. */
char *
i386lynx_pid_to_str (pid)
int pid;
{
static char buf[40];
sprintf (buf, "process %d thread %d", PIDGET (pid), TIDGET (pid));
return buf;
}

View File

@ -1599,9 +1599,9 @@ procfs_attach (args, from_tty)
exec_file = (char *) get_exec_file (0);
if (exec_file)
printf ("Attaching program `%s', pid %d\n", exec_file, pid);
printf ("Attaching to program `%s', %s\n", exec_file, target_pid_to_str (pid));
else
printf ("Attaching pid %d\n", pid);
printf ("Attaching to %s\n", target_pid_to_str (pid));
fflush (stdout);
}
@ -1632,8 +1632,8 @@ procfs_detach (args, from_tty)
char *exec_file = get_exec_file (0);
if (exec_file == 0)
exec_file = "";
printf ("Detaching program: %s pid %d\n",
exec_file, inferior_pid);
printf ("Detaching from program: %s %s\n",
exec_file, target_pid_to_str (inferior_pid));
fflush (stdout);
}
if (args)
@ -1664,8 +1664,8 @@ static void
procfs_files_info (ignore)
struct target_ops *ignore;
{
printf ("\tUsing the running image of %s process %d via /proc.\n",
attach_flag? "attached": "child", inferior_pid);
printf ("\tUsing the running image of %s %s via /proc.\n",
attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
}
/* ARGSUSED */
@ -1761,7 +1761,7 @@ do_attach (pid)
}
else
{
printf ("Ok, gdb will wait for process %u to stop.\n", pid);
printf ("Ok, gdb will wait for %s to stop.\n", target_pid_to_str (pid));
}
}
@ -2150,12 +2150,13 @@ set_proc_siginfo (pip, signo)
}
}
/* Resume execution of the inferior process. If STEP is nozero, then
/* Resume execution of process PID. If STEP is nozero, then
just single step it. If SIGNAL is nonzero, restart it with that
signal activated. */
static void
procfs_resume (step, signo)
procfs_resume (pid, step, signo)
int pid;
int step;
int signo;
{
@ -2552,7 +2553,8 @@ info_proc_siginfo (pip, summary)
}
if (sip -> si_code <= 0)
{
printf_filtered ("sent by pid %d, uid %d ", sip -> si_pid,
printf_filtered ("sent by %s, uid %d ",
target_pid_to_str (sip -> si_pid),
sip -> si_uid);
}
else
@ -2567,8 +2569,8 @@ info_proc_siginfo (pip, summary)
}
else if ((sip -> si_signo == SIGCHLD))
{
printf_filtered ("child pid %u, status %u ",
sip -> si_pid,
printf_filtered ("child %s, status %u ",
target_pid_to_str (sip -> si_pid),
sip -> si_status);
}
else if ((sip -> si_signo == SIGPOLL))
@ -2590,7 +2592,7 @@ info_proc_siginfo (pip, summary)
}
if (sip -> si_code <= 0)
{
printf_filtered ("\t%-16u %s\n", sip -> si_pid,
printf_filtered ("\t%-16u %s\n", sip -> si_pid, /* XXX need target_pid_to_str() */
"PID of process sending signal");
printf_filtered ("\t%-16u %s\n", sip -> si_uid,
"UID of process sending signal");
@ -2613,7 +2615,7 @@ info_proc_siginfo (pip, summary)
}
else if ((sip -> si_signo == SIGCHLD))
{
printf_filtered ("\t%-16u %s.\n", sip -> si_pid,
printf_filtered ("\t%-16u %s.\n", sip -> si_pid, /* XXX need target_pid_to_str() */
"Child process ID");
printf_filtered ("\t%-16u %s.\n", sip -> si_status,
"Child process exit value or signal");

View File

@ -675,8 +675,8 @@ adapt_detach (args,from_tty)
/* Tell the remote machine to resume. */
void
adapt_resume (step, sig)
int step, sig;
adapt_resume (pid, step, sig)
int pid, step, sig;
{
if (step)
{

View File

@ -479,8 +479,8 @@ eb_detach (from_tty)
/* Tell the remote machine to resume. */
void
eb_resume (step, sig)
int step, sig;
eb_resume (pid, step, sig)
int pid, step, sig;
{
if (step)
{

View File

@ -161,7 +161,7 @@ static int
es1800_wait PARAMS ((WAITTYPE *));
static void
es1800_resume PARAMS ((int, int));
es1800_resume PARAMS ((int, int, int));
static void
es1800_detach PARAMS ((char *, int));
@ -650,7 +650,8 @@ es1800_detach (args, from_tty)
siggnal - the signal value to be given to the target (0 = no signal) */
static void
es1800_resume (step, siggnal)
es1800_resume (pid, step, siggnal)
int pid;
int step;
int siggnal;
{

View File

@ -638,8 +638,8 @@ hms_detach (args, from_tty)
/* Tell the remote machine to resume. */
void
hms_resume (step, sig)
int step, sig;
hms_resume (pid, step, sig)
int pid, step, sig;
{
dcache_flush ();

View File

@ -71,7 +71,7 @@ static void
mips_detach PARAMS ((char *args, int from_tty));
static void
mips_resume PARAMS ((int step, int siggnal));
mips_resume PARAMS ((int pid, int step, int siggnal));
static int
mips_wait PARAMS ((WAITTYPE *status));
@ -957,8 +957,8 @@ mips_detach (args, from_tty)
from the board. */
static void
mips_resume (step, siggnal)
int step, siggnal;
mips_resume (pid, step, siggnal)
int pid, step, siggnal;
{
if (siggnal)
error ("Can't send signals to a remote system. Try `handle %d ignore'.",

View File

@ -498,8 +498,8 @@ mm_detach (args,from_tty)
** Tell the remote machine to resume. */
static void
mm_resume (step, sig)
int step, sig;
mm_resume (pid, step, sig)
int pid, step, sig;
{
if (sig)
error ("Can't send signals to a remote MiniMon system.");

View File

@ -436,8 +436,8 @@ monitor_detach (from_tty)
* _resume -- Tell the remote machine to resume.
*/
static void
monitor_resume (step, sig)
int step, sig;
monitor_resume (pid, step, sig)
int pid, step, sig;
{
#ifdef LOG_FILE
fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);

View File

@ -257,8 +257,8 @@ non_dle( buf, n )
/* Tell the remote machine to resume. */
void
nindy_resume (step, siggnal)
int step, siggnal;
nindy_resume (pid, step, siggnal)
int pid, step, siggnal;
{
if (siggnal != 0 && siggnal != stop_signal)
error ("Can't send signals to remote NINDY targets.");

View File

@ -201,8 +201,8 @@ extern int one_stepped; /* From machine dependent code */
static int remote_set_one_stepped;
int
remote_resume (step, signal)
int step, signal;
remote_resume (pid, step, signal)
int pid, step, signal;
{
if (step)
{

View File

@ -242,7 +242,7 @@ sim_before_main_loop ()
}
static void rem_resume(a,b)
static void rem_resume(pid, a , b)
{
sim_resume(a,b);
}

View File

@ -311,8 +311,8 @@ simif_detach (args,from_tty)
to the target, or zero for no signal. */
static void
simif_resume (step, siggnal)
int step, siggnal;
simif_resume (pid, step, siggnal)
int pid, step, siggnal;
{
if (sim_verbose)
printf_filtered ("simif_resume: step %d, signal %d\n", step, siggnal);

View File

@ -358,8 +358,8 @@ st2000_detach (from_tty)
/* Tell the remote machine to resume. */
static void
st2000_resume (step, sig)
int step, sig;
st2000_resume (pid, step, sig)
int pid, step, sig;
{
if (step)
{

View File

@ -52,7 +52,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
static int kiodebug;
extern int stop_soon_quietly; /* for wait_for_inferior */
extern struct value *call_function_by_hand();
static void udi_resume PARAMS ((int step, int sig));
static void udi_resume PARAMS ((int pid, int step, int sig));
static void udi_fetch_registers PARAMS ((int regno));
static void udi_load PARAMS ((char *args, int from_tty));
static void fetch_register PARAMS ((int regno));
@ -403,8 +403,8 @@ udi_detach (args,from_tty)
** Tell the remote machine to resume. */
static void
udi_resume (step, sig)
int step, sig;
udi_resume (pid, step, sig)
int pid, step, sig;
{
UDIError tip_error;
UDIUInt32 Steps = 1;

View File

@ -578,7 +578,8 @@ vx_run_files_info ()
}
static void
vx_resume (step, siggnal)
vx_resume (pid, step, siggnal)
int pid;
int step;
int siggnal;
{
@ -592,7 +593,7 @@ vx_resume (step, siggnal)
bzero ((char *) &ptrace_in, sizeof (ptrace_in));
bzero ((char *) &ptrace_out, sizeof (ptrace_out));
ptrace_in.pid = inferior_pid;
ptrace_in.pid = pid;
ptrace_in.addr = 1; /* Target side insists on this, or it panics. */
/* XXX change second param to be a proc number */

View File

@ -310,7 +310,8 @@ sim_mourn ()
}
static void
rem_resume (a, b)
rem_resume (pid, a, b)
int pid;
int a;
int b;
{

233
gdb/thread.c Normal file
View File

@ -0,0 +1,233 @@
/* for separate threads within the inferior process, for GDB.
Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include "defs.h"
#include "symtab.h"
#include "frame.h"
#include "inferior.h"
#include "environ.h"
#include "value.h"
#include "target.h"
#include "thread.h"
#include <sys/types.h>
#include <signal.h>
/*#include "lynxos-core.h"*/
struct thread_info
{
struct thread_info *next;
int pid; /* Actual process id */
int num; /* Convenient handle */
};
static struct thread_info *thread_list = NULL;
static int highest_thread_num;
static void thread_info PARAMS ((void));
static void thread_command PARAMS ((char * tidstr, int from_tty));
static void prune_threads PARAMS ((void));
static void thread_switch PARAMS ((int pid));
void
init_thread_list ()
{
struct thread_info *tp, *tpnext;
if (!thread_list)
return;
for (tp = thread_list; tp; tp = tpnext)
{
tpnext = tp->next;
free (tp);
}
thread_list = NULL;
highest_thread_num = 0;
}
void
add_thread (pid)
int pid;
{
struct thread_info *tp;
tp = xmalloc (sizeof (struct thread_info));
tp->pid = pid;
tp->num = ++highest_thread_num;
tp->next = thread_list;
thread_list = tp;
}
static struct thread_info *
find_thread_id (num)
int num;
{
struct thread_info *tp;
for (tp = thread_list; tp; tp = tp->next)
if (tp->num == num)
return tp;
return NULL;
}
int
in_thread_list (pid)
int pid;
{
struct thread_info *tp;
for (tp = thread_list; tp; tp = tp->next)
if (tp->pid == pid)
return 1;
return 0; /* Never heard of 'im */
}
#if 0
void
bfd_get_core_threads (abfd)
bfd *abfd;
{
int i;
inferior_pid = BUILDPID (inferior_pid, core_thread (abfd)->pid);
for (i = 0; i < core_pss (abfd).threadcnt; i++)
add_thread (core_thread (abfd)[i].pid);
}
#endif
static void
prune_threads ()
{
struct thread_info *tp, *tpprev;
tpprev = 0;
for (tp = thread_list; tp; tp = tp->next)
if (tp->pid == -1)
{
if (tpprev)
tpprev->next = tp->next;
else
thread_list = NULL;
free (tp);
}
else
tpprev = tp;
}
/* Print information about currently known threads */
static void
info_threads_command (arg, from_tty)
char *arg;
int from_tty;
{
struct thread_info *tp;
int current_pid = inferior_pid;
for (tp = thread_list; tp; tp = tp->next)
{
if (target_has_execution
&& kill (tp->pid, 0) == -1)
{
tp->pid == -1; /* Mark it as dead */
continue;
}
if (tp->pid == current_pid)
printf_filtered ("* ");
else
printf_filtered (" ");
printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
thread_switch (tp->pid);
print_stack_frame (selected_frame, -1, 0);
}
thread_switch (current_pid);
prune_threads ();
}
/* Switch from one thread to another. */
void
thread_switch (pid)
int pid;
{
if (pid == inferior_pid)
return;
inferior_pid = pid;
pc_changed = 0;
flush_cached_frames ();
registers_changed ();
stop_pc = read_pc();
set_current_frame (create_new_frame (read_fp (), stop_pc));
stop_frame_address = FRAME_FP (get_current_frame ());
select_frame (get_current_frame (), 0);
}
static void
thread_command (tidstr, from_tty)
char *tidstr;
int from_tty;
{
int num;
struct thread_info *tp;
if (!tidstr)
error ("Please specify a thread ID. Use the \"info threads\" command to\n\
see the IDs of currently known threads.");
num = atoi (tidstr);
tp = find_thread_id (num);
if (!tp)
error ("Thread ID %d not known. Use the \"info threads\" command to\n\
see the IDs of currently known threads.", num);
thread_switch (tp->pid);
printf_filtered ("[Switching to %s]\n", target_pid_to_str (inferior_pid));
print_stack_frame (selected_frame, selected_frame_level, 1);
}
void
_initialize_thread ()
{
add_info ("threads", info_threads_command,
"IDs of currently known threads.");
add_com ("thread", class_info, thread_command,
"Use this command to switch between threads.\n\
The new thread ID must be currently known.");
}

29
gdb/thread.h Normal file
View File

@ -0,0 +1,29 @@
/************************************************************
(C) Copyright 1987-1992
Lynx Real-Time Systems, Inc.
Los Gatos, CA
All rights reserved.
$Date$
$Revision$
************************************************************/
#ifndef THREAD_H
#define THREAD_H
extern void init_thread_list PARAMS ((void));
extern void add_thread PARAMS ((int));
extern int in_thread_list PARAMS ((int));
#if 0
#ifdef __STDC__
struct _bfd;
#endif
extern void bfd_get_core_threads PARAMS ((struct _bfd *));
#endif
#endif /* THREAD_H */