From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 123413 invoked by alias); 23 Jan 2018 21:18:49 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 123092 invoked by uid 440); 23 Jan 2018 21:18:47 -0000 Date: Tue, 23 Jan 2018 21:18:00 -0000 Message-ID: <20180123211846.123029.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/globalstate: Change the client states list to a map X-Git-Refname: refs/heads/scox/globalstate X-Git-Reftype: branch X-Git-Oldrev: bafd5fd4f7aece42f52b297ab26e95ada81b9346 X-Git-Newrev: f0f213d9ba8a71683e845a4caad9489bc3b8df98 X-SW-Source: 2018-q1/txt/msg00000.txt.bz2 List-Id: The branch, scox/globalstate has been updated via f0f213d9ba8a71683e845a4caad9489bc3b8df98 (commit) from bafd5fd4f7aece42f52b297ab26e95ada81b9346 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit f0f213d9ba8a71683e845a4caad9489bc3b8df98 Author: Stan Cox Date: Tue Nov 7 13:55:14 2017 -0500 Change the client states list to a map ----------------------------------------------------------------------- Summary of changes: gdb/gdbserver/ChangeLog | 38 ++- gdb/gdbserver/event-loop.c | 6 +- gdb/gdbserver/mem-break.c | 31 -- gdb/gdbserver/mem-break.h | 4 - gdb/gdbserver/remote-utils.c | 3 +- gdb/gdbserver/server.c | 602 ++++++++++++++++-------------- gdb/gdbserver/server.h | 43 ++- gdb/testsuite/gdb.server/multi-threads.c | 86 +++++ 8 files changed, 457 insertions(+), 356 deletions(-) create mode 100644 gdb/testsuite/gdb.server/multi-threads.c First 500 lines of diff: diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index f5aa20b..8fe9f8c 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,17 +1,15 @@ -<<<<<<< HEAD -2016-07-19 Stan Cox +2017-11-03 Stan Cox + + * server.h (client_breakpoints): Use a set. Change all users. + (multi_client_states.cs): Use a map. Change all users. + * mem-break.c (has_client_breakpoint_at): Move from here.. + * server.c (multi_client_states::has_client_breakpoint_at): ..to here + (client_state::client_state): New constructor. + (multi_client_states::set_client_state): Use it. Use client + states map. + (multi_client_states::add_client_breakpoint): Use client breaks + set. - * server.c (get_packet_type): Add Hg,m,M,g,G - (is_waiter): New. - (setup_multiplexing): Send shadow client notification when - vStopped received. - (notify_clients): Add have_first_notify to indicate if this is an - initial notification. Handle first and successive notify case. - (handle_monitor_command): Display thread info for client state - * server.h (new_general_thread): Intended for synchronizing - multiple client threads. - (in_buffer): Renamed notify_buffer. -======= 2017-10-21 Simon Marchi * gdbthread.h (find_thread, for_each_thread): New functions. @@ -1590,7 +1588,19 @@ (set_breakpoint_at): Call set_breakpoint_type_at. (set_reinsert_breakpoint): Call set_breakpoint_type_at. * mem-break.h (set_breakpoint_at): Update comments. ->>>>>>> gdb/master + +2016-07-19 Stan Cox + + * server.c (get_packet_type): Add Hg,m,M,g,G + (is_waiter): New. + (setup_multiplexing): Send shadow client notification when + vStopped received. + (notify_clients): Add have_first_notify to indicate if this is an + initial notification. Handle first and successive notify case. + (handle_monitor_command): Display thread info for client state + * server.h (new_general_thread): Intended for synchronizing + multiple client threads. + (in_buffer): Renamed notify_buffer. 2016-07-12 Chung-Lin Tang diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c index 5897125..c021973 100644 --- a/gdb/gdbserver/event-loop.c +++ b/gdb/gdbserver/event-loop.c @@ -386,7 +386,8 @@ delete_file_handler (gdb_fildes_t fd) prev_ptr->next_file = file_ptr->next_file; } - delete_client_state (fd); + struct multi_client_states *client_states = get_client_states(); + client_states->delete_client_state (fd); free (file_ptr); } @@ -428,8 +429,9 @@ handle_file_event (gdb_fildes_t event_file_desc) if (mask != 0) { /* Don't change client states if we have multiple clients */ + struct multi_client_states *client_states = get_client_states(); if (have_multiple_clients (file_ptr->fd)) - set_client_state (file_ptr->fd); + client_states->set_client_state (file_ptr->fd); if ((*file_ptr->proc) (file_ptr->error, file_ptr->client_data) < 0) return -1; diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index 54ef744..8c32360 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -359,37 +359,6 @@ find_raw_breakpoint_at (CORE_ADDR addr, enum raw_bkpt_type type, int kind) } -/* Does the client have a breakpoint at address ADDR? */ - -int -has_client_breakpoint_at (CORE_ADDR addr) -{ - client_state *cs = get_client_state (); - - struct client_breakpoint *cb; - - for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next) - { - if (addr == cb->addr) - { - if (debug_threads) - debug_printf ("%s:%d fd=%d return true at %#lx\n", - __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)cb->addr); - return 1; - } - } - - if (debug_threads) - { - debug_printf ("%s:%d fd=%d addr=%#lx breakpoints at:\n", __FUNCTION__, __LINE__, cs->file_desc, (long unsigned)addr); - for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next) - debug_printf (" %#lx", (long unsigned)cb->addr); - debug_printf ("\n"); - } - return 0; -} - - /* See mem-break.h. */ int diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h index 8008c20..54f0983 100644 --- a/gdb/gdbserver/mem-break.h +++ b/gdb/gdbserver/mem-break.h @@ -261,10 +261,6 @@ void uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc); void reinsert_fast_tracepoint_jumps_at (CORE_ADDR where); -/* Does a client have a breakpoint at addr? */ - -int has_client_breakpoint_at (CORE_ADDR addr); - /* Insert a memory breakpoint. */ int insert_memory_breakpoint (struct raw_breakpoint *bp); diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 558de50..09ed9de 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -178,7 +178,8 @@ handle_accept_event (int err, gdb_client_data client_data) if (remote_desc == -1) perror_with_name ("Accept failed"); - set_client_state (remote_desc); + struct multi_client_states *client_states = get_client_states(); + client_states->set_client_state (remote_desc); noack_mode = 0; /* Enable TCP keep alive process. */ diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 25db411..cb5a803 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -95,7 +95,7 @@ static struct btrace_config current_btrace_conf; DEFINE_QUEUE_P (notif_event_p); -static struct client_states client_states; +static struct multi_client_states client_states; enum pending_types {none_pending, pending_waitee, pending_cont_waiter, pending_step_waiter}; @@ -106,20 +106,76 @@ const char *packet_types_str[] = {"other", "vContc", "vConts","vContt","vRun", " const char *waitkind_str[] = {"exited", "stopped", "signalled", "loaded", "forked", "vforked", "execed", "vfork-done", "syscall-entry", "syscall-exit", "spurious", "ignore", "no-history", "not-resumed", "thread-created", "thread-exited", ""}; -/* Return the current client state */ +multi_client_states* +get_client_states (void) +{ + return &client_states; +} + client_state* get_client_state (void) { - /* was extern inline client_state* */ - return client_states.current_cs; + return client_states.get_client_state(); +} + + +client_state::client_state (gdb_fildes_t fd, client_state *csidx) +{ + file_desc = fd; + attached_to_client = csidx->attached_to_client; + nonstop_pending = csidx->nonstop_pending; + catch_syscalls = csidx->catch_syscalls; + extended_protocol_ = csidx->extended_protocol_; + response_needed_ = csidx->response_needed_; + exit_requested_ = csidx->exit_requested_; + run_once_ = csidx->run_once_; + multi_process_ = csidx->multi_process_; + report_fork_events_ = csidx->report_fork_events_; + report_vfork_events_ = csidx->report_vfork_events_; + report_exec_events_ = csidx->report_exec_events_; + report_thread_events_ = csidx->report_thread_events_; + report_no_resumed_ = csidx->report_no_resumed_; + non_stop_ = csidx->non_stop_; + swbreak_feature_ = csidx->swbreak_feature_; + hwbreak_feature_ = csidx->hwbreak_feature_; + vCont_supported_ = csidx->vCont_supported_; + disable_randomization_ = csidx->disable_randomization_; + program_name_ = csidx->program_name_; + program_args_ = csidx->program_args_; + wrapper_argv_ = csidx->wrapper_argv_; + remote_debug_ = csidx->remote_debug_; + noack_mode_ = csidx->noack_mode_; + transport_is_reliable_ = csidx->transport_is_reliable_; + ss = new (server_state); + ss->mem_buf_ = csidx->ss->mem_buf_; + ss->readchar_bufcnt_ = 0; + packet_type = other_packet; + last_packet_type = other_packet; + pending = none_pending; + notify_buffer_ = NULL; + own_buffer_ = (char*) xmalloc (PBUFSIZ + 1); + ss->attach_count_ = 0; + ss->cont_thread_ = null_ptid; + ss->general_thread_ = null_ptid; + ss->signal_pid_ = 0; + ss->last_ptid_ = null_ptid; + ss->last_status_.kind = TARGET_WAITKIND_IGNORE; + if (csidx->file_desc < 0) + { + ss->all_processes_ = all_processes; + ss->all_threads_ = all_threads; + ss->current_thread_ = current_thread; + } + else + ss->current_thread_ = NULL; } /* Add a new client state for FD or return if found */ client_state * -set_client_state (gdb_fildes_t fd) +multi_client_states::set_client_state (gdb_fildes_t fd) { /* States: * fd = -1 add initial client state @@ -131,152 +187,109 @@ set_client_state (gdb_fildes_t fd) /* add/return initial client state */ if (fd == -1) { - if (client_states.first == NULL) + if (client_states.cs.empty()) { - client_states.first = new (client_state); - client_states.first->ss = new (server_state); - client_states.first->file_desc = fd; + client_states.cs[fd] = new (client_state); + client_states.cs[fd]->ss = new (server_state); + client_states.cs[fd]->file_desc = fd; } - client_states.current_fd = fd; - client_states.current_cs = client_states.first; - get_client_state()->file_desc = fd; - return client_states.first; + client_states.current_cs = client_states.cs[fd]; + return client_states.cs[fd]; } /* add/return client state for fd F */ - for (csidx = client_states.first; ; csidx = csidx->next) + std::map::iterator it; + it = client_states.cs.find(fd); + if (it != client_states.cs.end()) { - - if (csidx->file_desc == fd) - { - client_states.current_fd = fd; - client_states.current_cs = csidx; - return csidx; - } - else if (csidx->next == NULL) - break; + client_states.current_cs = it->second; + return it->second; } + else + csidx = client_states.cs.rbegin()->second; /* add client state S for fd F */ - cs = new (client_state); - cs->attached_to_client = csidx->attached_to_client; - cs->nonstop_pending = csidx->nonstop_pending; - cs->catch_syscalls = csidx->catch_syscalls; - cs->extended_protocol_ = csidx->extended_protocol_; - cs->response_needed_ = csidx->response_needed_; - cs->exit_requested_ = csidx->exit_requested_; - cs->run_once_ = csidx->run_once_; - cs->multi_process_ = csidx->multi_process_; - cs->report_fork_events_ = csidx->report_fork_events_; - cs->report_vfork_events_ = csidx->report_vfork_events_; - cs->report_exec_events_ = csidx->report_exec_events_; - cs->report_thread_events_ = csidx->report_thread_events_; - cs->report_no_resumed_ = csidx->report_no_resumed_; - cs->non_stop_ = csidx->non_stop_; - cs->swbreak_feature_ = csidx->swbreak_feature_; - cs->hwbreak_feature_ = csidx->hwbreak_feature_; - cs->vCont_supported_ = csidx->vCont_supported_; - cs->disable_randomization_ = csidx->disable_randomization_; - cs->remote_debug_ = csidx->remote_debug_; - cs->noack_mode_ = csidx->noack_mode_; - cs->transport_is_reliable_ = csidx->transport_is_reliable_; - cs->next = csidx->next; - cs->ss = new (server_state); - cs->ss->mem_buf_ = csidx->ss->mem_buf_; - cs->ss->readchar_bufcnt_ = 0; - - // *(cs->ss) = *(csidx->ss); + client_states.cs[fd] = cs = new client_state (fd, csidx); cs->file_desc = fd; - cs->packet_type = other_packet; - cs->last_packet_type = other_packet; - cs->pending = none_pending; - cs->notify_buffer_ = NULL; - cs->own_buffer_ = (char*) xmalloc (PBUFSIZ + 1); - cs->client_breakpoints = NULL; - client_states.current_cs = cs; - cs->ss->attach_count_ = 0; - cs->ss->cont_thread_ = null_ptid; - cs->ss->general_thread_ = null_ptid; - cs->ss->signal_pid_ = 0; - cs->ss->last_ptid_ = null_ptid; - cs->ss->last_status_.kind = TARGET_WAITKIND_IGNORE; - cs->ss->current_thread_ = NULL; - // cs->ss->all_processes_.erase (cs->ss->all_processes_.begin(), cs->ss->all_processes_.end()); - // cs->ss->all_threads_.erase (cs->ss->all_threads_.begin(), cs->ss->all_threads_.end()); - client_states.current_fd = fd; - csidx->next = client_states.current_cs; + client_states.set_current_client (cs); return cs; } /* Add breakpoint ADDR to the per client breakpoint list */ -static void -add_client_breakpoint (CORE_ADDR addr) __attribute__ ((unused)); -static void -add_client_breakpoint (CORE_ADDR addr) +void +multi_client_states::add_client_breakpoint (CORE_ADDR addr) { - struct client_breakpoint *cb; - struct client_breakpoint *newcb; - client_state *cs = get_client_state(); - - for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next) - if (addr == cb->addr) - return; - else if (cb->next == NULL) - break; - newcb = XCNEW (struct client_breakpoint); - if (cb != NULL) - cb->next = newcb; - else - cs->client_breakpoints = newcb; - newcb->addr = addr; - newcb->next = NULL; + client_state *cs = get_client_state (); + cs->client_breakpoints.insert (addr); - for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next) - if (debug_threads) - debug_printf ("%s:%d %d %#lx breakpoint at %#lx\n", __FUNCTION__, __LINE__, get_client_state()->file_desc, (long unsigned)addr, (long unsigned)cb->addr); + std::unordered_set::iterator it; + if (debug_threads) + { + debug_printf ("%s %d ", __FUNCTION__, get_client_state()->file_desc); + for (it = cs->client_breakpoints.begin(); + it != cs->client_breakpoints.end(); ++it) + debug_printf ("%#llx ", *it); + debug_printf ("\n"); + } } /* Remove ADDR from the per client breakpoint list */ -static void -delete_client_breakpoint (CORE_ADDR addr) +void +multi_client_states::delete_client_breakpoint (CORE_ADDR addr) { - /* TODO gdb_remove_breakpoint removes breakpoints when we expect them - so lifetimes of list items needs improvement */ - struct client_breakpoint *cb; - struct client_breakpoint *previous_cb = NULL; - client_state *cs = get_client_state(); + client_state *cs = get_client_state (); + + if (addr) + cs->client_breakpoints.erase (addr); + else + cs->client_breakpoints.erase (cs->client_breakpoints.begin(), + cs->client_breakpoints.end()); - cb = cs->client_breakpoints; - while (cb != NULL) + std::unordered_set::iterator it; + if (debug_threads) { - struct client_breakpoint *next_cb; - if (addr == cb->addr || addr == 0) - { - if (! previous_cb) - cs->client_breakpoints = cb->next; - else - previous_cb->next = cb->next; + debug_printf ("%s %d ", __FUNCTION__, get_client_state()->file_desc); + for (it = cs->client_breakpoints.begin(); + it != cs->client_breakpoints.end(); ++it) + debug_printf ("%#llx ", *it); + debug_printf ("\n"); + } +} - next_cb = cb->next; - XDELETE (cb); - cb = next_cb; - continue; - } - previous_cb = cb; - cb = cb->next; + +/* Does the client have a breakpoint at address ADDR? */ + +int +multi_client_states::has_client_breakpoint_at (CORE_ADDR addr) +{ + std::unordered_set::iterator it; + client_state *cs = get_client_state (); + + if (debug_threads) + { + debug_printf ("%s:%d %d Breakpoint at %#llx? ", __FUNCTION__, __LINE__, get_client_state()->file_desc, addr); + + for (it = cs->client_breakpoints.begin(); + it != cs->client_breakpoints.end(); ++it) + debug_printf ("%#llx ", *it); + debug_printf ("\n"); } + + it = cs->client_breakpoints.find (addr); - for (cb = cs->client_breakpoints; cb != NULL; cb = cb->next) - if (debug_threads) - debug_printf ("%s:%d %d %#lx breakpoint at %#lx\n", __FUNCTION__, __LINE__, get_client_state()->file_desc, (long unsigned)addr, (long unsigned)cb->addr); + if (it != cs->client_breakpoints.end()) + return 1; + else + return 0; } -static int attached_to_same_proc (client_state *cs1, client_state *cs2) +static int +attached_to_same_proc (client_state *cs1, client_state *cs2) { return cs1->file_desc != -1 && cs2->file_desc != -1 && cs1 != cs2 && cs1->ss == cs2->ss; @@ -285,25 +298,26 @@ static int attached_to_same_proc (client_state *cs1, client_state *cs2) /* Free client state CS; considering the corresponding server state */ -static void free_client_state (client_state *cs) +void +multi_client_states::free_client_state (client_state *cs) { /* TODO keep reference count and delete when 0 */ - client_state *csi; - for (csi = client_states.first; csi != NULL; csi = csi->next) + std::map::iterator it; + + for (it = client_states.cs.begin(); it != client_states.cs.end(); ++it) { - if (attached_to_same_proc (cs, csi)) + if (attached_to_same_proc (cs, it->second)) break; } - delete_client_breakpoint (0); - if (csi == NULL) - // XDELETE (cs->ss); - free (cs->ss); + if (it == client_states.cs.end()) + delete (cs->ss); + client_states.delete_client_breakpoint (0); + if (cs->notify_buffer_) xfree (cs->notify_buffer_); free (cs->own_buffer_); - // XDELETE (cs); hooks/post-receive -- Repository for Project Archer.