This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH v2 2/2] consolidate gdbserver global data
- From: Stan Cox <scox at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Pedro Alves <palves at redhat dot com>
- Date: Mon, 21 Dec 2015 12:03:54 -0500
- Subject: Re: [PATCH v2 2/2] consolidate gdbserver global data
- Authentication-results: sourceware.org; auth=none
- References: <5648B89D dot 3050305 at redhat dot com> <n34r5m$nis$1 at ger dot gmane dot org> <n4v8lf$dpr$1 at ger dot gmane dot org> <5677FF0D dot 3090501 at redhat dot com>
The thinking was that it would be like, not a perfect analogy, database
normalization. So, logically, there would be one server structure per
inferior that contains those items that are common to all remote clients
accessing that inferior. Each server would have one or more associated
client structures, one per remote client. So the server_state is,
roughly, the gdbserver view of things and the client_state is the remote
gdb view of things.
So at a high level
/ [client 1, fd 4]
[server for inferior 1]
\ [client 2, fd 9]
This is "inverted" in the current implementation model. So there is a
list of client structures that are "indexed" by the file descriptor
corresponding to the client. So in this example there is one server
state that has two client states. The file_desc is the client "key" and
finding a client_state involves searching the list of clients (via
client_state.next) for the client_state that matches that file_desc.
client_states.first
-> /* client 1 --- fd 4 */ struct client_state
file_desc = 4,
attached_to_client = 1,
packet_type = 0,
last_packet_type = 4,
/* enum packet_types { other_packet, vContc, vConts, vContt,
vStopped, vRun, vAttach }; */
pending = 0,
/* enum pending_types {none_pending, pending_waitee,
pending_cont_waiter,pending_step_waiter,pending_stop}; */
server_waiting_ = 0,
extended_protocol_ = 1,
response_needed_ = 0,
exit_requested_ = 0,
run_once_ = 0,
multi_process_ = 1,
report_fork_events_ = 1,
report_vfork_events_ = 1,
non_stop_ = 1,
swbreak_feature_ = 1,
hwbreak_feature_ = 1,
disable_randomization_ = 1,
program_argv_ = 0x683840,
wrapper_argv_ = 0x0,
packet_length_ = 17,
pass_signals_ = {0 <repeats 14 times>,
program_signals_ = {1,
program_signals_p_ = 1,
in_buffer_ = 0x6838a0 "z0,7ffff7df0f57,", <incomplete sequence \327>,
own_buffer_ = 0x6848e0 "OK",
client_breakpoints = 0x6836a0,
ss = 0x681430,
next = 0x688920
client_states.first.next
-> /* client 2 --- fd 9 */ struct client_state
...
ss = 0x681430,
next = 0
client_states.first.ss
-> /* server -- ss = 0x681430 */ struct server_state
attach_count_ = 2, /* number of clients for this server_state */
cont_thread_ = {...}
general_thread_ = {...}
signal_pid_ = 32251,
last_status_ = {
kind = TARGET_WAITKIND_NO_RESUMED,
value = {
integer = 5,
sig = GDB_SIGNAL_TRAP,
related_pid = {...}
...
last_status_exited = 0,
last_ptid_ = {...}
mem_buf_ = 0x67cc70 "..."
readchar_buf_ = "$z0,7ffff7df0f57,1#050"...,
readchar_bufcnt_ = 0,
readchar_bufp_ = 0x6814cd "0,fff#03b;"...,
all_processes_ = { head = 0x683a80, tail = 0x683a80 },
all_threads_ = { head = 0x683cb0, tail = 0x683cb0 },
current_thread_ = 0x683cb0
client_states.current_cs
-> /* there is always a "current" client_state
this points to the "current" client_state */
Example "queries"
1) What is client 1's in_buffer?
- Find client 1's fd in the client list
- client_state.in_buffer
2) What is client 2's last_status?
- Find Client 2's fd in the client list
- client_state.ss.last_status
3) What is the current client_state?
-client_states.current_cs
Thanks for looking Pedro. I'm wide open to any ways to improve this to
make it easier to understand and use.