aboutsummaryrefslogtreecommitdiff
path: root/lldb/tools
diff options
context:
space:
mode:
authorjimingham <jingham@apple.com>2023-11-30 09:48:04 -0800
committerGitHub <noreply@github.com>2023-11-30 09:48:04 -0800
commitd1bf1947e4e4f3ef75f2ba3ac9aa77dc38214de1 (patch)
treed443633500da7e90d4fb137e76aca8312a1a8ad4 /lldb/tools
parentcb13e9286b6d4e384b5d4203e853d44e2eff0f0f (diff)
downloadllvm-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.cpp30
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;
+ }
+
}
}