diff options
author | jimingham <jingham@apple.com> | 2023-11-30 09:48:04 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-30 09:48:04 -0800 |
commit | d1bf1947e4e4f3ef75f2ba3ac9aa77dc38214de1 (patch) | |
tree | d443633500da7e90d4fb137e76aca8312a1a8ad4 /lldb/tools | |
parent | cb13e9286b6d4e384b5d4203e853d44e2eff0f0f (diff) | |
download | llvm-d1bf1947e4e4f3ef75f2ba3ac9aa77dc38214de1.zip llvm-d1bf1947e4e4f3ef75f2ba3ac9aa77dc38214de1.tar.gz llvm-d1bf1947e4e4f3ef75f2ba3ac9aa77dc38214de1.tar.bz2 |
Send an explicit interrupt to cancel an attach waitfor. (#72565)
Currently when you interrupt a:
(lldb) process attach -w -n some_process
lldb just closes the connection to the stub and kills the
lldb_private::Process it made for the attach. The stub at the other end
notices the connection go down and exits because of that. But when
communication to a device is handled through some kind of proxy server
which isn't as well behaved as one would wish, that signal might not be
reliable, causing debugserver to persist on the machine, waiting to
steal the next instance of that process.
We can work around those failures by sending an explicit interrupt
before closing down the connection. The stub will also have to be
waiting for the interrupt for this to make any difference. I changed
debugserver to do that.
I didn't make the equivalent change in lldb-server. So long as you
aren't faced with a flakey connection, this should not be necessary.
Diffstat (limited to 'lldb/tools')
-rw-r--r-- | lldb/tools/debugserver/source/DNB.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index f6c1130..0ec50df 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -50,6 +50,7 @@ #include "MacOSX/MachProcess.h" #include "MacOSX/MachTask.h" #include "MacOSX/ThreadInfo.h" +#include "RNBRemote.h" typedef std::shared_ptr<MachProcess> MachProcessSP; typedef std::map<nub_process_t, MachProcessSP> ProcessMap; @@ -745,7 +746,6 @@ DNBProcessAttachWait(RNBContext *ctx, const char *waitfor_process_name, break; } } else { - // Get the current process list, and check for matches that // aren't in our original list. If anyone wants to attach // to an existing process by name, they should do it with @@ -799,7 +799,33 @@ DNBProcessAttachWait(RNBContext *ctx, const char *waitfor_process_name, break; } - ::usleep(waitfor_interval); // Sleep for WAITFOR_INTERVAL, then poll again + // Now we're going to wait a while before polling again. But we also + // need to check whether we've gotten an event from the debugger + // telling us to interrupt the wait. So we'll use the wait for a possible + // next event to also be our short pause... + struct timespec short_timeout; + DNBTimer::OffsetTimeOfDay(&short_timeout, 0, waitfor_interval); + uint32_t event_mask = RNBContext::event_read_packet_available + | RNBContext::event_read_thread_exiting; + nub_event_t set_events = ctx->Events().WaitForSetEvents(event_mask, + &short_timeout); + if (set_events & RNBContext::event_read_packet_available) { + // If we get any packet from the debugger while waiting on the async, + // it has to be telling us to interrupt. So always exit here. + // Over here in DNB land we can see that there was a packet, but all + // the methods to actually handle it are protected. It's not worth + // rearranging all that just to get which packet we were sent... + DNBLogError("Interrupted by packet while waiting for '%s' to appear.\n", + waitfor_process_name); + break; + } + if (set_events & RNBContext::event_read_thread_exiting) { + // The packet thread is shutting down, get out of here... + DNBLogError("Interrupted by packet thread shutdown while waiting for " + "%s to appear.\n", waitfor_process_name); + break; + } + } } |