summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
authorStella Stamenova <stilis@microsoft.com>2018-06-01 19:14:53 +0000
committerStella Stamenova <stilis@microsoft.com>2018-06-01 19:14:53 +0000
commit36d457c20d86a749e08ecee23eeb2bade5f2ab56 (patch)
tree15464da0474d863b74a85bf43e75e0ae67304492 /lldb
parent78a8494eb5bef6bb3ef20e2d581d79c20fbe678b (diff)
downloadbcm5719-llvm-36d457c20d86a749e08ecee23eeb2bade5f2ab56.tar.gz
bcm5719-llvm-36d457c20d86a749e08ecee23eeb2bade5f2ab56.zip
[lldb, process] Fix occasional hang when launching a process in LLDB
Summary: Occasionally, when launching a process in lldb (especially on windows, but not limited to), lldb will hang before the process is launched and it will never recover. This happens because the timing of the processing of the state changes can be slightly different. The state changes that are issued are: 1) SetPublicState(eStateLaunching) 2) SetPrivateState(eStateLaunching) 3) SetPublicState(eStateStopped) 4) SetPrivateState(eStateStopped) What we expect to see is: public state: launching -> launching -> stopped private state: launching -> stopped What we see is: public state: launching -> stopped -> launching private state: launching -> stopped The second launching change to the public state is issued when WaitForProcessStopPrivate calls HandlePrivateEvent on the event which was created when the private state was set to launching. HandlePrivateEvent has logic to determine whether to broadcase the event and a launching event is *always* broadcast. At the same time, when the stopped event is processed by WaitForProcessStopPrivate next, the function exists and that event is never broadcast, so the public state remains as launching. HandlePrivateEvent does two things: determine whether there's a next action as well as determine whether to broadcast the event that was processed. There's only ever a next action set if we are trying to attach to a process, but WaitForProcessStopPrivate is only ever called when we are launching a process or connecting remotely, so the first part of HandlePrivateEvent (handling the next action) is irrelevant for WaitForProcessStopPrivate. As far as broadcasting the event is concerned, since we are handling state changes that already occurred to the public state (and are now duplicated in the private state), I believe the broadcast step is unnecessary also (and in fact, it causes the hang). This change removes the call to HandlePrivateEvent from inside WaitForProcessStopPrivate. Incidentally, there was also a bug filed recently that is the same issue: https://bugs.llvm.org/show_bug.cgi?id=37496 Reviewers: asmith, labath, zturner, jingham Reviewed By: zturner, jingham Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D47609 llvm-svn: 333781
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/lldb-enumerations.h3
-rw-r--r--lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp1
-rw-r--r--lldb/source/Target/Process.cpp6
3 files changed, 7 insertions, 3 deletions
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 8cce1358a07..7bf6fdaecf2 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -44,6 +44,9 @@ enum StateType {
///launched or attached to anything yet
eStateAttaching, ///< Process is currently trying to attach
eStateLaunching, ///< Process is in the process of launching
+ // The state changes eStateAttaching and eStateLaunching are both sent while the
+ // private state thread is either not yet started or paused. For that reason, they
+ // should only be signaled as public state changes, and not private state changes.
eStateStopped, ///< Process or thread is stopped and can be examined.
eStateRunning, ///< Process or thread is running and can't be examined.
eStateStepping, ///< Process or thread is in the process of stepping and can
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 13b8a49ca6e..42b4effc709 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -249,7 +249,6 @@ Status ProcessWindows::DoLaunch(Module *exe_module,
bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
m_session_data.reset(new ProcessWindowsData(stop_at_entry));
- SetPrivateState(eStateLaunching);
DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
m_session_data->m_debugger.reset(new DebuggerThread(delegate));
DebuggerThreadSP debugger = m_session_data->m_debugger;
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 583a9200917..32ed39842e3 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2688,8 +2688,7 @@ StateType
Process::WaitForProcessStopPrivate(EventSP &event_sp,
const Timeout<std::micro> &timeout) {
StateType state;
- // Now wait for the process to launch and return control to us, and then call
- // DidLaunch:
+
while (true) {
event_sp.reset();
state = GetStateChangedEventsPrivate(event_sp, timeout);
@@ -2767,6 +2766,9 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) {
}
} else {
EventSP event_sp;
+
+ // Now wait for the process to launch and return control to us, and then call
+ // DidLaunch:
StateType state = WaitForProcessStopPrivate(event_sp, seconds(10));
if (state == eStateInvalid || !event_sp) {
OpenPOWER on IntegriCloud