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:
parent
3481ad9a11
commit
25286543da
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ;;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
{
|
||||
|
|
|
@ -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 *) ®isters[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;
|
||||
}
|
30
gdb/procfs.c
30
gdb/procfs.c
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
{
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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'.",
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -310,7 +310,8 @@ sim_mourn ()
|
|||
}
|
||||
|
||||
static void
|
||||
rem_resume (a, b)
|
||||
rem_resume (pid, a, b)
|
||||
int pid;
|
||||
int a;
|
||||
int b;
|
||||
{
|
||||
|
|
|
@ -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.");
|
||||
}
|
|
@ -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 */
|
Loading…
Reference in New Issue