Add the ability from the SB API's to set the "one thread" timeout

for expression evaluations that try one and then all threads.

<rdar://problem/15598528>

llvm-svn: 205060
This commit is contained in:
Jim Ingham 2014-03-28 21:58:28 +00:00
parent dca7c7c5f1
commit 914f4e7092
6 changed files with 86 additions and 10 deletions

View File

@ -56,9 +56,19 @@ public:
uint32_t
GetTimeoutInMicroSeconds () const;
// Set the timeout for the expression, 0 means wait forever.
void
SetTimeoutInMicroSeconds (uint32_t timeout = 0);
uint32_t
GetOneThreadTimeoutInMicroSeconds () const;
// Set the timeout for running on one thread, 0 means use the default behavior.
// If you set this higher than the overall timeout, you'll get an error when you
// try to run the expression.
void
SetOneThreadTimeoutInMicroSeconds (uint32_t timeout = 0);
bool
GetTryAllThreads () const;

View File

@ -203,8 +203,10 @@ public:
m_trap_exceptions(true),
m_generate_debug_info(false),
m_use_dynamic(lldb::eNoDynamicValues),
m_timeout_usec(default_timeout)
{}
m_timeout_usec(default_timeout),
m_one_thread_timeout_usec(0)
{
}
ExecutionPolicy
GetExecutionPolicy () const
@ -302,6 +304,18 @@ public:
m_timeout_usec = timeout;
}
uint32_t
GetOneThreadTimeoutUsec () const
{
return m_one_thread_timeout_usec;
}
void
SetOneThreadTimeoutUsec (uint32_t timeout = 0)
{
m_one_thread_timeout_usec = timeout;
}
bool
GetTryAllThreads () const
{
@ -378,6 +392,7 @@ private:
bool m_generate_debug_info;
lldb::DynamicValueType m_use_dynamic;
uint32_t m_timeout_usec;
uint32_t m_one_thread_timeout_usec;
};
//----------------------------------------------------------------------

View File

@ -64,6 +64,13 @@ public:
void
SetTimeoutInMicroSeconds (uint32_t timeout = 0);
uint32_t
GetOneThreadTimeoutInMicroSeconds () const;
%feature("docstring", "Sets the timeout in microseconds to run the expression on one thread before either timing out or trying all threads.") SetTimeoutInMicroSeconds;
void
SetOneThreadTimeoutInMicroSeconds (uint32_t timeout = 0);
bool
GetTryAllThreads () const;

View File

@ -101,6 +101,18 @@ SBExpressionOptions::SetTimeoutInMicroSeconds (uint32_t timeout)
m_opaque_ap->SetTimeoutUsec (timeout);
}
uint32_t
SBExpressionOptions::GetOneThreadTimeoutInMicroSeconds () const
{
return m_opaque_ap->GetOneThreadTimeoutUsec ();
}
void
SBExpressionOptions::SetOneThreadTimeoutInMicroSeconds (uint32_t timeout)
{
m_opaque_ap->SetOneThreadTimeoutUsec (timeout);
}
bool
SBExpressionOptions::GetTryAllThreads () const
{

View File

@ -5168,6 +5168,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
TimeValue final_timeout = one_thread_timeout;
uint32_t timeout_usec = options.GetTimeoutUsec();
if (!options.GetStopOthers())
{
before_first_timeout = false;
@ -5175,16 +5176,37 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
}
else if (options.GetTryAllThreads())
{
// If we are running all threads then we take half the time to run all threads, bounded by
// .25 sec.
if (options.GetTimeoutUsec() == 0)
one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec);
uint64_t option_one_thread_timeout = options.GetOneThreadTimeoutUsec();
// If the overall wait is forever, then we only need to set the one thread timeout:
if (timeout_usec == 0)
{
if (option_one_thread_timeout == 0)
one_thread_timeout.OffsetWithMicroSeconds(option_one_thread_timeout);
else
one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec);
}
else
{
uint64_t computed_timeout = timeout_usec / 2;
if (computed_timeout > default_one_thread_timeout_usec)
computed_timeout = default_one_thread_timeout_usec;
one_thread_timeout.OffsetWithMicroSeconds(computed_timeout);
// Otherwise, if the one thread timeout is set, make sure it isn't longer than the overall timeout,
// and use it, otherwise use half the total timeout, bounded by the default_one_thread_timeout_usec.
uint64_t computed_one_thread_timeout;
if (option_one_thread_timeout != 0)
{
if (timeout_usec < option_one_thread_timeout)
{
errors.Printf("RunThreadPlan called without one thread timeout greater than total timeout");
return eExecutionSetupError;
}
computed_one_thread_timeout = option_one_thread_timeout;
}
else
{
computed_one_thread_timeout = timeout_usec / 2;
if (computed_one_thread_timeout > default_one_thread_timeout_usec)
computed_one_thread_timeout = default_one_thread_timeout_usec;
}
one_thread_timeout.OffsetWithMicroSeconds(computed_one_thread_timeout);
}
final_timeout.OffsetWithMicroSeconds (timeout_usec);
}

View File

@ -87,6 +87,16 @@ class ExprCommandWithTimeoutsTestCase(TestBase):
return_value = interp.HandleCommand ("expr -t 1000000 -u true -- wait_a_while(1000)", result)
self.assertTrue(return_value == lldb.eReturnStatusSuccessFinishResult)
# Finally set the one thread timeout and make sure that doesn't change things much:
options.SetTimeoutInMicroSeconds(1000000)
options.SetOneThreadTimeoutInMicroSeconds(500000)
value = frame.EvaluateExpression ("wait_a_while (1000)", options)
self.assertTrue(value.IsValid())
self.assertTrue (value.GetError().Success() == True)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()