Fix Target::Launch in case of synchronous execution

Summary: This patch fixes Target::Launch in case of synchronous execution.

Test Plan:
# Create file with source commands:
```
$ cat start_script
target create ~/p/hello
process launch -s
continue
```

# Run lldb and execute "command source -c 0 -s 0 start_script":
```
$ bin/lldb
(lldb) command source -c 0 -s 0 start_script
Executing commands in '/Users/IliaK/p/llvm/build_ninja/start_script'.
(lldb) target create ~/p/hello
Current executable set to '~/p/hello' (x86_64).
(lldb) process launch -s
Process 92028 stopped
* thread #1: tid = 0x26731, 0x00007fff5fc01000 dyld`_dyld_start, stop reason = signal SIGSTOP
    frame #0: 0x00007fff5fc01000 dyld`_dyld_start
dyld`_dyld_start:
->  0x7fff5fc01000 <+0>: popq   %rdi
    0x7fff5fc01001 <+1>: pushq  $0x0
    0x7fff5fc01003 <+3>: movq   %rsp, %rbp
    0x7fff5fc01006 <+6>: andq   $-0x10, %rsp
(lldb) Process 92028 launched: '/Users/IliaK/p/hello' (x86_64)
(lldb) continue
'
` - it's \ni=1
j=2
x=3
y=4
argc: /Users/IliaK/p/hello
argc: (null)
Process 92028 resuming
Process 92028 exited with status = 0 (0x00000000)

(lldb)
```

was:
```
$ bin/lldb
(lldb) command source -c 0 -s 0 start_script
Executing commands in '/Users/IliaK/p/llvm/build_ninja/start_script'.
(lldb) target create ~/p/hello
Current executable set to '~/p/hello' (x86_64).
(lldb) process launch -s
Process 92100 launched: '/Users/IliaK/p/hello' (x86_64)
(lldb) continue
error: Process must be launched.
Process 92100 stopped
* thread #1: tid = 0x2699a, 0x00007fff5fc01000 dyld`_dyld_start, stop reason = signal SIGSTOP
    frame #0: 0x00007fff5fc01000 dyld`_dyld_start
dyld`_dyld_start:
->  0x7fff5fc01000 <+0>: popq   %rdi
    0x7fff5fc01001 <+1>: pushq  $0x0
    0x7fff5fc01003 <+3>: movq   %rsp, %rbp
    0x7fff5fc01006 <+6>: andq   $-0x10, %rsp
(lldb)
```

Reviewers: jingham, clayborg

Reviewed By: clayborg

Subscribers: labath, lldb-commits, clayborg, jingham

Differential Revision: http://reviews.llvm.org/D8541

llvm-svn: 233022
This commit is contained in:
Ilia K 2015-03-23 21:16:25 +00:00
parent 05a55de3ba
commit 064e69f2a9
1 changed files with 37 additions and 20 deletions

View File

@ -2591,41 +2591,58 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
if (error.Success())
{
if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
if (synchronous_execution || launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
{
EventSP event_sp;
ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false, hijack_listener_sp.get(), NULL);
StateType state = m_process_sp->WaitForProcessToStop (NULL, &event_sp, false, hijack_listener_sp.get(), NULL);
if (state == eStateStopped)
{
if (!synchronous_execution)
m_process_sp->RestoreProcessEvents ();
error = m_process_sp->PrivateResume();
if (error.Success())
if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
{
// there is a race condition where this thread will return up the call stack to the main command
// handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
// a chance to call PushProcessIOHandler()
m_process_sp->SyncIOHandler(2000);
if (!synchronous_execution)
m_process_sp->RestoreProcessEvents ();
if (synchronous_execution)
error = m_process_sp->PrivateResume();
if (error.Success())
{
state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get(), stream);
const bool must_be_alive = false; // eStateExited is ok, so this must be false
if (!StateIsStoppedState(state, must_be_alive))
// there is a race condition where this thread will return up the call stack to the main command
// handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
// a chance to call PushProcessIOHandler()
m_process_sp->SyncIOHandler(2000);
if (synchronous_execution)
{
error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get(), stream);
const bool must_be_alive = false; // eStateExited is ok, so this must be false
if (!StateIsStoppedState(state, must_be_alive))
{
error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
}
}
}
else
{
Error error2;
error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
error = error2;
}
}
else
{
Error error2;
error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
error = error2;
assert(synchronous_execution && launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == true);
// Target was stopped at entry as was intended. Need to notify the listeners about it.
m_process_sp->RestoreProcessEvents();
m_process_sp->HandlePrivateEvent(event_sp);
// there is a race condition where this thread will return up the call stack to the main command
// handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
// a chance to call PushProcessIOHandler()
m_process_sp->SyncIOHandler(2000);
}
}
else if (state == eStateExited)