From patchwork Sun Nov 15 16:53:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stan Cox X-Patchwork-Id: 9672 Received: (qmail 79412 invoked by alias); 15 Nov 2015 16:53:57 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 78860 invoked by uid 89); 15 Nov 2015 16:53:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_50, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sun, 15 Nov 2015 16:53:51 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 88C63C0A515C for ; Sun, 15 Nov 2015 16:53:50 +0000 (UTC) Received: from localhost.localdomain (vpn-57-41.rdu2.redhat.com [10.10.57.41]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAFGrn6X022267 for ; Sun, 15 Nov 2015 11:53:49 -0500 X-Mozilla-News-Host: news://news.gmane.org:119 To: gdb-patches@sourceware.org From: Stan Cox Subject: [PATCH] consolidate gdbserver global data Message-ID: <5648B89D.3050305@redhat.com> Date: Sun, 15 Nov 2015 11:53:49 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 This patch consolidates global data into two structures. Data that is related to the client is defined in the client_status structure. Data that is related to the inferior running under gdbserver is defined in the server_status structure. This delineation is to allow, as a future expansion, the ability to have multiple clients, for example gdb and strace, connected to the same inferior. To maintain source compatibility, macros are defined so that global variable references do not have to be changed to be structure member references. To accommodate this a few variable names that conflicted were changed. Currently set_client_state sets up a single client state and get_client_state returns it. Going forward this infrastructure can be expanded so that multiple clients can be supported. gdb/gdbserver/Changelog * gdb/nat/linux-personality.h (maybe_disable_address_space_randomization): disable_randomization conflicts with client_state macro name below. gdb/gdbserver/Changelog * server.h (struct server_state, struct client_state): New. Move global data items here and remove the extern declarations. Add defines for struct members for source compatibility. (struct client_states) New. Head of client_state list. * server.c (cont_thread, server_waiting, extended_protocol) (response_needed, exit_requested, run_once, multi_process) (report_fork_events, report_vfork_events, report_exec_events) (non_stop, swbreak_feature, hwbreak_feature, vCont_supported) (disable_randomization, program_argv, wrapper_argv, pass_signals) (program_signals, signal_pid, disable_packet_vCont) (disable_packet_Tthread, disable_packet_qC) (disable_packet_qfThreadInfo, last_status, last_ptid, own_buf) (mem_buf): Moved to struct client_status, struct server_status (set_client_state): Set client_states, the head of the struct client_state list. (get_client_state): Return the current client_state. (handle_qxfer_btrace, resume): Global own_buf now own_buffer Global last_status now last_waitstatus. (Change all references) (captured_main): Move initialization to set_client_state. * (remote-utils.c, remote-utils.h) Make get_remote_desc available for grabbing a client's file descriptor. * linux-low.c: Global last_status now last_waitstatus. (Change all) * inferiors.h (all_processes, all_threads, current_thread) Move to client_status * gdbthread.h (last_status): Now known as last_waitstatus. diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h index d6959f4..004c334 100644 --- a/gdb/gdbserver/gdbthread.h +++ b/gdb/gdbserver/gdbthread.h @@ -37,7 +37,7 @@ struct thread_info enum resume_kind last_resume_kind; /* The last wait status reported for this thread. */ - struct target_waitstatus last_status; + struct target_waitstatus last_waitstatus; /* True if LAST_STATUS hasn't been reported to GDB yet. */ int status_pending_p; diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c index 72a3ef1..ab80a96 100644 --- a/gdb/gdbserver/inferiors.c +++ b/gdb/gdbserver/inferiors.c @@ -22,10 +22,6 @@ #include "gdbthread.h" #include "dll.h" -struct inferior_list all_processes; -struct inferior_list all_threads; - -struct thread_info *current_thread; #define get_thread(inf) ((struct thread_info *)(inf)) @@ -109,7 +105,7 @@ add_thread (ptid_t thread_id, void *target_data) new_thread->entry.id = thread_id; new_thread->last_resume_kind = resume_continue; - new_thread->last_status.kind = TARGET_WAITKIND_IGNORE; + new_thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE; add_inferior_to_list (&all_threads, &new_thread->entry); diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h index d722616..d457a35 100644 --- a/gdb/gdbserver/inferiors.h +++ b/gdb/gdbserver/inferiors.h @@ -84,8 +84,6 @@ struct process_info struct process_info *current_process (void); struct process_info *get_thread_process (struct thread_info *); -extern struct inferior_list all_processes; - void add_inferior_to_list (struct inferior_list *list, struct inferior_list_entry *new_inferior); void for_each_inferior (struct inferior_list *list, @@ -122,7 +120,6 @@ int one_inferior_p (struct inferior_list *list); #define ALL_PROCESSES(cur, tmp) \ ALL_INFERIORS_TYPE (struct process_info, &all_processes, cur, tmp) -extern struct thread_info *current_thread; void remove_inferior (struct inferior_list *list, struct inferior_list_entry *entry); diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 41ab510..b4724a0 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -506,7 +506,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) child_lwp->status_pending_p = 0; child_thr = get_lwp_thread (child_lwp); child_thr->last_resume_kind = resume_stop; - child_thr->last_status.kind = TARGET_WAITKIND_STOPPED; + child_thr->last_waitstatus.kind = TARGET_WAITKIND_STOPPED; /* If we're suspending all threads, leave this one suspended too. */ @@ -626,7 +626,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) event_lwp->status_pending_p = 1; event_lwp->status_pending = wstat; event_thr->last_resume_kind = resume_continue; - event_thr->last_status.kind = TARGET_WAITKIND_IGNORE; + event_thr->last_waitstatus.kind = TARGET_WAITKIND_IGNORE; /* Report the event. */ *orig_event_lwp = event_lwp; @@ -1272,13 +1272,13 @@ get_detach_signal (struct thread_info *thread) /* If the thread had been suspended by gdbserver, and it stopped cleanly, then it'll have stopped with SIGSTOP. But we don't want to deliver that SIGSTOP. */ - if (thread->last_status.kind != TARGET_WAITKIND_STOPPED - || thread->last_status.value.sig == GDB_SIGNAL_0) + if (thread->last_waitstatus.kind != TARGET_WAITKIND_STOPPED + || thread->last_waitstatus.value.sig == GDB_SIGNAL_0) return 0; /* Otherwise, we may need to deliver the signal we intercepted. */ - status = lp->last_status; + status = lp->last_waitstatus; } if (!WIFSTOPPED (status)) @@ -1489,7 +1489,7 @@ thread_still_has_status_pending_p (struct thread_info *thread) /* If we got a `vCont;t', but we haven't reported a stop yet, do report any status pending the LWP may have. */ if (thread->last_resume_kind == resume_stop - && thread->last_status.kind != TARGET_WAITKIND_IGNORE) + && thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE) return 0; if (thread->last_resume_kind != resume_stop @@ -1500,7 +1500,7 @@ thread_still_has_status_pending_p (struct thread_info *thread) CORE_ADDR pc; int discard = 0; - gdb_assert (lp->last_status != 0); + gdb_assert (lp->last_waitstatus != 0); pc = get_pc (lp); @@ -2218,7 +2218,7 @@ linux_low_filter_event (int lwpid, int wstat) child->stopped = 1; - child->last_status = wstat; + child->last_waitstatus = wstat; /* Check if the thread has exited. */ if ((WIFEXITED (wstat) || WIFSIGNALED (wstat))) @@ -2379,7 +2379,7 @@ resume_stopped_resumed_lwps (struct inferior_list_entry *entry) && !lp->suspended && !lp->status_pending_p && thread->last_resume_kind != resume_stop - && thread->last_status.kind == TARGET_WAITKIND_IGNORE) + && thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE) { int step = thread->last_resume_kind == resume_step; @@ -2628,7 +2628,7 @@ count_events_callback (struct inferior_list_entry *entry, void *data) gdb_assert (count != NULL); /* Count only resumed LWPs that have an event pending. */ - if (thread->last_status.kind == TARGET_WAITKIND_IGNORE + if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE && lp->status_pending_p) (*count)++; @@ -2643,7 +2643,7 @@ select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data) struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lp = get_thread_lwp (thread); - if (thread->last_status.kind == TARGET_WAITKIND_IGNORE + if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE && thread->last_resume_kind == resume_step && lp->status_pending_p) return 1; @@ -2663,7 +2663,7 @@ select_event_lwp_callback (struct inferior_list_entry *entry, void *data) gdb_assert (selector != NULL); /* Select only resumed LWPs that have an event pending. */ - if (thread->last_status.kind == TARGET_WAITKIND_IGNORE + if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE && lp->status_pending_p) if ((*selector)-- == 0) return 1; @@ -4165,7 +4165,7 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg) { if (debug_threads) debug_printf ("already %s LWP %ld at GDB's request\n", - (thread->last_status.kind + (thread->last_waitstatus.kind == TARGET_WAITKIND_STOPPED) ? "stopped" : "stopping", @@ -4570,7 +4570,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) /* For stop requests, we're done. */ lwp->resume = NULL; - thread->last_status.kind = TARGET_WAITKIND_IGNORE; + thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE; return 0; } @@ -4611,8 +4611,8 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) make sure to queue its siginfo. We can ignore the return value of ptrace; if it fails, we'll skip PTRACE_SETSIGINFO. */ - if (WIFSTOPPED (lwp->last_status) - && WSTOPSIG (lwp->last_status) == lwp->resume->sig) + if (WIFSTOPPED (lwp->last_waitstatus) + && WSTOPSIG (lwp->last_waitstatus) == lwp->resume->sig) ptrace (PTRACE_GETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0, &p_sig->info); @@ -4620,7 +4620,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) } } - thread->last_status.kind = TARGET_WAITKIND_IGNORE; + thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE; lwp->resume = NULL; return 0; } @@ -4719,7 +4719,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) } if (thread->last_resume_kind == resume_stop - && thread->last_status.kind != TARGET_WAITKIND_IGNORE) + && thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE) { if (debug_threads) debug_printf (" client wants LWP to remain %ld stopped\n", @@ -5498,8 +5498,6 @@ linux_look_up_symbols (void) static void linux_request_interrupt (void) { - extern unsigned long signal_pid; - /* Send a SIGINT to the process group. This acts just like the user typed a ^C on the controlling terminal. */ kill (-signal_pid, SIGINT); diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index ccf4c94..1d87cd9 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -272,7 +272,7 @@ struct lwp_info int stopped; /* When stopped is set, the last wait status recorded for this lwp. */ - int last_status; + int last_waitstatus; /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for this LWP's last event, to pass to GDB without any further diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index e366091..41ee4b3 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -122,6 +122,19 @@ int transport_is_reliable = 0; # define write(fd, buf, len) send (fd, (char *) buf, len, 0) #endif + +int +get_remote_desc () +{ + return remote_desc; +} + +void +set_remote_desc (gdb_fildes_t fd) +{ + remote_desc = fd; +} + int gdb_connected (void) { @@ -860,13 +873,6 @@ initialize_async_io (void) unblock_async_io (); } -/* Internal buffer used by readchar. - These are global to readchar because reschedule_remote needs to be - able to tell whether the buffer is empty. */ - -static unsigned char readchar_buf[BUFSIZ]; -static int readchar_bufcnt = 0; -static unsigned char *readchar_bufp; /* Returns next char from remote GDB. -1 if error. */ @@ -1474,16 +1480,16 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb) while (own_buf[0] == 'm') { CORE_ADDR mem_addr; - unsigned char *mem_buf; + unsigned char *mem_buffer; unsigned int mem_len; decode_m_packet (&own_buf[1], &mem_addr, &mem_len); - mem_buf = (unsigned char *) xmalloc (mem_len); - if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0) - bin2hex (mem_buf, own_buf, mem_len); + mem_buffer = (unsigned char *) xmalloc (mem_len); + if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0) + bin2hex (mem_buffer, own_buf, mem_len); else write_enn (own_buf); - free (mem_buf); + free (mem_buffer); if (putpkt (own_buf) < 0) return -1; len = getpkt (own_buf); @@ -1556,36 +1562,36 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc) while (own_buf[0] == 'm' || own_buf[0] == 'M' || own_buf[0] == 'X') { CORE_ADDR mem_addr; - unsigned char *mem_buf = NULL; + unsigned char *mem_buffer = NULL; unsigned int mem_len; if (own_buf[0] == 'm') { decode_m_packet (&own_buf[1], &mem_addr, &mem_len); - mem_buf = (unsigned char *) xmalloc (mem_len); - if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0) - bin2hex (mem_buf, own_buf, mem_len); + mem_buffer = (unsigned char *) xmalloc (mem_len); + if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0) + bin2hex (mem_buffer, own_buf, mem_len); else write_enn (own_buf); } else if (own_buf[0] == 'X') { if (decode_X_packet (&own_buf[1], len - 1, &mem_addr, - &mem_len, &mem_buf) < 0 - || write_inferior_memory (mem_addr, mem_buf, mem_len) != 0) + &mem_len, &mem_buffer) < 0 + || write_inferior_memory (mem_addr, mem_buffer, mem_len) != 0) write_enn (own_buf); else write_ok (own_buf); } else { - decode_M_packet (&own_buf[1], &mem_addr, &mem_len, &mem_buf); - if (write_inferior_memory (mem_addr, mem_buf, mem_len) == 0) + decode_M_packet (&own_buf[1], &mem_addr, &mem_len, &mem_buffer); + if (write_inferior_memory (mem_addr, mem_buffer, mem_len) == 0) write_ok (own_buf); else write_enn (own_buf); } - free (mem_buf); + free (mem_buffer); if (putpkt (own_buf) < 0) return -1; len = getpkt (own_buf); diff --git a/gdb/gdbserver/remote-utils.h b/gdb/gdbserver/remote-utils.h index 5fc43f4..2a1c62f 100644 --- a/gdb/gdbserver/remote-utils.h +++ b/gdb/gdbserver/remote-utils.h @@ -23,6 +23,9 @@ extern int remote_debug; extern int noack_mode; extern int transport_is_reliable; +int get_remote_desc (void); +void set_remote_desc (gdb_fildes_t); + int gdb_connected (void); #define STDIO_CONNECTION_NAME "stdio" diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index fd2804b..e1fa1bc 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -36,55 +36,6 @@ #include "dll.h" #include "hostio.h" -/* The thread set with an `Hc' packet. `Hc' is deprecated in favor of - `vCont'. Note the multi-process extensions made `vCont' a - requirement, so `Hc pPID.TID' is pretty much undefined. So - CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for - resuming all threads of the process (again, `Hc' isn't used for - multi-process), or a specific thread ptid_t. */ -ptid_t cont_thread; - -/* The thread set with an `Hg' packet. */ -ptid_t general_thread; - -int server_waiting; - -int extended_protocol; -static int response_needed; -static int exit_requested; - -/* --once: Exit after the first connection has closed. */ -int run_once; - -int multi_process; -int report_fork_events; -int report_vfork_events; -int report_exec_events; -int non_stop; -int swbreak_feature; -int hwbreak_feature; - -/* True if the "vContSupported" feature is active. In that case, GDB - wants us to report whether single step is supported in the reply to - "vCont?" packet. */ -static int vCont_supported; - -/* Whether we should attempt to disable the operating system's address - space randomization feature before starting an inferior. */ -int disable_randomization = 1; - -static char **program_argv, **wrapper_argv; - -int pass_signals[GDB_SIGNAL_LAST]; -int program_signals[GDB_SIGNAL_LAST]; -int program_signals_p; - -/* The PID of the originally created or attached inferior. Used to - send signals to the process when GDB sends us an asynchronous interrupt - (user hitting Control-C in the client), and to wait for the child to exit - when no longer debugging it. */ - -unsigned long signal_pid; #ifdef SIGTTOU /* A file descriptor for the controlling terminal. */ @@ -102,21 +53,6 @@ restore_old_foreground_pgrp (void) } #endif -/* Set if you want to disable optional thread related packets support - in gdbserver, for the sake of testing GDB against stubs that don't - support them. */ -int disable_packet_vCont; -int disable_packet_Tthread; -int disable_packet_qC; -int disable_packet_qfThreadInfo; - -/* Last status reported to GDB. */ -static struct target_waitstatus last_status; -static ptid_t last_ptid; - -static char *own_buf; -static unsigned char *mem_buf; - /* A sub-class of 'struct notif_event' for stop, holding information relative to a single stop reply. We keep a queue of these to push to GDB in non-stop mode. */ @@ -138,6 +74,35 @@ static struct btrace_config current_btrace_conf; DEFINE_QUEUE_P (notif_event_p); +static struct client_states client_states; + + +/* Add a new client state for FD or return if found */ + +client_state * +set_client_state (gdb_fildes_t fd) +{ + if (client_states.first == NULL) + { + client_states.first = XCNEW (client_state); + client_states.first->ss = XCNEW (server_state); + } + client_states.current_fd = fd; + client_states.current_cs = client_states.first; + own_buffer = (char *) xmalloc (PBUFSIZ + 1); + return client_states.first; +} + + +/* Return the current client state */ + +client_state * +get_client_state (void) +{ + return client_states.current_cs; +} + + /* Put a stop reply to the stop reply queue. */ static void @@ -273,7 +238,7 @@ start_inferior (char **argv) break; current_thread->last_resume_kind = resume_stop; - current_thread->last_status = last_status; + current_thread->last_waitstatus = last_status; } while (last_status.value.sig != GDB_SIGNAL_TRAP); } @@ -291,7 +256,7 @@ start_inferior (char **argv) && last_status.kind != TARGET_WAITKIND_SIGNALLED) { current_thread->last_resume_kind = resume_stop; - current_thread->last_status = last_status; + current_thread->last_waitstatus = last_status; } else mourn_inferior (find_process_pid (ptid_get_pid (last_ptid))); @@ -328,7 +293,7 @@ attach_inferior (int pid) last_status.value.sig = GDB_SIGNAL_TRAP; current_thread->last_resume_kind = resume_stop; - current_thread->last_status = last_status; + current_thread->last_waitstatus = last_status; } return 0; @@ -592,6 +557,7 @@ handle_general_set (char *own_buf) return; } + if (startswith (own_buf, "QProgramSignals:")) { int numsigs = (int) GDB_SIGNAL_LAST, i; @@ -1618,20 +1584,20 @@ handle_qxfer_btrace (const char *annex, if (ptid_equal (general_thread, null_ptid) || ptid_equal (general_thread, minus_one_ptid)) { - strcpy (own_buf, "E.Must select a single thread."); + strcpy (own_buffer, "E.Must select a single thread."); return -3; } thread = find_thread_ptid (general_thread); if (thread == NULL) { - strcpy (own_buf, "E.No such thread."); + strcpy (own_buffer, "E.No such thread."); return -3; } if (thread->btrace == NULL) { - strcpy (own_buf, "E.Btrace not enabled."); + strcpy (own_buffer, "E.Btrace not enabled."); return -3; } @@ -1643,7 +1609,7 @@ handle_qxfer_btrace (const char *annex, type = BTRACE_READ_DELTA; else { - strcpy (own_buf, "E.Bad annex."); + strcpy (own_buffer, "E.Bad annex."); return -3; } @@ -1654,7 +1620,7 @@ handle_qxfer_btrace (const char *annex, result = target_read_btrace (thread->btrace, &cache, type); if (result != 0) { - memcpy (own_buf, cache.buffer, cache.used_size); + memcpy (own_buffer, cache.buffer, cache.used_size); return -3; } } @@ -1692,20 +1658,20 @@ handle_qxfer_btrace_conf (const char *annex, if (ptid_equal (general_thread, null_ptid) || ptid_equal (general_thread, minus_one_ptid)) { - strcpy (own_buf, "E.Must select a single thread."); + strcpy (own_buffer, "E.Must select a single thread."); return -3; } thread = find_thread_ptid (general_thread); if (thread == NULL) { - strcpy (own_buf, "E.No such thread."); + strcpy (own_buffer, "E.No such thread."); return -3; } if (thread->btrace == NULL) { - strcpy (own_buf, "E.Btrace not enabled."); + strcpy (own_buffer, "E.Btrace not enabled."); return -3; } @@ -1716,7 +1682,7 @@ handle_qxfer_btrace_conf (const char *annex, result = target_read_btrace_conf (thread->btrace, &cache); if (result != 0) { - memcpy (own_buf, cache.buffer, cache.used_size); + memcpy (own_buffer, cache.buffer, cache.used_size); return -3; } } @@ -2499,9 +2465,9 @@ handle_pending_status (const struct thread_resume *resumption, { thread->status_pending_p = 0; - last_status = thread->last_status; + last_status = thread->last_waitstatus; last_ptid = thread->entry.id; - prepare_resume_reply (own_buf, last_ptid, &last_status); + prepare_resume_reply (own_buffer, last_ptid, &last_status); return 1; } return 0; @@ -2640,7 +2606,7 @@ resume (struct thread_resume *actions, size_t num_actions) (*the_target->resume) (actions, num_actions); if (non_stop) - write_ok (own_buf); + write_ok (own_buffer); else { last_ptid = mywait (minus_one_ptid, &last_status, 0, 1); @@ -2649,7 +2615,7 @@ resume (struct thread_resume *actions, size_t num_actions) { /* No proper RSP support for this yet. At least return error. */ - sprintf (own_buf, "E.No unwaited-for children left."); + sprintf (own_buffer, "E.No unwaited-for children left."); disable_async_io (); return; } @@ -2657,14 +2623,14 @@ resume (struct thread_resume *actions, size_t num_actions) if (last_status.kind != TARGET_WAITKIND_EXITED && last_status.kind != TARGET_WAITKIND_SIGNALLED && last_status.kind != TARGET_WAITKIND_NO_RESUMED) - current_thread->last_status = last_status; + current_thread->last_waitstatus = last_status; /* From the client's perspective, all-stop mode always stops all threads implicitly (and the target backend has already done so by now). Tag all threads as "want-stopped", so we don't resume them implicitly without the client telling us to. */ gdb_wants_all_threads_stopped (); - prepare_resume_reply (own_buf, last_ptid, &last_status); + prepare_resume_reply (own_buffer, last_ptid, &last_status); disable_async_io (); if (last_status.kind == TARGET_WAITKIND_EXITED @@ -2957,7 +2923,7 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg) struct vstop_notif *new_notif = XNEW (struct vstop_notif); new_notif->ptid = entry->id; - new_notif->status = thread->last_status; + new_notif->status = thread->last_waitstatus; /* Pass the last stop reply back to GDB, but don't notify yet. */ notif_event_enque (¬if_stop, @@ -2970,7 +2936,7 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg) if (debug_threads) { char *status_string - = target_waitstatus_to_string (&thread->last_status); + = target_waitstatus_to_string (&thread->last_waitstatus); debug_printf ("Reporting thread %s as already stopped with %s\n", target_pid_to_str (entry->id), @@ -2979,11 +2945,11 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg) xfree (status_string); } - gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE); + gdb_assert (thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE); /* Pass the last stop reply back to GDB, but don't notify yet. */ - queue_stop_reply (entry->id, &thread->last_status); + queue_stop_reply (entry->id, &thread->last_waitstatus); } } @@ -3001,12 +2967,12 @@ gdb_wants_thread_stopped (struct inferior_list_entry *entry) thread->last_resume_kind = resume_stop; - if (thread->last_status.kind == TARGET_WAITKIND_IGNORE) + if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE) { /* Most threads are stopped implicitly (all-stop); tag that with signal 0. */ - thread->last_status.kind = TARGET_WAITKIND_STOPPED; - thread->last_status.value.sig = GDB_SIGNAL_0; + thread->last_waitstatus.kind = TARGET_WAITKIND_STOPPED; + thread->last_waitstatus.value.sig = GDB_SIGNAL_0; } } @@ -3047,15 +3013,15 @@ set_pending_status_callback (struct inferior_list_entry *entry) { struct thread_info *thread = (struct thread_info *) entry; - if (thread->last_status.kind != TARGET_WAITKIND_STOPPED - || (thread->last_status.value.sig != GDB_SIGNAL_0 + if (thread->last_waitstatus.kind != TARGET_WAITKIND_STOPPED + || (thread->last_waitstatus.value.sig != GDB_SIGNAL_0 /* A breakpoint, watchpoint or finished step from a previous GDB run isn't considered interesting for a new GDB run. If we left those pending, the new GDB could consider them random SIGTRAPs. This leaves out real async traps. We'd have to peek into the (target-specific) siginfo to distinguish those. */ - && thread->last_status.value.sig != GDB_SIGNAL_TRAP)) + && thread->last_waitstatus.value.sig != GDB_SIGNAL_TRAP)) thread->status_pending_p = 1; } @@ -3138,8 +3104,8 @@ handle_status (char *own_buf) general_thread = thread->id; set_desired_thread (1); - gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE); - prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status); + gdb_assert (tp->last_waitstatus.kind != TARGET_WAITKIND_IGNORE); + prepare_resume_reply (own_buf, tp->entry.id, &tp->last_waitstatus); } else strcpy (own_buf, "W00"); @@ -3366,6 +3332,11 @@ captured_main (int argc, char *argv[]) volatile int multi_mode = 0; volatile int attach = 0; int was_running; + int run_once_arg = 0; + int disable_randomization_arg = 1; + + int remote_desc = get_remote_desc(); + set_client_state (remote_desc); while (*next_arg != NULL && **next_arg == '-') { @@ -3462,11 +3433,11 @@ captured_main (int argc, char *argv[]) break; } else if (strcmp (*next_arg, "--disable-randomization") == 0) - disable_randomization = 1; + disable_randomization_arg = 1; else if (strcmp (*next_arg, "--no-disable-randomization") == 0) - disable_randomization = 0; + disable_randomization_arg = 0; else if (strcmp (*next_arg, "--once") == 0) - run_once = 1; + run_once_arg = 1; else { fprintf (stderr, "Unknown argument: %s\n", *next_arg); @@ -3477,6 +3448,10 @@ captured_main (int argc, char *argv[]) continue; } + run_once = run_once_arg; + disable_randomization = disable_randomization_arg; + program_argv = NULL; + port = *next_arg; next_arg++; if (port == NULL || (!attach && !multi_mode && *next_arg == NULL)) @@ -3527,7 +3502,6 @@ captured_main (int argc, char *argv[]) initialize_tracepoint (); initialize_notif (); - own_buf = (char *) xmalloc (PBUFSIZ + 1); mem_buf = (unsigned char *) xmalloc (PBUFSIZ); if (pid == 0 && *next_arg != NULL) @@ -3580,10 +3554,6 @@ captured_main (int argc, char *argv[]) { noack_mode = 0; - multi_process = 0; - report_fork_events = 0; - report_vfork_events = 0; - report_exec_events = 0; /* Be sure we're out of tfind mode. */ current_traceframe = -1; cont_thread = null_ptid; @@ -3653,8 +3623,8 @@ captured_main (int argc, char *argv[]) if (response_needed) { - write_enn (own_buf); - putpkt (own_buf); + write_enn (own_buffer); + putpkt (own_buffer); } if (run_once) @@ -3779,7 +3749,7 @@ process_serial_event (void) disable_async_io (); response_needed = 0; - packet_len = getpkt (own_buf); + packet_len = getpkt (own_buffer); if (packet_len <= 0) { remote_close (); @@ -3789,22 +3759,22 @@ process_serial_event (void) response_needed = 1; i = 0; - ch = own_buf[i++]; + ch = own_buffer[i++]; switch (ch) { case 'q': - handle_query (own_buf, packet_len, &new_packet_len); + handle_query (own_buffer, packet_len, &new_packet_len); break; case 'Q': - handle_general_set (own_buf); + handle_general_set (own_buffer); break; case 'D': - require_running (own_buf); + require_running (own_buffer); if (multi_process) { i++; /* skip ';' */ - pid = strtol (&own_buf[i], NULL, 16); + pid = strtol (&own_buffer[i], NULL, 16); } else pid = ptid_get_pid (current_ptid); @@ -3816,7 +3786,7 @@ process_serial_event (void) if (process == NULL) { - write_enn (own_buf); + write_enn (own_buffer); break; } @@ -3852,18 +3822,18 @@ process_serial_event (void) resume_info.sig = 0; (*the_target->resume) (&resume_info, 1); - write_ok (own_buf); + write_ok (own_buffer); break; /* from switch/case */ } fprintf (stderr, "Detaching from process %d\n", pid); stop_tracing (); if (detach_inferior (pid) != 0) - write_enn (own_buf); + write_enn (own_buffer); else { discard_queued_stop_replies (pid_to_ptid (pid)); - write_ok (own_buf); + write_ok (own_buffer); if (extended_protocol) { @@ -3876,7 +3846,7 @@ process_serial_event (void) } else { - putpkt (own_buf); + putpkt (own_buffer); remote_close (); /* If we are attached, then we can exit. Otherwise, we @@ -3889,20 +3859,20 @@ process_serial_event (void) break; case '!': extended_protocol = 1; - write_ok (own_buf); + write_ok (own_buffer); break; case '?': - handle_status (own_buf); + handle_status (own_buffer); break; case 'H': - if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') + if (own_buffer[1] == 'c' || own_buffer[1] == 'g' || own_buffer[1] == 's') { ptid_t gdb_id, thread_id; int pid; - require_running (own_buf); + require_running (own_buffer); - gdb_id = read_ptid (&own_buf[2], NULL); + gdb_id = read_ptid (&own_buffer[2], NULL); pid = ptid_get_pid (gdb_id); @@ -3919,7 +3889,7 @@ process_serial_event (void) &pid); if (!thread) { - write_enn (own_buf); + write_enn (own_buffer); break; } @@ -3930,12 +3900,12 @@ process_serial_event (void) thread_id = gdb_id_to_thread_id (gdb_id); if (ptid_equal (thread_id, null_ptid)) { - write_enn (own_buf); + write_enn (own_buffer); break; } } - if (own_buf[1] == 'g') + if (own_buffer[1] == 'g') { if (ptid_equal (thread_id, null_ptid)) { @@ -3954,20 +3924,20 @@ process_serial_event (void) set_desired_thread (1); gdb_assert (current_thread != NULL); } - else if (own_buf[1] == 'c') + else if (own_buffer[1] == 'c') cont_thread = thread_id; - write_ok (own_buf); + write_ok (own_buffer); } else { /* Silently ignore it so that gdb can extend the protocol without compatibility headaches. */ - own_buf[0] = '\0'; + own_buffer[0] = '\0'; } break; case 'g': - require_running (own_buf); + require_running (own_buffer); if (current_traceframe >= 0) { struct regcache *regcache @@ -3975,9 +3945,9 @@ process_serial_event (void) if (fetch_traceframe_registers (current_traceframe, regcache, -1) == 0) - registers_to_string (regcache, own_buf); + registers_to_string (regcache, own_buffer); else - write_enn (own_buf); + write_enn (own_buffer); free_register_cache (regcache); } else @@ -3985,85 +3955,85 @@ process_serial_event (void) struct regcache *regcache; if (!set_desired_thread (1)) - write_enn (own_buf); + write_enn (own_buffer); else { regcache = get_thread_regcache (current_thread, 1); - registers_to_string (regcache, own_buf); + registers_to_string (regcache, own_buffer); } } break; case 'G': - require_running (own_buf); + require_running (own_buffer); if (current_traceframe >= 0) - write_enn (own_buf); + write_enn (own_buffer); else { struct regcache *regcache; if (!set_desired_thread (1)) - write_enn (own_buf); + write_enn (own_buffer); else { regcache = get_thread_regcache (current_thread, 1); - registers_from_string (regcache, &own_buf[1]); - write_ok (own_buf); + registers_from_string (regcache, &own_buffer[1]); + write_ok (own_buffer); } } break; case 'm': - require_running (own_buf); - decode_m_packet (&own_buf[1], &mem_addr, &len); + require_running (own_buffer); + decode_m_packet (&own_buffer[1], &mem_addr, &len); res = gdb_read_memory (mem_addr, mem_buf, len); if (res < 0) - write_enn (own_buf); + write_enn (own_buffer); else - bin2hex (mem_buf, own_buf, res); + bin2hex (mem_buf, own_buffer, res); break; case 'M': - require_running (own_buf); - decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf); + require_running (own_buffer); + decode_M_packet (&own_buffer[1], &mem_addr, &len, &mem_buf); if (gdb_write_memory (mem_addr, mem_buf, len) == 0) - write_ok (own_buf); + write_ok (own_buffer); else - write_enn (own_buf); + write_enn (own_buffer); break; case 'X': - require_running (own_buf); - if (decode_X_packet (&own_buf[1], packet_len - 1, + require_running (own_buffer); + if (decode_X_packet (&own_buffer[1], packet_len - 1, &mem_addr, &len, &mem_buf) < 0 || gdb_write_memory (mem_addr, mem_buf, len) != 0) - write_enn (own_buf); + write_enn (own_buffer); else - write_ok (own_buf); + write_ok (own_buffer); break; case 'C': - require_running (own_buf); - hex2bin (own_buf + 1, &sig, 1); + require_running (own_buffer); + hex2bin (own_buffer + 1, &sig, 1); if (gdb_signal_to_host_p ((enum gdb_signal) sig)) signal = gdb_signal_to_host ((enum gdb_signal) sig); else signal = 0; - myresume (own_buf, 0, signal); + myresume (own_buffer, 0, signal); break; case 'S': - require_running (own_buf); - hex2bin (own_buf + 1, &sig, 1); + require_running (own_buffer); + hex2bin (own_buffer + 1, &sig, 1); if (gdb_signal_to_host_p ((enum gdb_signal) sig)) signal = gdb_signal_to_host ((enum gdb_signal) sig); else signal = 0; - myresume (own_buf, 1, signal); + myresume (own_buffer, 1, signal); break; case 'c': - require_running (own_buf); + require_running (own_buffer); signal = 0; - myresume (own_buf, 0, signal); + myresume (own_buffer, 0, signal); break; case 's': - require_running (own_buf); + require_running (own_buffer); signal = 0; - myresume (own_buf, 1, signal); + myresume (own_buffer, 1, signal); break; case 'Z': /* insert_ ... */ /* Fallthrough. */ @@ -4072,10 +4042,10 @@ process_serial_event (void) char *dataptr; ULONGEST addr; int kind; - char type = own_buf[1]; + char type = own_buffer[1]; int res; const int insert = ch == 'Z'; - char *p = &own_buf[3]; + char *p = &own_buffer[3]; p = unpack_varlen_hex (p, &addr); kind = strtol (p + 1, &dataptr, 16); @@ -4102,12 +4072,12 @@ process_serial_event (void) res = delete_gdb_breakpoint (type, addr, kind); if (res == 0) - write_ok (own_buf); + write_ok (own_buffer); else if (res == 1) /* Unsupported. */ - own_buf[0] = '\0'; + own_buffer[0] = '\0'; else - write_enn (own_buf); + write_enn (own_buffer); break; } case 'k': @@ -4135,20 +4105,20 @@ process_serial_event (void) { ptid_t gdb_id, thread_id; - require_running (own_buf); + require_running (own_buffer); - gdb_id = read_ptid (&own_buf[1], NULL); + gdb_id = read_ptid (&own_buffer[1], NULL); thread_id = gdb_id_to_thread_id (gdb_id); if (ptid_equal (thread_id, null_ptid)) { - write_enn (own_buf); + write_enn (own_buffer); break; } if (mythread_alive (thread_id)) - write_ok (own_buf); + write_ok (own_buffer); else - write_enn (own_buf); + write_enn (own_buffer); } break; case 'R': @@ -4191,26 +4161,26 @@ process_serial_event (void) /* It is a request we don't understand. Respond with an empty packet so that gdb knows that we don't support this request. */ - own_buf[0] = '\0'; + own_buffer[0] = '\0'; break; } case 'v': /* Extended (long) request. */ - handle_v_requests (own_buf, packet_len, &new_packet_len); + handle_v_requests (own_buffer, packet_len, &new_packet_len); break; default: /* It is a request we don't understand. Respond with an empty packet so that gdb knows that we don't support this request. */ - own_buf[0] = '\0'; + own_buffer[0] = '\0'; break; } if (new_packet_len != -1) - putpkt_binary (own_buf, new_packet_len); + putpkt_binary (own_buffer, new_packet_len); else - putpkt (own_buf); + putpkt (own_buffer); response_needed = 0; @@ -4287,7 +4257,7 @@ handle_target_event (int err, gdb_client_data client_data) "want-stopped" state to what the client wants, until it gets a new resume action. */ current_thread->last_resume_kind = resume_stop; - current_thread->last_status = last_status; + current_thread->last_waitstatus = last_status; } if (forward_event) diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 96ad4fa..d634ff8 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -67,42 +67,6 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap); void initialize_low (); -/* Public variables in server.c */ - -extern ptid_t cont_thread; -extern ptid_t general_thread; - -extern int server_waiting; -extern int pass_signals[]; -extern int program_signals[]; -extern int program_signals_p; - -extern int disable_packet_vCont; -extern int disable_packet_Tthread; -extern int disable_packet_qC; -extern int disable_packet_qfThreadInfo; - -extern int run_once; -extern int multi_process; -extern int report_fork_events; -extern int report_vfork_events; -extern int report_exec_events; -extern int non_stop; -extern int extended_protocol; - -/* True if the "swbreak+" feature is active. In that case, GDB wants - us to report whether a trap is explained by a software breakpoint - and for the server to handle PC adjustment if necessary on this - target. Only enabled if the target supports it. */ -extern int swbreak_feature; - -/* True if the "hwbreak+" feature is active. In that case, GDB wants - us to report whether a trap is explained by a hardware breakpoint. - Only enabled if the target supports it. */ -extern int hwbreak_feature; - -extern int disable_randomization; - #if USE_WIN32API #include typedef SOCKET gdb_fildes_t; @@ -134,3 +98,143 @@ extern void discard_queued_stop_replies (ptid_t ptid); #define PBUFSIZ 16384 #endif /* SERVER_H */ + +/* Description of the remote protocol state for the currently + connected target. This is per-target state, and independent of the + selected architecture. */ + +struct server_state +{ + /* From server.c */ + /* The thread set with an `Hc' packet. `Hc' is deprecated in favor of + `vCont'. Note the multi-process extensions made `vCont' a + requirement, so `Hc pPID.TID' is pretty much undefined. So + CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for + resuming all threads of the process (again, `Hc' isn't used for + multi-process), or a specific thread ptid_t. */ + ptid_t cont_thread_; + /* The thread set with an `Hg' packet. */ + ptid_t general_thread_; + /* The PID of the originally created or attached inferior. Used to + send signals to the process when GDB sends us an asynchronous interrupt + (user hitting Control-C in the client), and to wait for the child to exit + when no longer debugging it. */ + + unsigned long signal_pid_; + /* Last status reported to GDB. */ + struct target_waitstatus last_status_; + ptid_t last_ptid_; + unsigned char *mem_buf_; + + /* from remote-utils.c */ + /* Internal buffer used by readchar. + These are global to readchar because reschedule_remote needs to be + able to tell whether the buffer is empty. */ + unsigned char readchar_buf_[BUFSIZ]; + int readchar_bufcnt_; + unsigned char *readchar_bufp_; + /* from inferiors.c */ + struct inferior_list all_processes_; + struct inferior_list all_threads_; + struct thread_info *current_thread_; +}; + +typedef struct server_state server_state; + +struct client_state +{ + /* From server.c */ + int server_waiting_; + + int extended_protocol_; + int response_needed_; + int exit_requested_; + + /* --once: Exit after the first connection has closed. */ + int run_once_; + + int multi_process_; + int report_fork_events_; + int report_vfork_events_; + int report_exec_events_; + int non_stop_; + /* True if the "swbreak+" feature is active. In that case, GDB wants + us to report whether a trap is explained by a software breakpoint + and for the server to handle PC adjustment if necessary on this + target. Only enabled if the target supports it. */ + int swbreak_feature_; + /* True if the "hwbreak+" feature is active. In that case, GDB wants + us to report whether a trap is explained by a hardware breakpoint. + Only enabled if the target supports it. */ + int hwbreak_feature_; + + /* True if the "vContSupported" feature is active. In that case, GDB + wants us to report whether single step is supported in the reply to + "vCont?" packet. */ + int vCont_supported_; + + /* Whether we should attempt to disable the operating system's address + space randomization feature before starting an inferior. */ + int disable_randomization_; + + int disable_packet_vCont_; + int disable_packet_Tthread_; + int disable_packet_qC_; + int disable_packet_qfThreadInfo_; + + char **program_argv_, **wrapper_argv_; + + int pass_signals_[GDB_SIGNAL_LAST]; + int program_signals_[GDB_SIGNAL_LAST]; + int program_signals_p_; + char *own_buffer_; + server_state *ss; +}; + +typedef struct client_state client_state; + +struct client_states +{ + client_state *first; + client_state *current_cs; + gdb_fildes_t current_fd; +}; + +client_state * get_client_state (); + +#define cont_thread (get_client_state()->ss->cont_thread_) +#define general_thread (get_client_state()->ss->general_thread_) +#define signal_pid (get_client_state()->ss->signal_pid_) +#define last_status (get_client_state()->ss->last_status_) +#define last_ptid (get_client_state()->ss->last_ptid_) +#define mem_buf (get_client_state()->ss->mem_buf_) +#define readchar_buf (get_client_state()->ss->readchar_buf_) +#define readchar_bufcnt (get_client_state()->ss->readchar_bufcnt_) +#define readchar_bufp (get_client_state()->ss->readchar_bufp_) +#define all_processes (get_client_state()->ss->all_processes_) +#define all_threads (get_client_state()->ss->all_threads_) +#define current_thread (get_client_state()->ss->current_thread_) +#define server_waiting (get_client_state()->server_waiting_) +#define extended_protocol (get_client_state()->extended_protocol_) +#define response_needed (get_client_state()->response_needed_) +#define exit_requested (get_client_state()->exit_requested_) +#define run_once (get_client_state()->run_once_) +#define multi_process (get_client_state()->multi_process_) +#define report_fork_events (get_client_state()->report_fork_events_) +#define report_vfork_events (get_client_state()->report_vfork_events_) +#define report_exec_events (get_client_state()->report_exec_events_) +#define non_stop (get_client_state()->non_stop_) +#define swbreak_feature (get_client_state()->swbreak_feature_) +#define hwbreak_feature (get_client_state()->hwbreak_feature_) +#define vCont_supported (get_client_state()->vCont_supported_) +#define disable_randomization (get_client_state()->disable_randomization_) +#define disable_packet_vCont (get_client_state()->disable_packet_vCont_) +#define disable_packet_Tthread (get_client_state()->disable_packet_Tthread_) +#define disable_packet_qC (get_client_state()->disable_packet_qC_) +#define disable_packet_qfThreadInfo (get_client_state()->disable_packet_qfThreadInfo_) +#define program_argv (get_client_state()->program_argv_) +#define wrapper_argv (get_client_state()->wrapper_argv_) +#define pass_signals (get_client_state()->pass_signals_) +#define program_signals (get_client_state()->program_signals_) +#define program_signals_p (get_client_state()->program_signals_p_) +#define own_buffer (get_client_state()->own_buffer_) diff --git a/gdb/nat/linux-personality.h b/gdb/nat/linux-personality.h index 009e614..5f7fa8b 100644 --- a/gdb/nat/linux-personality.h +++ b/gdb/nat/linux-personality.h @@ -26,6 +26,6 @@ re-enable the inferior's address space randomization. */ extern struct cleanup *maybe_disable_address_space_randomization - (int disable_randomization); + (int disable_randomization_p); #endif /* ! NAT_LINUX_PERSONALITY_H */