2008-10-27 Pedro Alves * target.h (struct target_ops) : New field. (target_supports_multi_process): New define. * target.c (update_current_target): Inherit and de_fault to_supports_multi_process. * infcmd.c (attach_command): Allow attaching to multiple processes if the target supports it. (detach_command): If the target claims there is still execution, don't clear the thread list. * remote.c (remote_supports_multi_process): New. (init_remote_ops): Register remote_supports_multi_process. --- gdb/infcmd.c | 12 ++++++++++-- gdb/remote.c | 8 ++++++++ gdb/target.c | 4 ++++ gdb/target.h | 10 ++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) Index: src/gdb/target.h =================================================================== --- src.orig/gdb/target.h 2008-10-27 12:27:28.000000000 +0000 +++ src/gdb/target.h 2008-10-27 12:27:30.000000000 +0000 @@ -536,6 +536,10 @@ struct target_ops /* Can target execute in reverse? */ int (*to_can_execute_reverse) (); + /* Does this target support debugging multiple processes + simultaneously? */ + int (*to_supports_multi_process) (void); + int to_magic; /* Need sub-structure for target machine related rather than comm related? */ @@ -647,6 +651,12 @@ extern void target_resume (ptid_t ptid, #define target_prepare_to_store(regcache) \ (*current_target.to_prepare_to_store) (regcache) +/* Returns true if this target can debug multiple processes + simultaneously. */ + +#define target_supports_multi_process() \ + (*current_target.to_supports_multi_process) () + extern DCACHE *target_dcache; extern int target_read_string (CORE_ADDR, char **, int, int *); Index: src/gdb/target.c =================================================================== --- src.orig/gdb/target.c 2008-10-27 12:27:28.000000000 +0000 +++ src/gdb/target.c 2008-10-27 12:27:30.000000000 +0000 @@ -471,6 +471,7 @@ update_current_target (void) /* Do not inherit to_read_description. */ INHERIT (to_get_ada_task_ptid, t); /* Do not inherit to_search_memory. */ + INHERIT (to_supports_multi_process, t); INHERIT (to_magic, t); /* Do not inherit to_memory_map. */ /* Do not inherit to_flash_erase. */ @@ -638,6 +639,9 @@ update_current_target (void) de_fault (to_get_ada_task_ptid, (ptid_t (*) (long, long)) default_get_ada_task_ptid); + de_fault (to_supports_multi_process, + (int (*) (void)) + return_zero); #undef de_fault /* Finally, position the target-stack beneath the squashed Index: src/gdb/infcmd.c =================================================================== --- src.orig/gdb/infcmd.c 2008-10-27 12:27:28.000000000 +0000 +++ src/gdb/infcmd.c 2008-10-27 12:32:26.000000000 +0000 @@ -2201,7 +2201,10 @@ attach_command (char *args, int from_tty dont_repeat (); /* Not for the faint of heart */ - if (target_has_execution) + if (target_supports_multi_process ()) + /* Don't complain if we can be attached to multiple processes. */ + ; + else if (target_has_execution) { if (query ("A program is being debugged already. Kill it? ")) target_kill (); @@ -2311,7 +2314,12 @@ detach_command (char *args, int from_tty dont_repeat (); /* Not for the faint of heart. */ target_detach (args, from_tty); no_shared_libraries (NULL, from_tty); - init_thread_list (); + + /* If the current target interface claims there's still execution, + then don't mess with threads of other processes. */ + if (!target_has_execution) + init_thread_list (); + if (deprecated_detach_hook) deprecated_detach_hook (); } Index: src/gdb/remote.c =================================================================== --- src.orig/gdb/remote.c 2008-10-27 12:27:28.000000000 +0000 +++ src/gdb/remote.c 2008-10-27 12:27:30.000000000 +0000 @@ -8554,6 +8554,13 @@ remote_supports_non_stop (void) return 1; } +static int +remote_supports_multi_process (void) +{ + struct remote_state *rs = get_remote_state (); + return remote_multi_process_p (rs); +} + static void init_remote_ops (void) { @@ -8616,6 +8623,7 @@ Specify the serial device it is connecte remote_ops.to_terminal_inferior = remote_terminal_inferior; remote_ops.to_terminal_ours = remote_terminal_ours; remote_ops.to_supports_non_stop = remote_supports_non_stop; + remote_ops.to_supports_multi_process = remote_supports_multi_process; } /* Set up the extended remote vector by making a copy of the standard