* inftarg.c (child_thread_alive): New function to see if a

particular thread is still running.
        (child_ops): Add child_thread_alive entry.
        * remote.c (remote_thread_alive): New function to see if a
        particular thread is still alive.
        (remote_ops): Add remote_thread_alive.
        * target.c (dummy_target): Add dummy entry for thread_alive.
        (cleanup_target): de_fault thread_alive too.
        (update_current_target): INHERIT thread_alive too.
        (debug_to_thread_alive): New function.
        (setup_target_debug): Add debug_to_thread_alive.
        * target.h (struct target_ops): Add to_thread_alive.
        (target_thread_alive): Define.
        * thread.c (info_threads_command): Don't call kill; use
        target_thread_alive instead.
        * config/nm-lynx.h (CHILD_THREAD_ALIVE): Define.
        * gdbserver/low-lynx.c (mythread_alive): New function.
        (mywait): Don't restart any threads after a new thread notification,
        let the generic code handle it.
        * gdbserver/low-sparc.c (mythread_alive): Dummy version.
        * gdbserver/low-sun3.c (mythread_alive): Likewise.
        * gdbserver/server.c (main): Handle thread_alive requests.
        * gdbserver/server.h (mythread_alive): Declare.
        * corelow.c (core_ops): Add dummy entry for thread_alive.
        * exec.c (exec_ops): Likewise.
        * m3-nat.c (m3_ops): Likewise.
        * monitor.c (monitor_ops): Likewise.
        * procfs.c (procfs_ops): Likewise.
        * remote-arc.c (arc_ops): Likewise.
        * remote-array.c (array_ops): Likewise.
        * remote-e7000.c (e7000_ops): Likewise.
        * remote-es.c (es1800_ops, es1800_child_ops): Likewise.
        * remote-mips.c (mips_ops): Likewise.
        * remote-pa.c (remote_hppro_ops): Likewise.
        * remote-sim.c (gdbsim_ops): Likewise.
        * sparcl-tdep.c (sparclite_ops): Likewise.

More lynx-6100 work
This commit is contained in:
Jeff Law 1995-07-13 21:40:22 +00:00
parent 37ea61215c
commit 43fc25c87e
17 changed files with 635 additions and 36 deletions

View File

@ -1,3 +1,54 @@
Thu Jul 13 13:42:38 1995 Jeffrey A. Law <law@rtl.cygnus.com>
* inftarg.c (child_thread_alive): New function to see if a
particular thread is still running.
(child_ops): Add child_thread_alive entry.
* remote.c (remote_thread_alive): New function to see if a
particular thread is still alive.
(remote_ops): Add remote_thread_alive.
* target.c (dummy_target): Add dummy entry for thread_alive.
(cleanup_target): de_fault thread_alive too.
(update_current_target): INHERIT thread_alive too.
(debug_to_thread_alive): New function.
(setup_target_debug): Add debug_to_thread_alive.
* target.h (struct target_ops): Add to_thread_alive.
(target_thread_alive): Define.
* thread.c (info_threads_command): Don't call kill; use
target_thread_alive instead.
* config/nm-lynx.h (CHILD_THREAD_ALIVE): Define.
* gdbserver/low-lynx.c (mythread_alive): New function.
(mywait): Don't restart any threads after a new thread notification,
let the generic code handle it.
* gdbserver/low-sparc.c (mythread_alive): Dummy version.
* gdbserver/low-sun3.c (mythread_alive): Likewise.
* gdbserver/server.c (main): Handle thread_alive requests.
* gdbserver/server.h (mythread_alive): Declare.
* corelow.c (core_ops): Add dummy entry for thread_alive.
* exec.c (exec_ops): Likewise.
* m3-nat.c (m3_ops): Likewise.
* monitor.c (monitor_ops): Likewise.
* procfs.c (procfs_ops): Likewise.
* remote-arc.c (arc_ops): Likewise.
* remote-array.c (array_ops): Likewise.
* remote-e7000.c (e7000_ops): Likewise.
* remote-es.c (es1800_ops, es1800_child_ops): Likewise.
* remote-mips.c (mips_ops): Likewise.
* remote-pa.c (remote_hppro_ops): Likewise.
* remote-sim.c (gdbsim_ops): Likewise.
* sparcl-tdep.c (sparclite_ops): Likewise.
Tue Jul 11 11:15:55 1995 Kung Hsu <kung@rtl.cygnus.com>
* solib.c: Add _DYNAMIC__MGC base symbol for Mentor Graphics Inc.
* solib.c (match_main): New function for checking name of main.
* solib.c (solib_add): Not to add if solib match main.
Fri Jul 7 14:41:56 1995 Kung Hsu <kung@rtl.cygnus.com>
* elfread.c (elf_symtab_read): Fix a bug ignoring compiler
generated internal labels ($LM...).
Wed Jul 5 11:38:36 1995 Kung Hsu <kung@rtl.cygnus.com>
* defs.h: if __GO32__ or WIN32 the directory separating symbol should

