From 43fc25c87e2e768f17030ac44ea434dfc756add0 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 13 Jul 1995 21:40:22 +0000 Subject: * 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/target.c | 528 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 508 insertions(+), 20 deletions(-) (limited to 'gdb/target.c') 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 (); } -- cgit v1.1