diff options
author | Pedro Alves <palves@redhat.com> | 2009-04-01 22:48:05 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2009-04-01 22:48:05 +0000 |
commit | bd99dc858385792aad304d42f4a47791fd8d3272 (patch) | |
tree | ee30ea92e8d9e1ddbfb5a2f5f2a26b0ed12364b6 /gdb/gdbserver/remote-utils.c | |
parent | 5b1c542ea1c4ff247db390bd24a9e0665d0c2e48 (diff) | |
download | gdb-bd99dc858385792aad304d42f4a47791fd8d3272.zip gdb-bd99dc858385792aad304d42f4a47791fd8d3272.tar.gz gdb-bd99dc858385792aad304d42f4a47791fd8d3272.tar.bz2 |
Non-stop mode support.
* server.h (non_stop): Declare.
(gdb_client_data, handler_func): Declare.
(delete_file_handler, add_file_handler, start_event_loop):
Declare.
(handle_serial_event, handle_target_event, push_event)
(putpkt_notif): Declare.
* target.h (enum resume_kind): New.
(struct thread_resume): Replace `step' field by `kind' field.
(TARGET_WNOHANG): Define.
(struct target_ops) <wait>: Add `options' argument.
<supports_non_stop, async, start_non_stop>: New fields.
(target_supports_non_stop, target_async): New.
(start_non_stop): Declare.
(mywait): Add `options' argument.
* target.c (mywait): Add `options' argument. Print child exit
notifications here.
(start_non_stop): New.
* server.c (non_stop, own_buf, mem_buf): New globals.
(struct vstop_notif): New.
(notif_queue): New global.
(queue_stop_reply, push_event, discard_queued_stop_replies)
(send_next_stop_reply): New.
(start_inferior): Adjust to use resume_kind. Adjust to mywait
interface changes.
(attach_inferior): In non-stop mode, don't wait for the target
here.
(handle_general_set): Handle QNonStop.
(handle_query): When handling qC, return the current general
thread, instead of the first thread of the list.
(handle_query): If the backend supports non-stop mode, include
QNonStop+ in the qSupported query response.
(handle_v_cont): Adjust to use resume_kind. Handle resume_stop
and non-stop mode.
(handle_v_attach, handle_v_run): Handle non-stop mode.
(handle_v_stopped): New.
(handle_v_requests): Report support for vCont;t. Handle vStopped.
(myresume): Adjust to use resume_kind. Handle non-stop.
(queue_stop_reply_callback): New.
(handle_status): Handle non-stop mode.
(main): Clear non_stop flag on reconnection. Use the event-loop.
Refactor serial protocol handling from here ...
(process_serial_event): ... to this new function. When GDB
selects any thread, select one here. In non-stop mode, wait until
GDB acks all pending events before exiting.
(handle_serial_event, handle_target_event): New.
* remote-utils.c (remote_open): Install remote_desc in the event
loop.
(remote_close): Remove remote_desc from the event loop.
(putpkt_binary): Rename to...
(putpkt_binary_1): ... this. Add `is_notic' argument. Handle it.
(putpkt_binary): New as wrapper around putpkt_binary_1.
(putpkt_notif): New.
(prepare_resume_reply): In non-stop mode, don't change the
general_thread.
* event-loop.c: New.
* Makefile.in (OBJ): Add event-loop.o.
(event-loop.o): New rule.
* linux-low.h (pid_of): Moved here.
(lwpid_of): New.
(get_lwp_thread): Use lwpid_of.
(struct lwp_info): Delete `lwpid' field. Add `suspended' field.
* linux-low.c (pid_of): Delete.
(inferior_pid): Use lwpid_of.
(linux_event_pipe): New.
(target_is_async_p): New.
(delete_lwp): New.
(handle_extended_wait): Use lwpid_of.
(add_lwp): Don't set lwpid field.
(linux_attach_lwp): Adjust debug output. Use lwpid_of.
(linux_kill_one_lwp): If killing a running lwp, stop it first.
Use lwpid_of. Adjust to linux_wait_for_event interface changes.
(linux_detach_one_lwp): If detaching from a running lwp, stop it
first. Adjust to linux_wait_for_event interface changes. Use
lwpid_of.
(linux_detach): Don't delete the main lwp here.
(linux_join): Use my_waitpid. Avoid signal_pid. Use lwpid_of.
(status_pending_p): Don't consider explicitly suspended lwps.
(linux_wait_for_lwp): Take an integer pid instead of a lwp_info
pointer. Add OPTIONS argument. Change return type to int. Use
my_waitpid instead of sleeping. Handle WNOHANG. Use lwpid_of.
(linux_wait_for_event): Take an integer pid instead of a lwp_info
pointer. Add status pointer argument. Return a pid instead of a
status. Use lwpid_of. Adjust to linux_wait_for_lwp interface
changes. In non-stop mode, don't switch to a random thread.
(linux_wait): Rename to...
(linux_wait_1): ... this. Add target_options argument, and handle
it. Adjust to use resume_kind. Use lwpid_of. In non-stop mode,
don't handle the continue thread. Handle TARGET_WNOHANG. Merge
clean exit and signal exit code. Don't stop all threads in
non-stop mode. In all-stop mode, only stop all threads when
reporting a stop to GDB. Handle explicit thread stop requests.
(async_file_flush, async_file_mark): New.
(linux_wait): New.
(send_sigstop): Use lwpid_of.
(wait_for_sigstop): Use lwpid_of. Adjust to linux_wait_for_event
interface changes. In non-stop mode, don't switch to a random
thread.
(linux_resume_one_lwp): Use lwpid_of.
(linux_continue_one_thread, linux_queue_one_thread): Merge into ...
(linux_resume_one_thread): ... this. Handle resume_stop. In
non-stop mode, don't look for pending flag in all threads.
(resume_status_pending_p): Don't consider explicitly suspended
threads.
(my_waitpid): Reimplement. Emulate __WALL.
(linux_request_interrupt, linux_read_offsets, linux_xfer_siginfo):
Use lwpid_of.
(sigchld_handler, linux_supports_non_stop, linux_async)
(linux_start_non_stop): New.
(linux_target_ops): Register linux_supports_non_stop, linux_async
and linux_start_non_stop.
(initialize_low): Install SIGCHLD handler.
* thread-db.c (thread_db_create_event, find_one_thread)
(thread_db_get_tls_address): Use lwpid_of.
* win32-low.c (win32_detach): Adjust to use resume_kind.
(win32_wait): Add `options' argument.
* spu-low.c (spu_resume): Adjust to use resume_kind.
(spu_wait): Add `options' argument.
Diffstat (limited to 'gdb/gdbserver/remote-utils.c')
-rw-r--r-- | gdb/gdbserver/remote-utils.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index d0967e3..c506bf5 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -286,11 +286,16 @@ remote_open (char *name) fcntl (remote_desc, F_SETOWN, getpid ()); #endif #endif + + /* Register the event loop handler. */ + add_file_handler (remote_desc, handle_serial_event, NULL); } void remote_close (void) { + delete_file_handler (remote_desc); + #ifdef USE_WIN32API closesocket (remote_desc); #else @@ -522,8 +527,8 @@ try_rle (char *buf, int remaining, unsigned char *csum, char **p) The data of the packet is in BUF, and the length of the packet is in CNT. Returns >= 0 on success, -1 otherwise. */ -int -putpkt_binary (char *buf, int cnt) +static int +putpkt_binary_1 (char *buf, int cnt, int is_notif) { int i; unsigned char csum = 0; @@ -537,7 +542,10 @@ putpkt_binary (char *buf, int cnt) and giving it a checksum. */ p = buf2; - *p++ = '$'; + if (is_notif) + *p++ = '%'; + else + *p++ = '$'; for (i = 0; i < cnt;) i += try_rle (buf + i, cnt - i, &csum, &p); @@ -561,12 +569,15 @@ putpkt_binary (char *buf, int cnt) return -1; } - if (noack_mode) + if (noack_mode || is_notif) { /* Don't expect an ack then. */ if (remote_debug) { - fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2); + if (is_notif) + fprintf (stderr, "putpkt (\"%s\"); [notif]\n", buf2); + else + fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2); fflush (stderr); } break; @@ -605,6 +616,12 @@ putpkt_binary (char *buf, int cnt) return 1; /* Success! */ } +int +putpkt_binary (char *buf, int cnt) +{ + return putpkt_binary_1 (buf, cnt, 0); +} + /* Send a packet to the remote machine, with error checking. The data of the packet is in BUF, and the packet should be a NUL-terminated string. Returns >= 0 on success, -1 otherwise. */ @@ -615,6 +632,12 @@ putpkt (char *buf) return putpkt_binary (buf, strlen (buf)); } +int +putpkt_notif (char *buf) +{ + return putpkt_binary_1 (buf, strlen (buf), 1); +} + /* Come here when we get an input interrupt from the remote side. This interrupt should only be active while we are waiting for the child to do something. About the only thing that should come through is a ^C, which @@ -1000,7 +1023,10 @@ prepare_resume_reply (char *buf, unsigned long ptid, gdbserver to know what inferior_ptid is. */ if (1 || general_thread != ptid) { - general_thread = ptid; + /* In non-stop, don't change the general thread behind + GDB's back. */ + if (!non_stop) + general_thread = ptid; sprintf (buf, "thread:%lx;", ptid); buf += strlen (buf); } |