View File

@ -359,6 +359,7 @@ struct target_ops core_ops = {
0, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
core_stratum, /* to_stratum */
0, /* to_next */

View File

@ -99,6 +99,24 @@ kill_inferior ()
inferior_pid = 0;
}
/* Return nonzero if the given thread is still alive. */
int
mythread_alive (pid)
int pid;
{
/* Arggh. Apparently pthread_kill only works for threads within
the process that calls pthread_kill.
We want to avoid the lynx signal extensions as they simply don't
map well to the generic gdb interface we want to keep.
All we want to do is determine if a particular thread is alive;
it appears as if we can just make a harmless thread specific
ptrace call to do that. */
return (ptrace (PTRACE_THREADUSER,
BUILDPID (PIDGET (inferior_pid), pid), 0, 0) != -1);
}
/* Wait for process, returns status */
unsigned char
@ -132,12 +150,13 @@ mywait (status)
if (realsig == SIGNEWTHREAD)
{
/* Simply ignore new thread notification, as we can't do anything
useful with such threads. All ptrace calls at this point just
fail for no apparent reason. The thread will eventually get a
real signal when it becomes real. */
myresume (0, 0);
continue;
/* It's a new thread notification. Nothing to do here since
the machine independent code in wait_for_inferior will
add the thread to the thread list and restart the thread
when pid != inferior_pid and pid is not in the thread list.
We don't even want to muck with realsig -- the code in
wait_for_inferior expects SIGTRAP. */
;
}
}
break;

View File

@ -98,6 +98,14 @@ kill_inferior ()
/*************inferior_died ();****VK**************/
}
/* Return nonzero if the given thread is still alive. */
int
mythread_alive (pid)
int pid;
{
return 1;
}
/* Wait for process, returns status */
unsigned char

View File

@ -95,6 +95,14 @@ kill_inferior ()
/*************inferior_died ();****VK**************/
}
/* Return nonzero if the given thread is still alive. */
int
mythread_alive (pid)
int pid;
{
return 1;
}
/* Wait for process, returns status */
unsigned char

View File

