From 43fc25c87e2e768f17030ac44ea434dfc756add0 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 13 Jul 1995 21:40:22 +0000 Subject: [PATCH] * 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 --- gdb/ChangeLog | 51 +++++ gdb/corelow.c | 1 + gdb/gdbserver/low-lynx.c | 31 ++- gdb/gdbserver/low-sparc.c | 8 + gdb/gdbserver/low-sun3.c | 8 + gdb/m3-nat.c | 1 + gdb/procfs.c | 1 + gdb/remote-arc.c | 1 + gdb/remote-array.c | 1 + gdb/remote-es.c | 2 + gdb/remote-mips.c | 1 + gdb/remote-pa.c | 1 + gdb/remote-sim.c | 1 + gdb/remote.c | 27 ++- gdb/sparcl-tdep.c | 1 + gdb/target.c | 528 ++++++++++++++++++++++++++++++++++++++++++++-- gdb/thread.c | 7 +- 17 files changed, 635 insertions(+), 36 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d639e93..99c69f4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,54 @@ +Thu Jul 13 13:42:38 1995 Jeffrey A. Law + + * 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 + + * 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 + + * elfread.c (elf_symtab_read): Fix a bug ignoring compiler + generated internal labels ($LM...). + Wed Jul 5 11:38:36 1995 Kung Hsu * defs.h: if __GO32__ or WIN32 the directory separating symbol should diff --git a/gdb/corelow.c b/gdb/corelow.c index bf4a5fc..0d6fb81 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -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 */ diff --git a/gdb/gdbserver/low-lynx.c b/gdb/gdbserver/low-lynx.c index 1de79bd..79103c3 100644 --- a/gdb/gdbserver/low-lynx.c +++ b/gdb/gdbserver/low-lynx.c @@ -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; diff --git a/gdb/gdbserver/low-sparc.c b/gdb/gdbserver/low-sparc.c index f3e3b0e..7397876 100644 --- a/gdb/gdbserver/low-sparc.c +++ b/gdb/gdbserver/low-sparc.c @@ -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 diff --git a/gdb/gdbserver/low-sun3.c b/gdb/gdbserver/low-sun3.c index 21207e6..283c3fd 100644 --- a/gdb/gdbserver/low-sun3.c +++ b/gdb/gdbserver/low-sun3.c @@ -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 diff --git a/gdb/m3-nat.c b/gdb/m3-nat.c index 52a3eb6..75a8cb8 100644 --- a/gdb/m3-nat.c +++ b/gdb/m3-nat.c @@ -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 */ diff --git a/gdb/procfs.c b/gdb/procfs.c index c2605d5..699b8d2 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -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 */ diff --git a/gdb/remote-arc.c b/gdb/remote-arc.c index 7a97f3f..df984bd 100644 --- a/gdb/remote-arc.c +++ b/gdb/remote-arc.c @@ -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 */ diff --git a/gdb/remote-array.c b/gdb/remote-array.c index b7a9f4c..2ee7c9a 100644 --- a/gdb/remote-array.c +++ b/gdb/remote-array.c @@ -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 */ diff --git a/gdb/remote-es.c b/gdb/remote-es.c index 04ec81b..bd5e2bc 100644 --- a/gdb/remote-es.c +++ b/gdb/remote-es.c @@ -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 */ diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c index 6195dbb..b490443 100644 --- a/gdb/remote-mips.c +++ b/gdb/remote-mips.c @@ -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 */ diff --git a/gdb/remote-pa.c b/gdb/remote-pa.c index 58837bf..d131b47 100644 --- a/gdb/remote-pa.c +++ b/gdb/remote-pa.c @@ -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 */ diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index 637adae..79e5701 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -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 */ diff --git a/gdb/remote.c b/gdb/remote.c index 98916fc..8e59d4c 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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 */ diff --git a/gdb/sparcl-tdep.c b/gdb/sparcl-tdep.c index af8bc39..c74d06d 100644 --- a/gdb/sparcl-tdep.c +++ b/gdb/sparcl-tdep.c @@ -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 */ diff --git a/gdb/target.c b/gdb/target.c index 6abbd00..9368d58 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -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 (¤t_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"}, @@ -1145,6 +1220,14 @@ target_signal_from_host (hostsig) #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; } @@ -1290,7 +1373,20 @@ target_signal_to_host (oursig) #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, ¤t_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 (); } diff --git a/gdb/thread.c b/gdb/thread.c index 2e89274..6313173 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -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; -- 2.7.4