@ -4554,6 +4554,7 @@ struct target_ops m3_ops = {
m3_mourn_inferior, /* to_mourn_inferior */
m3_can_run, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
m3_stop, /* to_stop */
process_stratum, /* to_stratum */
0, /* to_next */

View File

@ -3765,6 +3765,7 @@ struct target_ops procfs_ops = {
procfs_mourn_inferior, /* to_mourn_inferior */
procfs_can_run, /* to_can_run */
procfs_notice_signals, /* to_notice_signals */
0 /* to_thread_alive */
procfs_stop, /* to_stop */
process_stratum, /* to_stratum */
0, /* to_next */

View File

@ -1009,6 +1009,7 @@ Specify the device it is connected to.", /* to_doc */
arc_mourn, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
NULL, /* to_next */

View File

@ -156,6 +156,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
array_mourn_inferior, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
0, /* to_next */

View File

@ -2075,6 +2075,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
NULL, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
core_stratum, /* to_stratum */
0, /* to_next */
@ -2123,6 +2124,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
es1800_mourn_inferior, /* to_mourn_inferior */
0, /* to_can_run */
0, /* notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
0, /* to_next */

View File

@ -1563,6 +1563,7 @@ HOST:PORT to access a board over a network", /* to_doc */
mips_mourn_inferior, /* to_mourn_inferior */
NULL, /* to_can_run */
NULL, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
NULL, /* to_next */

View File

@ -1502,6 +1502,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya) or telnet port.",
remote_mourn, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
NULL, /* to_next */

View File

@ -440,6 +440,7 @@ struct target_ops gdbsim_ops = {
gdbsim_mourn_inferior, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
NULL, /* to_next */

View File

@ -191,10 +191,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Prototypes for local functions */
static int remote_write_bytes PARAMS ((CORE_ADDR memaddr,
unsigned char *myaddr, int len));
char *myaddr, int len));
static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
unsigned char *myaddr, int len));
char *myaddr, int len));
static void remote_files_info PARAMS ((struct target_ops *ignore));
@ -313,6 +313,24 @@ set_thread (th, gen)
cont_thread = th;
}
/* Return nonzero if the thread TH is still alive on the remote system. */
static int
remote_thread_alive (th)
int th;
{
char buf[PBUFSIZ];
buf[0] = 'T';
if (th < 0)
sprintf (&buf[1], "-%x", -th);
else
sprintf (&buf[1], "%x", th);
putpkt (buf);
getpkt (buf, 0);
return (buf[0] == 'O' && buf[1] == 'K');
}
/* Clean up connection to a remote debugger. */
/* ARGSUSED */
@ -940,7 +958,7 @@ remote_store_word (addr, word)
static int
remote_write_bytes (memaddr, myaddr, len)
CORE_ADDR memaddr;
unsigned char *myaddr;
char *myaddr;
int len;
{
char buf[PBUFSIZ];
@ -988,7 +1006,7 @@ remote_write_bytes (memaddr, myaddr, len)
static int
remote_read_bytes (memaddr, myaddr, len)
CORE_ADDR memaddr;
unsigned char *myaddr;
char *myaddr;
int len;
{
char buf[PBUFSIZ];
@ -1570,6 +1588,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
remote_mourn, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
remote_thread_alive, /* to_thread_alive */
0, /* to_stop */
process_stratum, /* to_stratum */
NULL, /* to_next */

View File

@ -858,6 +858,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
0, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
download_stratum, /* to_stratum */
0, /* to_next */

View File

@ -84,24 +84,47 @@ unsigned target_struct_allocsize;
/* The initial current target, so that there is always a semi-valid
current target. */
struct target_ops dummy_target = {"None", "None", "",
0, 0, /* open, close */
find_default_attach, 0, /* attach, detach */
0, 0, /* resume, wait */
0, 0, 0, /* registers */
0, 0, /* memory */
0, 0, /* bkpts */
0, 0, 0, 0, 0, /* terminal */
0, 0, /* kill, load */
0, /* lookup_symbol */
find_default_create_inferior, /* create_inferior */
0, /* mourn_inferior */
0, /* can_run */
0, /* notice_signals */
dummy_stratum, 0, /* stratum, next */
0, 0, 0, 0, 0, /* all mem, mem, stack, regs, exec */
0, 0, /* section pointers */
OPS_MAGIC,
struct target_ops dummy_target = {
"None", /* to_shortname */
"None", /* to_longname */
"", /* to_doc */
0, /* to_open */
0, /* to_close */
find_default_attach, /* to_attach */
0, /* to_detach */
0, /* to_resume */
0, /* to_wait */
0, /* to_fetch_registers */
0, /* to_store_registers */
0, /* to_prepare_to_store */
0, /* to_xfer_memory */
0, /* to_files_info */
0, /* to_insert_breakpoint */
0, /* to_remove_breakpoint */
0, /* to_terminal_init */
0, /* to_terminal_inferior */
0, /* to_terminal_ours_for_output */
0, /* to_terminal_ours */
0, /* to_terminal_info */
0, /* to_kill */
0, /* to_load */
0, /* to_lookup_symbol */
find_default_create_inferior, /* to_create_inferior */
0, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
dummy_stratum, /* to_stratum */
0, /* to_next */
0, /* to_next */
0, /* to_has_all_memory */
0, /* to_has_memory */
0, /* to_has_registers */
0, /* to_has_execution */
0, /* to_sections */
0, /* to_sections_end */
OPS_MAGIC, /* to_magic */
};
/* Top of target stack. */
@ -122,6 +145,15 @@ static struct cmd_list_element *targetlist = NULL;
int attach_flag;
#ifdef MAINTENANCE_CMDS
/* Non-zero if we want to see trace of target level stuff. */
static int targetdebug = 0;
static void setup_target_debug PARAMS ((void));
#endif
/* The user just typed 'target' without the name of a target. */
/* ARGSUSED */
@ -300,6 +332,8 @@ cleanup_target (t)
de_fault (to_mourn_inferior, (void (*)())noprocess);
de_fault (to_can_run, return_zero);
de_fault (to_notice_signals, (void (*)())ignore);
de_fault (to_thread_alive, (void (*)())ignore);
de_fault (to_stop, (void (*)())ignore);
#undef de_fault
}
@ -353,6 +387,8 @@ update_current_target ()
INHERIT (to_mourn_inferior, t);
INHERIT (to_can_run, t);
INHERIT (to_notice_signals, t);
INHERIT (to_thread_alive, t);
INHERIT (to_stop, t);
INHERIT (to_stratum, t);
INHERIT (DONT_USE, t);
INHERIT (to_has_all_memory, t);
@ -433,6 +469,12 @@ push_target (t)
update_current_target ();
cleanup_target (&current_target); /* Fill in the gaps */
#ifdef MAINTENANCE_CMDS
if (targetdebug)
setup_target_debug ();
#endif
return prev != 0;
}
@ -806,7 +848,7 @@ find_default_run_target (do_mesg)
for (t = target_structs; t < target_structs + target_struct_size;
++t)
{
if (target_can_run(*t))
if ((*t)->to_can_run && target_can_run(*t))
{
runable = *t;
++count;
@ -951,6 +993,39 @@ static struct {
{"SIGMSG", "Monitor mode data available"},
{"SIGSOUND", "Sound completed"},
{"SIGSAK", "Secure attention"},
{"SIGPRIO", "SIGPRIO"},
{"SIG33", "Real-time event 33"},
{"SIG34", "Real-time event 34"},
{"SIG35", "Real-time event 35"},
{"SIG36", "Real-time event 36"},
{"SIG37", "Real-time event 37"},
{"SIG38", "Real-time event 38"},
{"SIG39", "Real-time event 39"},
{"SIG40", "Real-time event 40"},
{"SIG41", "Real-time event 41"},
{"SIG42", "Real-time event 42"},
{"SIG43", "Real-time event 43"},
{"SIG44", "Real-time event 44"},
{"SIG45", "Real-time event 45"},
{"SIG46", "Real-time event 46"},
{"SIG47", "Real-time event 47"},
{"SIG48", "Real-time event 48"},
{"SIG49", "Real-time event 49"},
{"SIG50", "Real-time event 50"},
{"SIG51", "Real-time event 51"},
{"SIG52", "Real-time event 52"},
{"SIG53", "Real-time event 53"},
{"SIG54", "Real-time event 54"},
{"SIG55", "Real-time event 55"},
{"SIG56", "Real-time event 56"},
{"SIG57", "Real-time event 57"},
{"SIG58", "Real-time event 58"},
{"SIG59", "Real-time event 59"},
{"SIG60", "Real-time event 60"},
{"SIG61", "Real-time event 61"},
{"SIG62", "Real-time event 62"},
{"SIG63", "Real-time event 63"},
{NULL, "Unknown signal"},
{NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"},
@ -1144,6 +1219,14 @@ target_signal_from_host (hostsig)
#endif
#if defined (SIGSAK)
if (hostsig == SIGSAK) return TARGET_SIGNAL_SAK;
#endif
#if defined (SIGPRIO)
if (hostsig == SIGPRIO) return TARGET_SIGNAL_PRIO;
#endif
#if defined (REALTIME_LO)
if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
return (enum target_signal)
(hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33);
#endif
return TARGET_SIGNAL_UNKNOWN;
}
@ -1289,8 +1372,21 @@ target_signal_to_host (oursig)
#endif
#if defined (SIGSAK)
case TARGET_SIGNAL_SAK: return SIGSAK;
#endif
#if defined (SIGPRIO)
case TARGET_SIGNAL_PRIO: return SIGPRIO;
#endif
default:
#if defined (REALTIME_LO)
if (oursig >= TARGET_SIGNAL_REALTIME_33
&& oursig <= TARGET_SIGNAL_REALTIME_63)
{
int retsig =
(int)oursig - (int)TARGET_SIGNAL_REALTIME_33 + REALTIME_LO;
if (retsig < REALTIME_HI)
return retsig;
}
#endif
/* The user might be trying to do "signal SIGSAK" where this system
doesn't have SIGSAK. */
warning ("Signal %s does not exist on this system.\n",
@ -1330,7 +1426,24 @@ store_waitstatus (ourstatus, hoststatus)
ourstatus->value.sig = target_signal_from_host (WSTOPSIG (hoststatus));
}
}
/* In some circumstances we allow a command to specify a numeric
signal. The idea is to keep these circumstances limited so that
users (and scripts) develop portable habits. For comparison,
POSIX.2 `kill' requires that 1,2,3,6,9,14, and 15 work (and using a
numeric signal at all is obscelescent. We are slightly more
lenient and allow 1-15 which should match host signal numbers on
most systems. Use of symbolic signal names is strongly encouraged. */
enum target_signal
target_signal_from_command (num)
int num;
{
if (num >= 1 && num <= 15)
return (enum target_signal)num;
error ("Only signals 1-15 are valid as numeric signals.\n\
Use \"info signals\" for a list of symbolic signals.");
}
/* Returns zero to leave the inferior alone, one to interrupt it. */
int (*target_activity_function) PARAMS ((void));
@ -1345,11 +1458,377 @@ normal_pid_to_str (pid)
{
static char buf[30];
sprintf (buf, "process %d", pid);
if (STREQ (current_target.to_shortname, "remote"))
sprintf (buf, "thread %d", pid);
else
sprintf (buf, "process %d", pid);
return buf;
}
#ifdef MAINTENANCE_CMDS
static struct target_ops debug_target;
static void
debug_to_open (args, from_tty)
char *args;
int from_tty;
{
debug_target.to_open (args, from_tty);
fprintf_unfiltered (stderr, "target_open (%s, %d)\n", args, from_tty);
}
static void
debug_to_close (quitting)
int quitting;
{
debug_target.to_close (quitting);
fprintf_unfiltered (stderr, "target_close (%d)\n", quitting);
}
static void
debug_to_attach (args, from_tty)
char *args;
int from_tty;
{
debug_target.to_attach (args, from_tty);
fprintf_unfiltered (stderr, "target_attach (%s, %d)\n", args, from_tty);
}
static void
debug_to_detach (args, from_tty)
char *args;
int from_tty;
{
debug_target.to_detach (args, from_tty);
fprintf_unfiltered (stderr, "target_detach (%s, %d)\n", args, from_tty);
}
static void
debug_to_resume (pid, step, siggnal)
int pid;
int step;
enum target_signal siggnal;
{
debug_target.to_resume (pid, step, siggnal);
fprintf_unfiltered (stderr, "target_resume (%d, %s, %s)\n", pid,
step ? "step" : "continue",
target_signal_to_name (siggnal));
}
static int
debug_to_wait (pid, status)
int pid;
struct target_waitstatus *status;
{
int retval;
retval = debug_target.to_wait (pid, status);
fprintf_unfiltered (stderr, "target_wait (%d, status) = %d, ", pid, retval);
fprintf_unfiltered (stderr, "status->kind = ");
switch (status->kind)
{
case TARGET_WAITKIND_EXITED:
fprintf_unfiltered (stderr, "exited, status = %d\n", status->value.integer);
break;
case TARGET_WAITKIND_STOPPED:
fprintf_unfiltered (stderr, "stopped, signal = %s\n",
target_signal_to_name (status->value.sig));
break;
case TARGET_WAITKIND_SIGNALLED:
fprintf_unfiltered (stderr, "signalled, signal = %s\n",
target_signal_to_name (status->value.sig));
break;
case TARGET_WAITKIND_LOADED:
fprintf_unfiltered (stderr, "loaded\n");
break;
case TARGET_WAITKIND_SPURIOUS:
fprintf_unfiltered (stderr, "spurious\n");
break;
default:
fprintf_unfiltered (stderr, "unknown???\n");
break;
}
return retval;
}
static void
debug_to_fetch_registers (regno)
int regno;
{
debug_target.to_fetch_registers (regno);
fprintf_unfiltered (stderr, "target_fetch_registers (%s)",
regno != -1 ? reg_names[regno] : "-1");
if (regno != -1)
fprintf_unfiltered (stderr, " = 0x%x %d", read_register (regno),
read_register (regno));
fprintf_unfiltered (stderr, "\n");
}
static void
debug_to_store_registers (regno)
int regno;
{
debug_target.to_store_registers (regno);
if (regno >= 0 && regno < NUM_REGS)
fprintf_unfiltered (stderr, "target_store_registers (%s) = 0x%x %d\n",
reg_names[regno], read_register (regno),
read_register (regno));
else
fprintf_unfiltered (stderr, "target_store_registers (%d)\n", regno);
}
static void
debug_to_prepare_to_store ()
{
debug_target.to_prepare_to_store ();
fprintf_unfiltered (stderr, "target_prepare_to_store ()\n");
}
static int
debug_to_xfer_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
struct target_ops *target;
{
int retval;
retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
fprintf_unfiltered (stderr, "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
memaddr, len, write ? "write" : "read", retval);
if (retval > 0)
{
int i;
fputs_unfiltered (", bytes =", gdb_stderr);
for (i = 0; i < retval; i++)
fprintf_unfiltered (stderr, " %02x", myaddr[i] & 0xff);
}
fputc_unfiltered ('\n', gdb_stderr);
return retval;
}
static void
debug_to_files_info (target)
struct target_ops *target;
{
debug_target.to_files_info (target);
fprintf_unfiltered (stderr, "target_files_info (xxx)\n");
}
static int
debug_to_insert_breakpoint (addr, save)
CORE_ADDR addr;
char *save;
{
int retval;
retval = debug_target.to_insert_breakpoint (addr, save);
fprintf_unfiltered (stderr, "target_insert_breakpoint (0x%x, xxx) = %d\n",
addr, retval);
return retval;
}
static int
debug_to_remove_breakpoint (addr, save)
CORE_ADDR addr;
char *save;
{
int retval;
retval = debug_target.to_remove_breakpoint (addr, save);
fprintf_unfiltered (stderr, "target_remove_breakpoint (0x%x, xxx) = %d\n",
addr, retval);
return retval;
}
static void
debug_to_terminal_init ()
{
debug_target.to_terminal_init ();
fprintf_unfiltered (stderr, "target_terminal_init ()\n");
}
static void
debug_to_terminal_inferior ()
{
debug_target.to_terminal_inferior ();
fprintf_unfiltered (stderr, "target_terminal_inferior ()\n");
}
static void
debug_to_terminal_ours_for_output ()
{
debug_target.to_terminal_ours_for_output ();
fprintf_unfiltered (stderr, "target_terminal_ours_for_output ()\n");
}
static void
debug_to_terminal_ours ()
{
debug_target.to_terminal_ours ();
fprintf_unfiltered (stderr, "target_terminal_ours ()\n");
}
static void
debug_to_terminal_info (arg, from_tty)
char *arg;
int from_tty;
{
debug_target.to_terminal_info (arg, from_tty);
fprintf_unfiltered (stderr, "target_terminal_info (%s, %d)\n", arg,
from_tty);
}
static void
debug_to_kill ()
{
debug_target.to_kill ();
fprintf_unfiltered (stderr, "target_kill ()\n");
}
static void
debug_to_load (args, from_tty)
char *args;
int from_tty;
{
debug_target.to_load (args, from_tty);
fprintf_unfiltered (stderr, "target_load (%s, %d)\n", args, from_tty);
}
static int
debug_to_lookup_symbol (name, addrp)
char *name;
CORE_ADDR *addrp;
{
int retval;
retval = debug_target.to_lookup_symbol (name, addrp);
fprintf_unfiltered (stderr, "target_lookup_symbol (%s, xxx)\n", name);
return retval;
}
static void
debug_to_create_inferior (exec_file, args, env)
char *exec_file;
char *args;
char **env;
{
debug_target.to_create_inferior (exec_file, args, env);
fprintf_unfiltered (stderr, "target_create_inferior (%s, %s, xxx)\n",
exec_file, args);
}
static void
debug_to_mourn_inferior ()
{
debug_target.to_mourn_inferior ();
fprintf_unfiltered (stderr, "target_mourn_inferior ()\n");
}
static int
debug_to_can_run ()
{
int retval;
retval = debug_target.to_can_run ();
fprintf_unfiltered (stderr, "target_can_run () = %d\n", retval);
return retval;
}
static void
debug_to_notice_signals (pid)
int pid;
{
debug_target.to_notice_signals (pid);
fprintf_unfiltered (stderr, "target_notice_signals (%d)\n", pid);
}
static void
debug_to_thread_alive (pid)
int pid;
{
debug_target.to_thread_alive (pid);
fprintf_unfiltered (stderr, "target_thread_alive (%d)\n", pid);
}
static void
debug_to_stop ()
{
debug_target.to_stop ();
fprintf_unfiltered (stderr, "target_stop ()\n");
}
static void
setup_target_debug ()
{
memcpy (&debug_target, &current_target, sizeof debug_target);
current_target.to_open = debug_to_open;
current_target.to_close = debug_to_close;
current_target.to_attach = debug_to_attach;
current_target.to_detach = debug_to_detach;
current_target.to_resume = debug_to_resume;
current_target.to_wait = debug_to_wait;
current_target.to_fetch_registers = debug_to_fetch_registers;
current_target.to_store_registers = debug_to_store_registers;
current_target.to_prepare_to_store = debug_to_prepare_to_store;
current_target.to_xfer_memory = debug_to_xfer_memory;
current_target.to_files_info = debug_to_files_info;
current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
current_target.to_terminal_init = debug_to_terminal_init;
current_target.to_terminal_inferior = debug_to_terminal_inferior;
current_target.to_terminal_ours_for_output = debug_to_terminal_ours_for_output;
current_target.to_terminal_ours = debug_to_terminal_ours;
current_target.to_terminal_info = debug_to_terminal_info;
current_target.to_kill = debug_to_kill;
current_target.to_load = debug_to_load;
current_target.to_lookup_symbol = debug_to_lookup_symbol;
current_target.to_create_inferior = debug_to_create_inferior;
current_target.to_mourn_inferior = debug_to_mourn_inferior;
current_target.to_can_run = debug_to_can_run;
current_target.to_notice_signals = debug_to_notice_signals;
current_target.to_thread_alive = debug_to_thread_alive;
current_target.to_stop = debug_to_stop;
}
#endif /* MAINTENANCE_CMDS */
static char targ_desc[] =
"Names of targets and files being debugged.\n\
Shows the entire stack of targets currently in use (including the exec-file,\n\
@ -1363,6 +1842,15 @@ initialize_targets ()
add_info ("target", target_info, targ_desc);
add_info ("files", target_info, targ_desc);
#ifdef MAINTENANCE_CMDS
add_show_from_set (
add_set_cmd ("targetdebug", class_maintenance, var_zinteger,
(char *)&targetdebug,
"Set target debugging.\n\
When non-zero, target debugging is enabled.", &setlist),
&showlist);
#endif
if (!STREQ (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC"))
abort ();
}

View File

@ -280,12 +280,7 @@ info_threads_command (arg, from_tty)
for (tp = thread_list; tp; tp = tp->next)
{
/* FIXME: need to figure out a way to do this for remote too,
or else the print_stack_frame below will fail with a bogus
thread ID. */
if (!STREQ (current_target.to_shortname, "remote")
&& target_has_execution
&& kill (tp->pid, 0) == -1)
if (! target_thread_alive (tp->pid))
{
tp->pid = -1; /* Mark it as dead */
continue;