forked from OSchip/llvm-project
Add the ability to set timeout & "run all threads" options both from the "expr" command and from
the SB API's that evaluate expressions. <rdar://problem/12457211> llvm-svn: 166062
This commit is contained in:
parent
02a1141e5a
commit
35e1bda695
|
@ -41,6 +41,7 @@ class SBDeclaration;
|
||||||
class SBError;
|
class SBError;
|
||||||
class SBEvent;
|
class SBEvent;
|
||||||
class SBEventList;
|
class SBEventList;
|
||||||
|
class SBExpressionOptions;
|
||||||
class SBFileSpec;
|
class SBFileSpec;
|
||||||
class SBFileSpecList;
|
class SBFileSpecList;
|
||||||
class SBFrame;
|
class SBFrame;
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
//===-- SBEvent.h -----------------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLDB_SBExpressionOptions_h_
|
||||||
|
#define LLDB_SBExpressionOptions_h_
|
||||||
|
|
||||||
|
#include "lldb/API/SBDefines.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace lldb {
|
||||||
|
|
||||||
|
|
||||||
|
class SBExpressionOptions
|
||||||
|
{
|
||||||
|
friend class SBFrame;
|
||||||
|
friend class SBValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SBExpressionOptions();
|
||||||
|
|
||||||
|
SBExpressionOptions (const lldb::SBExpressionOptions &rhs);
|
||||||
|
|
||||||
|
SBExpressionOptions (bool coerce_to_id,
|
||||||
|
bool unwind_on_error,
|
||||||
|
bool keep_in_memory,
|
||||||
|
bool run_others,
|
||||||
|
DynamicValueType use_dynamic,
|
||||||
|
uint32_t timeout_usec);
|
||||||
|
|
||||||
|
~SBExpressionOptions();
|
||||||
|
|
||||||
|
const SBExpressionOptions &
|
||||||
|
operator = (const lldb::SBExpressionOptions &rhs);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesCoerceToId () const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetCoerceToId (bool coerce = true);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesUnwindOnError () const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetUnwindOnError (bool unwind = false);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesKeepInMemory () const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetKeepInMemory (bool keep = true);
|
||||||
|
|
||||||
|
lldb::DynamicValueType
|
||||||
|
GetUseDynamic () const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetTimeoutUsec () const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetTimeoutUsec (uint32_t timeout = 0);
|
||||||
|
|
||||||
|
bool
|
||||||
|
GetRunOthers () const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetRunOthers (bool run_others = true);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
SBExpressionOptions (lldb_private::EvaluateExpressionOptions &expression_options);
|
||||||
|
|
||||||
|
lldb_private::EvaluateExpressionOptions *
|
||||||
|
get () const;
|
||||||
|
|
||||||
|
lldb_private::EvaluateExpressionOptions &
|
||||||
|
ref () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This auto_pointer is made in the constructor and is always valid.
|
||||||
|
mutable std::auto_ptr<lldb_private::EvaluateExpressionOptions> m_opaque_ap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lldb
|
||||||
|
|
||||||
|
#endif // LLDB_SBExpressionOptions_h_
|
|
@ -105,6 +105,9 @@ public:
|
||||||
|
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic, bool unwind_on_error);
|
EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic, bool unwind_on_error);
|
||||||
|
|
||||||
|
lldb::SBValue
|
||||||
|
EvaluateExpression (const char *expr, const SBExpressionOptions &options);
|
||||||
|
|
||||||
/// Gets the lexical block that defines the stack frame. Another way to think
|
/// Gets the lexical block that defines the stack frame. Another way to think
|
||||||
/// of this is it will return the block that contains all of the variables
|
/// of this is it will return the block that contains all of the variables
|
||||||
|
|
|
@ -136,6 +136,9 @@ public:
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
CreateValueFromExpression (const char *name, const char* expression);
|
CreateValueFromExpression (const char *name, const char* expression);
|
||||||
|
|
||||||
|
lldb::SBValue
|
||||||
|
CreateValueFromExpression (const char *name, const char* expression, SBExpressionOptions &options);
|
||||||
|
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
CreateValueFromAddress (const char* name,
|
CreateValueFromAddress (const char* name,
|
||||||
lldb::addr_t address,
|
lldb::addr_t address,
|
||||||
|
|
|
@ -251,9 +251,10 @@ public:
|
||||||
/// function call, and return the program state to what it was before the
|
/// function call, and return the program state to what it was before the
|
||||||
/// execution. If false, we leave the program in the stopped state.
|
/// execution. If false, we leave the program in the stopped state.
|
||||||
///
|
///
|
||||||
/// @param[in] single_thread_timeout_usec
|
/// @param[in] timeout_usec
|
||||||
/// If stop_others is true, the length of time to wait before
|
/// Timeout value (0 for no timeout). If try_all_threads is true, then we
|
||||||
/// concluding that the system is deadlocked.
|
/// will try on one thread for the lesser of .25 sec and half the total timeout.
|
||||||
|
/// then switch to running all threads, otherwise this will be the total timeout.
|
||||||
///
|
///
|
||||||
/// @param[in] errors
|
/// @param[in] errors
|
||||||
/// The stream to write errors to.
|
/// The stream to write errors to.
|
||||||
|
@ -272,7 +273,7 @@ public:
|
||||||
bool stop_others,
|
bool stop_others,
|
||||||
bool try_all_threads,
|
bool try_all_threads,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
Stream &errors,
|
Stream &errors,
|
||||||
lldb::addr_t* this_arg = 0);
|
lldb::addr_t* this_arg = 0);
|
||||||
|
|
||||||
|
@ -329,7 +330,7 @@ public:
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Run the function this ClangFunction was created with.
|
/// Run the function this ClangFunction was created with.
|
||||||
///
|
///
|
||||||
/// This simple version will run the function on one thread. If \a single_thread_timeout_usec
|
/// This simple version will run the function on one thread. If \a timeout_usec
|
||||||
/// is not zero, we time out after that timeout. If \a try_all_threads is true, then we will
|
/// is not zero, we time out after that timeout. If \a try_all_threads is true, then we will
|
||||||
/// resume with all threads on, otherwise we halt the process, and eExecutionInterrupted will be returned.
|
/// resume with all threads on, otherwise we halt the process, and eExecutionInterrupted will be returned.
|
||||||
///
|
///
|
||||||
|
@ -339,8 +340,10 @@ public:
|
||||||
/// @param[in] errors
|
/// @param[in] errors
|
||||||
/// Errors will be written here if there are any.
|
/// Errors will be written here if there are any.
|
||||||
///
|
///
|
||||||
/// @param[in] single_thread_timeout_usec
|
/// @param[in] timeout_usec
|
||||||
/// If \b true, run only this thread, if \b false let all threads run.
|
/// Timeout value (0 for no timeout). If try_all_threads is true, then we
|
||||||
|
/// will try on one thread for the lesser of .25 sec and half the total timeout.
|
||||||
|
/// then switch to running all threads, otherwise this will be the total timeout.
|
||||||
///
|
///
|
||||||
/// @param[in] try_all_threads
|
/// @param[in] try_all_threads
|
||||||
/// If \b true, run only this thread, if \b false let all threads run.
|
/// If \b true, run only this thread, if \b false let all threads run.
|
||||||
|
@ -379,8 +382,11 @@ public:
|
||||||
/// @param[in] stop_others
|
/// @param[in] stop_others
|
||||||
/// If \b true, run only this thread, if \b false let all threads run.
|
/// If \b true, run only this thread, if \b false let all threads run.
|
||||||
///
|
///
|
||||||
/// @param[in] single_thread_timeout_usec
|
/// @param[in] timeout_usec
|
||||||
/// If \b true, run only this thread, if \b false let all threads run.
|
/// Timeout value (0 for no timeout). If try_all_threads is true, then we
|
||||||
|
/// will try on one thread for the lesser of .25 sec and half the total timeout.
|
||||||
|
/// then switch to running all threads, otherwise this will be the total timeout.
|
||||||
|
///
|
||||||
///
|
///
|
||||||
/// @param[in] try_all_threads
|
/// @param[in] try_all_threads
|
||||||
/// If \b true, run only this thread, if \b false let all threads run.
|
/// If \b true, run only this thread, if \b false let all threads run.
|
||||||
|
@ -396,7 +402,7 @@ public:
|
||||||
lldb::addr_t *args_addr_ptr,
|
lldb::addr_t *args_addr_ptr,
|
||||||
Stream &errors,
|
Stream &errors,
|
||||||
bool stop_others,
|
bool stop_others,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
bool try_all_threads,
|
bool try_all_threads,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
Value &results);
|
Value &results);
|
||||||
|
|
|
@ -132,9 +132,16 @@ public:
|
||||||
/// A pointer to direct at the persistent variable in which the
|
/// A pointer to direct at the persistent variable in which the
|
||||||
/// expression's result is stored.
|
/// expression's result is stored.
|
||||||
///
|
///
|
||||||
/// @param[in] single_thread_timeout_usec
|
/// @param[in] try_all_threads
|
||||||
/// The amount of time (in usec) that we are willing to wait for this
|
/// If true, then we will try to run all threads if the function doesn't complete on
|
||||||
/// expression to complete, before assuming that we are blocked and giving up
|
/// one thread. See timeout_usec for the interaction of this variable and
|
||||||
|
/// the timeout.
|
||||||
|
///
|
||||||
|
/// @param[in] timeout_usec
|
||||||
|
/// Timeout value (0 for no timeout). If try_all_threads is true, then we
|
||||||
|
/// will try on one thread for the lesser of .25 sec and half the total timeout.
|
||||||
|
/// then switch to running all threads, otherwise this will be the total timeout.
|
||||||
|
///
|
||||||
///
|
///
|
||||||
/// @return
|
/// @return
|
||||||
/// A Process::Execution results value.
|
/// A Process::Execution results value.
|
||||||
|
@ -145,7 +152,8 @@ public:
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
ClangUserExpressionSP &shared_ptr_to_me,
|
ClangUserExpressionSP &shared_ptr_to_me,
|
||||||
lldb::ClangExpressionVariableSP &result,
|
lldb::ClangExpressionVariableSP &result,
|
||||||
uint32_t single_thread_timeout_usec = 500000);
|
bool try_all_threads = true,
|
||||||
|
uint32_t timeout_usec = 500000);
|
||||||
|
|
||||||
ThreadPlan *
|
ThreadPlan *
|
||||||
GetThreadPlanToExecuteJITExpression (Stream &error_stream,
|
GetThreadPlanToExecuteJITExpression (Stream &error_stream,
|
||||||
|
@ -314,9 +322,15 @@ public:
|
||||||
/// @param[in/out] result_valobj_sp
|
/// @param[in/out] result_valobj_sp
|
||||||
/// If execution is successful, the result valobj is placed here.
|
/// If execution is successful, the result valobj is placed here.
|
||||||
///
|
///
|
||||||
/// @param[in] single_thread_timeout_usec
|
/// @param[in] try_all_threads
|
||||||
/// The amount of time (in usec) that we are willing to wait for this
|
/// If true, then we will try to run all threads if the function doesn't complete on
|
||||||
/// expression to complete, before assuming that we are blocked and giving up
|
/// one thread. See timeout_usec for the interaction of this variable and
|
||||||
|
/// the timeout.
|
||||||
|
///
|
||||||
|
/// @param[in] timeout_usec
|
||||||
|
/// Timeout value (0 for no timeout). If try_all_threads is true, then we
|
||||||
|
/// will try on one thread for the lesser of .25 sec and half the total timeout.
|
||||||
|
/// then switch to running all threads, otherwise this will be the total timeout.
|
||||||
///
|
///
|
||||||
/// @result
|
/// @result
|
||||||
/// A Process::ExecutionResults value. eExecutionCompleted for success.
|
/// A Process::ExecutionResults value. eExecutionCompleted for success.
|
||||||
|
@ -330,7 +344,8 @@ public:
|
||||||
const char *expr_cstr,
|
const char *expr_cstr,
|
||||||
const char *expr_prefix,
|
const char *expr_prefix,
|
||||||
lldb::ValueObjectSP &result_valobj_sp,
|
lldb::ValueObjectSP &result_valobj_sp,
|
||||||
uint32_t single_thread_timeout_usec = 500000);
|
bool try_all_threads = true,
|
||||||
|
uint32_t timeout_usec = 500000);
|
||||||
|
|
||||||
static ExecutionResults
|
static ExecutionResults
|
||||||
EvaluateWithError (ExecutionContext &exe_ctx,
|
EvaluateWithError (ExecutionContext &exe_ctx,
|
||||||
|
@ -342,7 +357,8 @@ public:
|
||||||
const char *expr_prefix,
|
const char *expr_prefix,
|
||||||
lldb::ValueObjectSP &result_valobj_sp,
|
lldb::ValueObjectSP &result_valobj_sp,
|
||||||
Error &error,
|
Error &error,
|
||||||
uint32_t single_thread_timeout_usec = 500000);
|
bool try_all_threads = true,
|
||||||
|
uint32_t timeout_usec = 500000);
|
||||||
|
|
||||||
static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
|
static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -2363,9 +2363,9 @@ public:
|
||||||
RunThreadPlan (ExecutionContext &exe_ctx,
|
RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
lldb::ThreadPlanSP &thread_plan_sp,
|
lldb::ThreadPlanSP &thread_plan_sp,
|
||||||
bool stop_others,
|
bool stop_others,
|
||||||
bool try_all_threads,
|
bool run_others,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
Stream &errors);
|
Stream &errors);
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
|
|
@ -137,6 +137,121 @@ public:
|
||||||
|
|
||||||
typedef STD_SHARED_PTR(TargetProperties) TargetPropertiesSP;
|
typedef STD_SHARED_PTR(TargetProperties) TargetPropertiesSP;
|
||||||
|
|
||||||
|
class EvaluateExpressionOptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t default_timeout = 500000;
|
||||||
|
EvaluateExpressionOptions() :
|
||||||
|
m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
|
||||||
|
m_coerce_to_id(false),
|
||||||
|
m_unwind_on_error(true),
|
||||||
|
m_keep_in_memory(false),
|
||||||
|
m_run_others(true),
|
||||||
|
m_use_dynamic(lldb::eNoDynamicValues),
|
||||||
|
m_timeout_usec(default_timeout)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ExecutionPolicy
|
||||||
|
GetExecutionPolicy () const
|
||||||
|
{
|
||||||
|
return m_execution_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
|
||||||
|
{
|
||||||
|
m_execution_policy = policy;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesCoerceToId () const
|
||||||
|
{
|
||||||
|
return m_coerce_to_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetCoerceToId (bool coerce = true)
|
||||||
|
{
|
||||||
|
m_coerce_to_id = coerce;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesUnwindOnError () const
|
||||||
|
{
|
||||||
|
return m_unwind_on_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetUnwindOnError (bool unwind = false)
|
||||||
|
{
|
||||||
|
m_unwind_on_error = unwind;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesKeepInMemory () const
|
||||||
|
{
|
||||||
|
return m_keep_in_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetKeepInMemory (bool keep = true)
|
||||||
|
{
|
||||||
|
m_keep_in_memory = keep;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::DynamicValueType
|
||||||
|
GetUseDynamic () const
|
||||||
|
{
|
||||||
|
return m_use_dynamic;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
|
||||||
|
{
|
||||||
|
m_use_dynamic = dynamic;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetTimeoutUsec () const
|
||||||
|
{
|
||||||
|
return m_timeout_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetTimeoutUsec (uint32_t timeout = 0)
|
||||||
|
{
|
||||||
|
m_timeout_usec = timeout;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GetRunOthers () const
|
||||||
|
{
|
||||||
|
return m_run_others;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions&
|
||||||
|
SetRunOthers (bool run_others = true)
|
||||||
|
{
|
||||||
|
m_run_others = run_others;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ExecutionPolicy m_execution_policy;
|
||||||
|
bool m_coerce_to_id;
|
||||||
|
bool m_unwind_on_error;
|
||||||
|
bool m_keep_in_memory;
|
||||||
|
bool m_run_others;
|
||||||
|
lldb::DynamicValueType m_use_dynamic;
|
||||||
|
uint32_t m_timeout_usec;
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Target
|
// Target
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -760,104 +875,6 @@ public:
|
||||||
ClangASTImporter *
|
ClangASTImporter *
|
||||||
GetClangASTImporter();
|
GetClangASTImporter();
|
||||||
|
|
||||||
class EvaluateExpressionOptions
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EvaluateExpressionOptions() :
|
|
||||||
m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
|
|
||||||
m_coerce_to_id(false),
|
|
||||||
m_unwind_on_error(true),
|
|
||||||
m_keep_in_memory(false),
|
|
||||||
m_use_dynamic(lldb::eNoDynamicValues),
|
|
||||||
m_single_thread_timeout_usec(500000)
|
|
||||||
{}
|
|
||||||
|
|
||||||
ExecutionPolicy
|
|
||||||
GetExecutionPolicy () const
|
|
||||||
{
|
|
||||||
return m_execution_policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluateExpressionOptions&
|
|
||||||
SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
|
|
||||||
{
|
|
||||||
m_execution_policy = policy;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DoesCoerceToId () const
|
|
||||||
{
|
|
||||||
return m_coerce_to_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluateExpressionOptions&
|
|
||||||
SetCoerceToId (bool coerce = true)
|
|
||||||
{
|
|
||||||
m_coerce_to_id = coerce;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DoesUnwindOnError () const
|
|
||||||
{
|
|
||||||
return m_unwind_on_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluateExpressionOptions&
|
|
||||||
SetUnwindOnError (bool unwind = false)
|
|
||||||
{
|
|
||||||
m_unwind_on_error = unwind;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DoesKeepInMemory () const
|
|
||||||
{
|
|
||||||
return m_keep_in_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluateExpressionOptions&
|
|
||||||
SetKeepInMemory (bool keep = true)
|
|
||||||
{
|
|
||||||
m_keep_in_memory = keep;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
lldb::DynamicValueType
|
|
||||||
GetUseDynamic () const
|
|
||||||
{
|
|
||||||
return m_use_dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluateExpressionOptions&
|
|
||||||
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
|
|
||||||
{
|
|
||||||
m_use_dynamic = dynamic;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
GetSingleThreadTimeoutUsec () const
|
|
||||||
{
|
|
||||||
return m_single_thread_timeout_usec;
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluateExpressionOptions&
|
|
||||||
SetSingleThreadTimeoutUsec (uint32_t timeout = 0)
|
|
||||||
{
|
|
||||||
m_single_thread_timeout_usec = timeout;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ExecutionPolicy m_execution_policy;
|
|
||||||
bool m_coerce_to_id;
|
|
||||||
bool m_unwind_on_error;
|
|
||||||
bool m_keep_in_memory;
|
|
||||||
lldb::DynamicValueType m_use_dynamic;
|
|
||||||
uint32_t m_single_thread_timeout_usec;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Since expressions results can persist beyond the lifetime of a process,
|
// Since expressions results can persist beyond the lifetime of a process,
|
||||||
// and the const expression results are available after a process is gone,
|
// and the const expression results are available after a process is gone,
|
||||||
|
|
|
@ -98,6 +98,7 @@ class DynamicLibrary;
|
||||||
class DynamicLoader;
|
class DynamicLoader;
|
||||||
class EmulateInstruction;
|
class EmulateInstruction;
|
||||||
class Error;
|
class Error;
|
||||||
|
class EvaluateExpressionOptions;
|
||||||
class Event;
|
class Event;
|
||||||
class EventData;
|
class EventData;
|
||||||
class ExecutionContext;
|
class ExecutionContext;
|
||||||
|
|
|
@ -505,6 +505,8 @@
|
||||||
4CCA645613B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644813B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp */; };
|
4CCA645613B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644813B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp */; };
|
||||||
4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644A13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */; };
|
4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644A13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */; };
|
||||||
4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */; };
|
4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */; };
|
||||||
|
4CE4F673162C971A00F75CB3 /* SBExpressionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CE4F672162C971A00F75CB3 /* SBExpressionOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
4CE4F675162C973F00F75CB3 /* SBExpressionOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F674162C973F00F75CB3 /* SBExpressionOptions.cpp */; };
|
||||||
4CF3D80C15AF4DC800845BF3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; };
|
4CF3D80C15AF4DC800845BF3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; };
|
||||||
4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /* SBFileSpecList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /* SBFileSpecList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
|
4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
|
||||||
|
@ -1492,6 +1494,9 @@
|
||||||
4CCA644B13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleThreadPlanStepThroughObjCTrampoline.h; sourceTree = "<group>"; };
|
4CCA644B13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleThreadPlanStepThroughObjCTrampoline.h; sourceTree = "<group>"; };
|
||||||
4CD0BD0C134BFAB600CB44D4 /* ValueObjectDynamicValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectDynamicValue.h; path = include/lldb/Core/ValueObjectDynamicValue.h; sourceTree = "<group>"; };
|
4CD0BD0C134BFAB600CB44D4 /* ValueObjectDynamicValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectDynamicValue.h; path = include/lldb/Core/ValueObjectDynamicValue.h; sourceTree = "<group>"; };
|
||||||
4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectDynamicValue.cpp; path = source/Core/ValueObjectDynamicValue.cpp; sourceTree = "<group>"; };
|
4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectDynamicValue.cpp; path = source/Core/ValueObjectDynamicValue.cpp; sourceTree = "<group>"; };
|
||||||
|
4CE4F672162C971A00F75CB3 /* SBExpressionOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBExpressionOptions.h; path = include/lldb/API/SBExpressionOptions.h; sourceTree = "<group>"; };
|
||||||
|
4CE4F674162C973F00F75CB3 /* SBExpressionOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBExpressionOptions.cpp; path = source/API/SBExpressionOptions.cpp; sourceTree = "<group>"; };
|
||||||
|
4CE4F676162CE1E100F75CB3 /* SBExpressionOptions.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBExpressionOptions.i; sourceTree = "<group>"; };
|
||||||
4CEDAED311754F5E00E875A6 /* ThreadPlanStepUntil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepUntil.h; path = include/lldb/Target/ThreadPlanStepUntil.h; sourceTree = "<group>"; };
|
4CEDAED311754F5E00E875A6 /* ThreadPlanStepUntil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepUntil.h; path = include/lldb/Target/ThreadPlanStepUntil.h; sourceTree = "<group>"; };
|
||||||
4CF52AF41428291E0051E832 /* SBFileSpecList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFileSpecList.h; path = include/lldb/API/SBFileSpecList.h; sourceTree = "<group>"; };
|
4CF52AF41428291E0051E832 /* SBFileSpecList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFileSpecList.h; path = include/lldb/API/SBFileSpecList.h; sourceTree = "<group>"; };
|
||||||
4CF52AF7142829390051E832 /* SBFileSpecList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFileSpecList.cpp; path = source/API/SBFileSpecList.cpp; sourceTree = "<group>"; };
|
4CF52AF7142829390051E832 /* SBFileSpecList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFileSpecList.cpp; path = source/API/SBFileSpecList.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -2028,6 +2033,7 @@
|
||||||
2611FEFC142D83060017FEA3 /* SBFileSpec.i */,
|
2611FEFC142D83060017FEA3 /* SBFileSpec.i */,
|
||||||
2611FEFD142D83060017FEA3 /* SBFileSpecList.i */,
|
2611FEFD142D83060017FEA3 /* SBFileSpecList.i */,
|
||||||
2611FEFE142D83060017FEA3 /* SBFrame.i */,
|
2611FEFE142D83060017FEA3 /* SBFrame.i */,
|
||||||
|
4CE4F676162CE1E100F75CB3 /* SBExpressionOptions.i */,
|
||||||
2611FEFF142D83060017FEA3 /* SBFunction.i */,
|
2611FEFF142D83060017FEA3 /* SBFunction.i */,
|
||||||
2611FF00142D83060017FEA3 /* SBHostOS.i */,
|
2611FF00142D83060017FEA3 /* SBHostOS.i */,
|
||||||
2611FF01142D83060017FEA3 /* SBInputReader.i */,
|
2611FF01142D83060017FEA3 /* SBInputReader.i */,
|
||||||
|
@ -2118,6 +2124,8 @@
|
||||||
2682F284115EF3A700CCFF99 /* SBError.cpp */,
|
2682F284115EF3A700CCFF99 /* SBError.cpp */,
|
||||||
9A9830FE1125FC5800A56CB0 /* SBEvent.h */,
|
9A9830FE1125FC5800A56CB0 /* SBEvent.h */,
|
||||||
9A9830FD1125FC5800A56CB0 /* SBEvent.cpp */,
|
9A9830FD1125FC5800A56CB0 /* SBEvent.cpp */,
|
||||||
|
4CE4F672162C971A00F75CB3 /* SBExpressionOptions.h */,
|
||||||
|
4CE4F674162C973F00F75CB3 /* SBExpressionOptions.cpp */,
|
||||||
26022531115F27FA00A601A2 /* SBFileSpec.h */,
|
26022531115F27FA00A601A2 /* SBFileSpec.h */,
|
||||||
26022532115F281400A601A2 /* SBFileSpec.cpp */,
|
26022532115F281400A601A2 /* SBFileSpec.cpp */,
|
||||||
4CF52AF41428291E0051E832 /* SBFileSpecList.h */,
|
4CF52AF41428291E0051E832 /* SBFileSpecList.h */,
|
||||||
|
@ -3381,6 +3389,7 @@
|
||||||
B2A58722143119810092BFBA /* SBWatchpoint.h in Headers */,
|
B2A58722143119810092BFBA /* SBWatchpoint.h in Headers */,
|
||||||
26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */,
|
26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */,
|
||||||
26D265BC136B4269002EEE45 /* lldb-public.h in Headers */,
|
26D265BC136B4269002EEE45 /* lldb-public.h in Headers */,
|
||||||
|
4CE4F673162C971A00F75CB3 /* SBExpressionOptions.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -3773,6 +3782,7 @@
|
||||||
9475C18814E5E9FA001BFC6D /* SBTypeCategory.cpp in Sources */,
|
9475C18814E5E9FA001BFC6D /* SBTypeCategory.cpp in Sources */,
|
||||||
9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */,
|
9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */,
|
||||||
9452573A16262D0200325455 /* SBDeclaration.cpp in Sources */,
|
9452573A16262D0200325455 /* SBDeclaration.cpp in Sources */,
|
||||||
|
4CE4F675162C973F00F75CB3 /* SBExpressionOptions.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,6 +76,7 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\
|
||||||
" ${SRC_ROOT}/include/lldb/API/SBDebugger.h"\
|
" ${SRC_ROOT}/include/lldb/API/SBDebugger.h"\
|
||||||
" ${SRC_ROOT}/include/lldb/API/SBError.h"\
|
" ${SRC_ROOT}/include/lldb/API/SBError.h"\
|
||||||
" ${SRC_ROOT}/include/lldb/API/SBEvent.h"\
|
" ${SRC_ROOT}/include/lldb/API/SBEvent.h"\
|
||||||
|
" ${SRC_ROOT}/include/lldb/API/SBExpressionOptions.h"\
|
||||||
" ${SRC_ROOT}/include/lldb/API/SBFileSpec.h"\
|
" ${SRC_ROOT}/include/lldb/API/SBFileSpec.h"\
|
||||||
" ${SRC_ROOT}/include/lldb/API/SBFrame.h"\
|
" ${SRC_ROOT}/include/lldb/API/SBFrame.h"\
|
||||||
" ${SRC_ROOT}/include/lldb/API/SBFunction.h"\
|
" ${SRC_ROOT}/include/lldb/API/SBFunction.h"\
|
||||||
|
@ -120,6 +121,7 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\
|
||||||
" ${SRC_ROOT}/scripts/Python/interface/SBDeclaration.i"\
|
" ${SRC_ROOT}/scripts/Python/interface/SBDeclaration.i"\
|
||||||
" ${SRC_ROOT}/scripts/Python/interface/SBError.i"\
|
" ${SRC_ROOT}/scripts/Python/interface/SBError.i"\
|
||||||
" ${SRC_ROOT}/scripts/Python/interface/SBEvent.i"\
|
" ${SRC_ROOT}/scripts/Python/interface/SBEvent.i"\
|
||||||
|
" ${SRC_ROOT}/scripts/Python/interface/SBExpressionOptions.i"\
|
||||||
" ${SRC_ROOT}/scripts/Python/interface/SBFileSpec.i"\
|
" ${SRC_ROOT}/scripts/Python/interface/SBFileSpec.i"\
|
||||||
" ${SRC_ROOT}/scripts/Python/interface/SBFrame.i"\
|
" ${SRC_ROOT}/scripts/Python/interface/SBFrame.i"\
|
||||||
" ${SRC_ROOT}/scripts/Python/interface/SBFunction.i"\
|
" ${SRC_ROOT}/scripts/Python/interface/SBFunction.i"\
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
//===-- SWIG interface for SBExpressionOptions -----------------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
namespace lldb {
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"A container for options to use when evaluating expressions."
|
||||||
|
) SBExpressionOptions;
|
||||||
|
|
||||||
|
class SBExpressionOptions
|
||||||
|
{
|
||||||
|
friend class SBFrame;
|
||||||
|
friend class SBValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SBExpressionOptions();
|
||||||
|
|
||||||
|
SBExpressionOptions (const lldb::SBExpressionOptions &rhs);
|
||||||
|
|
||||||
|
SBExpressionOptions (bool coerce_to_id,
|
||||||
|
bool unwind_on_error,
|
||||||
|
bool keep_in_memory,
|
||||||
|
bool run_others,
|
||||||
|
DynamicValueType use_dynamic,
|
||||||
|
uint32_t timeout_usec);
|
||||||
|
|
||||||
|
~SBExpressionOptions();
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesCoerceToId () const;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Sets whether to coerce the expression result to ObjC id type after evaluation."
|
||||||
|
) SetCoerceToId;
|
||||||
|
void
|
||||||
|
SetCoerceToId (bool coerce = true);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesUnwindOnError () const;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Sets whether to unwind the expression stack on error."
|
||||||
|
) SetUnwindOnError;
|
||||||
|
void
|
||||||
|
SetUnwindOnError (bool unwind = false);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoesKeepInMemory () const;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Sets whether to keep the expression result in the target program's memory - forced to true when creating SBValues."
|
||||||
|
) SetKeepInMemory;
|
||||||
|
void
|
||||||
|
SetKeepInMemory (bool keep = true);
|
||||||
|
|
||||||
|
lldb::DynamicValueType
|
||||||
|
GetUseDynamic () const;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Sets whether to cast the expression result to its dynamic type."
|
||||||
|
) SetUseDynamic;
|
||||||
|
void
|
||||||
|
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetTimeoutUsec () const;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Sets the duration we will wait before cancelling expression evaluation. 0 means wait forever."
|
||||||
|
) SetTimeoutUsec;
|
||||||
|
void
|
||||||
|
SetTimeoutUsec (uint32_t timeout = 0);
|
||||||
|
|
||||||
|
bool
|
||||||
|
GetRunOthers () const;
|
||||||
|
|
||||||
|
%feature("docstring",
|
||||||
|
"Sets whether to run all threads if the expression does not complete on one thread."
|
||||||
|
) SetRunOthers;
|
||||||
|
void
|
||||||
|
SetRunOthers (bool run_others = true);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
SBExpressionOptions (lldb_private::EvaluateExpressionOptions &expression_options);
|
||||||
|
|
||||||
|
lldb_private::EvaluateExpressionOptions *
|
||||||
|
get () const;
|
||||||
|
|
||||||
|
lldb_private::EvaluateExpressionOptions &
|
||||||
|
ref () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This auto_pointer is made in the constructor and is always valid.
|
||||||
|
mutable std::auto_ptr<lldb_private::EvaluateExpressionOptions> m_opaque_ap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lldb
|
|
@ -139,6 +139,9 @@ public:
|
||||||
|
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic, bool unwind_on_error);
|
EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic, bool unwind_on_error);
|
||||||
|
|
||||||
|
lldb::SBValue
|
||||||
|
EvaluateExpression (const char *expr, SBExpressionOptions &options);
|
||||||
|
|
||||||
%feature("docstring", "
|
%feature("docstring", "
|
||||||
/// Gets the lexical block that defines the stack frame. Another way to think
|
/// Gets the lexical block that defines the stack frame. Another way to think
|
||||||
|
|
|
@ -222,6 +222,9 @@ public:
|
||||||
|
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
CreateValueFromExpression (const char *name, const char* expression);
|
CreateValueFromExpression (const char *name, const char* expression);
|
||||||
|
|
||||||
|
lldb::SBValue
|
||||||
|
CreateValueFromExpression (const char *name, const char* expression, SBExpressionOptions &options);
|
||||||
|
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
CreateValueFromAddress(const char* name, lldb::addr_t address, lldb::SBType type);
|
CreateValueFromAddress(const char* name, lldb::addr_t address, lldb::SBType type);
|
||||||
|
|
|
@ -66,6 +66,7 @@ import os
|
||||||
#include "lldb/API/SBDeclaration.h"
|
#include "lldb/API/SBDeclaration.h"
|
||||||
#include "lldb/API/SBError.h"
|
#include "lldb/API/SBError.h"
|
||||||
#include "lldb/API/SBEvent.h"
|
#include "lldb/API/SBEvent.h"
|
||||||
|
#include "lldb/API/SBExpressionOptions.h"
|
||||||
#include "lldb/API/SBFileSpec.h"
|
#include "lldb/API/SBFileSpec.h"
|
||||||
#include "lldb/API/SBFileSpecList.h"
|
#include "lldb/API/SBFileSpecList.h"
|
||||||
#include "lldb/API/SBFrame.h"
|
#include "lldb/API/SBFrame.h"
|
||||||
|
@ -125,6 +126,7 @@ import os
|
||||||
%include "./Python/interface/SBDeclaration.i"
|
%include "./Python/interface/SBDeclaration.i"
|
||||||
%include "./Python/interface/SBError.i"
|
%include "./Python/interface/SBError.i"
|
||||||
%include "./Python/interface/SBEvent.i"
|
%include "./Python/interface/SBEvent.i"
|
||||||
|
%include "./Python/interface/SBExpressionOptions.i"
|
||||||
%include "./Python/interface/SBFileSpec.i"
|
%include "./Python/interface/SBFileSpec.i"
|
||||||
%include "./Python/interface/SBFileSpecList.i"
|
%include "./Python/interface/SBFileSpecList.i"
|
||||||
%include "./Python/interface/SBFrame.i"
|
%include "./Python/interface/SBFrame.i"
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
//===-- SBExpressionOptions.cpp ---------------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "lldb/API/SBExpressionOptions.h"
|
||||||
|
#include "lldb/API/SBStream.h"
|
||||||
|
|
||||||
|
#include "lldb/Target/Target.h"
|
||||||
|
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace lldb_private;
|
||||||
|
|
||||||
|
|
||||||
|
SBExpressionOptions::SBExpressionOptions ()
|
||||||
|
{
|
||||||
|
m_opaque_ap.reset(new EvaluateExpressionOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
SBExpressionOptions::SBExpressionOptions (bool coerce_to_id,
|
||||||
|
bool unwind_on_error,
|
||||||
|
bool keep_in_memory,
|
||||||
|
bool run_others,
|
||||||
|
DynamicValueType use_dynamic,
|
||||||
|
uint32_t timeout_usec)
|
||||||
|
{
|
||||||
|
m_opaque_ap.reset(new EvaluateExpressionOptions());
|
||||||
|
m_opaque_ap->SetCoerceToId(coerce_to_id);
|
||||||
|
m_opaque_ap->SetUnwindOnError(unwind_on_error);
|
||||||
|
m_opaque_ap->SetKeepInMemory(keep_in_memory);
|
||||||
|
m_opaque_ap->SetRunOthers(run_others);
|
||||||
|
m_opaque_ap->SetUseDynamic (use_dynamic);
|
||||||
|
m_opaque_ap->SetTimeoutUsec (timeout_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
SBExpressionOptions::SBExpressionOptions (const SBExpressionOptions &rhs)
|
||||||
|
{
|
||||||
|
m_opaque_ap.reset(new EvaluateExpressionOptions());
|
||||||
|
*(m_opaque_ap.get()) = rhs.ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
const SBExpressionOptions &
|
||||||
|
SBExpressionOptions::operator = (const SBExpressionOptions &rhs)
|
||||||
|
{
|
||||||
|
if (this != &rhs)
|
||||||
|
{
|
||||||
|
this->ref() = rhs.ref();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SBExpressionOptions::~SBExpressionOptions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SBExpressionOptions::DoesCoerceToId () const
|
||||||
|
{
|
||||||
|
return m_opaque_ap->DoesCoerceToId ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SBExpressionOptions::SetCoerceToId (bool coerce)
|
||||||
|
{
|
||||||
|
m_opaque_ap->SetCoerceToId (coerce);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SBExpressionOptions::DoesUnwindOnError () const
|
||||||
|
{
|
||||||
|
return m_opaque_ap->DoesUnwindOnError ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SBExpressionOptions::SetUnwindOnError (bool unwind)
|
||||||
|
{
|
||||||
|
m_opaque_ap->SetUnwindOnError (unwind);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SBExpressionOptions::DoesKeepInMemory () const
|
||||||
|
{
|
||||||
|
return m_opaque_ap->DoesKeepInMemory ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SBExpressionOptions::SetKeepInMemory (bool keep)
|
||||||
|
{
|
||||||
|
m_opaque_ap->SetKeepInMemory (keep);
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::DynamicValueType
|
||||||
|
SBExpressionOptions::GetUseDynamic () const
|
||||||
|
{
|
||||||
|
return m_opaque_ap->GetUseDynamic ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SBExpressionOptions::SetUseDynamic (lldb::DynamicValueType dynamic)
|
||||||
|
{
|
||||||
|
m_opaque_ap->SetUseDynamic (dynamic);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
SBExpressionOptions::GetTimeoutUsec () const
|
||||||
|
{
|
||||||
|
return m_opaque_ap->GetTimeoutUsec ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SBExpressionOptions::SetTimeoutUsec (uint32_t timeout)
|
||||||
|
{
|
||||||
|
m_opaque_ap->SetTimeoutUsec (timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SBExpressionOptions::GetRunOthers () const
|
||||||
|
{
|
||||||
|
return m_opaque_ap->GetRunOthers ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SBExpressionOptions::SetRunOthers (bool run_others)
|
||||||
|
{
|
||||||
|
m_opaque_ap->SetRunOthers (run_others);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions *
|
||||||
|
SBExpressionOptions::get() const
|
||||||
|
{
|
||||||
|
return m_opaque_ap.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluateExpressionOptions &
|
||||||
|
SBExpressionOptions::ref () const
|
||||||
|
{
|
||||||
|
return *(m_opaque_ap.get());
|
||||||
|
}
|
|
@ -40,6 +40,7 @@
|
||||||
#include "lldb/API/SBDebugger.h"
|
#include "lldb/API/SBDebugger.h"
|
||||||
#include "lldb/API/SBValue.h"
|
#include "lldb/API/SBValue.h"
|
||||||
#include "lldb/API/SBAddress.h"
|
#include "lldb/API/SBAddress.h"
|
||||||
|
#include "lldb/API/SBExpressionOptions.h"
|
||||||
#include "lldb/API/SBStream.h"
|
#include "lldb/API/SBStream.h"
|
||||||
#include "lldb/API/SBSymbolContext.h"
|
#include "lldb/API/SBSymbolContext.h"
|
||||||
#include "lldb/API/SBThread.h"
|
#include "lldb/API/SBThread.h"
|
||||||
|
@ -1040,8 +1041,11 @@ SBFrame::EvaluateExpression (const char *expr)
|
||||||
Target *target = exe_ctx.GetTargetPtr();
|
Target *target = exe_ctx.GetTargetPtr();
|
||||||
if (frame && target)
|
if (frame && target)
|
||||||
{
|
{
|
||||||
lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue();
|
SBExpressionOptions options;
|
||||||
result = EvaluateExpression (expr, use_dynamic);
|
lldb::DynamicValueType fetch_dynamic_value = frame->CalculateTarget()->GetPreferDynamicValue();
|
||||||
|
options.SetUseDynamic (fetch_dynamic_value);
|
||||||
|
options.SetUnwindOnError (true);
|
||||||
|
return EvaluateExpression (expr, options);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1049,11 +1053,23 @@ SBFrame::EvaluateExpression (const char *expr)
|
||||||
SBValue
|
SBValue
|
||||||
SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value)
|
SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value)
|
||||||
{
|
{
|
||||||
return EvaluateExpression (expr, fetch_dynamic_value, true);
|
SBExpressionOptions options;
|
||||||
|
options.SetUseDynamic (fetch_dynamic_value);
|
||||||
|
options.SetUnwindOnError (true);
|
||||||
|
return EvaluateExpression (expr, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
SBValue
|
SBValue
|
||||||
SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value, bool unwind_on_error)
|
SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value, bool unwind_on_error)
|
||||||
|
{
|
||||||
|
SBExpressionOptions options;
|
||||||
|
options.SetUseDynamic (fetch_dynamic_value);
|
||||||
|
options.SetUnwindOnError (unwind_on_error);
|
||||||
|
return EvaluateExpression (expr, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::SBValue
|
||||||
|
SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
|
||||||
{
|
{
|
||||||
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||||
|
|
||||||
|
@ -1080,16 +1096,12 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna
|
||||||
StreamString frame_description;
|
StreamString frame_description;
|
||||||
frame->DumpUsingSettingsFormat (&frame_description);
|
frame->DumpUsingSettingsFormat (&frame_description);
|
||||||
Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
|
Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
|
||||||
expr, fetch_dynamic_value, frame_description.GetString().c_str());
|
expr, options.GetUseDynamic(), frame_description.GetString().c_str());
|
||||||
#endif
|
#endif
|
||||||
Target::EvaluateExpressionOptions options;
|
|
||||||
options.SetUnwindOnError(unwind_on_error)
|
|
||||||
.SetUseDynamic(fetch_dynamic_value);
|
|
||||||
|
|
||||||
exe_results = target->EvaluateExpression (expr,
|
exe_results = target->EvaluateExpression (expr,
|
||||||
frame,
|
frame,
|
||||||
expr_value_sp,
|
expr_value_sp,
|
||||||
options);
|
options.ref());
|
||||||
expr_result.SetSP(expr_value_sp);
|
expr_result.SetSP(expr_value_sp);
|
||||||
#ifdef LLDB_CONFIGURATION_DEBUG
|
#ifdef LLDB_CONFIGURATION_DEBUG
|
||||||
Host::SetCrashDescription (NULL);
|
Host::SetCrashDescription (NULL);
|
||||||
|
|
|
@ -40,11 +40,12 @@
|
||||||
#include "lldb/Target/Target.h"
|
#include "lldb/Target/Target.h"
|
||||||
#include "lldb/Target/Thread.h"
|
#include "lldb/Target/Thread.h"
|
||||||
|
|
||||||
|
#include "lldb/API/SBDebugger.h"
|
||||||
|
#include "lldb/API/SBExpressionOptions.h"
|
||||||
|
#include "lldb/API/SBFrame.h"
|
||||||
#include "lldb/API/SBProcess.h"
|
#include "lldb/API/SBProcess.h"
|
||||||
#include "lldb/API/SBTarget.h"
|
#include "lldb/API/SBTarget.h"
|
||||||
#include "lldb/API/SBThread.h"
|
#include "lldb/API/SBThread.h"
|
||||||
#include "lldb/API/SBFrame.h"
|
|
||||||
#include "lldb/API/SBDebugger.h"
|
|
||||||
|
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
@ -694,9 +695,12 @@ SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type)
|
||||||
if (log)
|
if (log)
|
||||||
{
|
{
|
||||||
if (new_value_sp)
|
if (new_value_sp)
|
||||||
log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString());
|
log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"",
|
||||||
|
value_sp.get(),
|
||||||
|
new_value_sp->GetName().AsCString());
|
||||||
else
|
else
|
||||||
log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", value_sp.get());
|
log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL",
|
||||||
|
value_sp.get());
|
||||||
}
|
}
|
||||||
return sb_value;
|
return sb_value;
|
||||||
}
|
}
|
||||||
|
@ -714,6 +718,14 @@ SBValue::Cast (SBType type)
|
||||||
|
|
||||||
lldb::SBValue
|
lldb::SBValue
|
||||||
SBValue::CreateValueFromExpression (const char *name, const char* expression)
|
SBValue::CreateValueFromExpression (const char *name, const char* expression)
|
||||||
|
{
|
||||||
|
SBExpressionOptions options;
|
||||||
|
options.SetKeepInMemory(true);
|
||||||
|
return CreateValueFromExpression (name, expression, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::SBValue
|
||||||
|
SBValue::CreateValueFromExpression (const char *name, const char *expression, SBExpressionOptions &options)
|
||||||
{
|
{
|
||||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||||
lldb::SBValue sb_value;
|
lldb::SBValue sb_value;
|
||||||
|
@ -734,12 +746,11 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression)
|
||||||
Target* target = exe_ctx.GetTargetPtr();
|
Target* target = exe_ctx.GetTargetPtr();
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
Target::EvaluateExpressionOptions options;
|
|
||||||
options.SetKeepInMemory(true);
|
options.SetKeepInMemory(true);
|
||||||
target->EvaluateExpression (expression,
|
target->EvaluateExpression (expression,
|
||||||
exe_ctx.GetFramePtr(),
|
exe_ctx.GetFramePtr(),
|
||||||
new_value_sp,
|
new_value_sp,
|
||||||
options);
|
options.ref());
|
||||||
if (new_value_sp)
|
if (new_value_sp)
|
||||||
{
|
{
|
||||||
new_value_sp->SetName(ConstString(name));
|
new_value_sp->SetName(ConstString(name));
|
||||||
|
@ -1617,7 +1628,9 @@ SBValue::GetAddress()
|
||||||
}
|
}
|
||||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", value_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset());
|
log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", value_sp.get(),
|
||||||
|
(addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"),
|
||||||
|
addr.GetOffset());
|
||||||
return SBAddress(new Address(addr));
|
return SBAddress(new Address(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,9 @@ CommandObjectExpression::CommandOptions::~CommandOptions ()
|
||||||
OptionDefinition
|
OptionDefinition
|
||||||
CommandObjectExpression::CommandOptions::g_option_table[] =
|
CommandObjectExpression::CommandOptions::g_option_table[] =
|
||||||
{
|
{
|
||||||
|
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', required_argument, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
|
||||||
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "dynamic-value", 'd', required_argument, NULL, 0, eArgTypeBoolean, "Upcast the value resulting from the expression to its dynamic type if available."},
|
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "dynamic-value", 'd', required_argument, NULL, 0, eArgTypeBoolean, "Upcast the value resulting from the expression to its dynamic type if available."},
|
||||||
|
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value for running the expression."},
|
||||||
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."},
|
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."},
|
||||||
{ LLDB_OPT_SET_2 , false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
|
{ LLDB_OPT_SET_2 , false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
|
||||||
};
|
};
|
||||||
|
@ -80,8 +82,16 @@ CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &int
|
||||||
//}
|
//}
|
||||||
//break;
|
//break;
|
||||||
|
|
||||||
case 'o':
|
case 'a':
|
||||||
print_object = true;
|
{
|
||||||
|
bool success;
|
||||||
|
bool result;
|
||||||
|
result = Args::StringToBoolean(option_arg, true, &success);
|
||||||
|
if (!success)
|
||||||
|
error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
|
||||||
|
else
|
||||||
|
try_all_threads = result;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -101,6 +111,22 @@ CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &int
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
print_object = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
uint32_t result;
|
||||||
|
result = Args::StringToUInt32(option_arg, 0, 0, &success);
|
||||||
|
if (success)
|
||||||
|
timeout = result;
|
||||||
|
else
|
||||||
|
error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
{
|
{
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -125,6 +151,8 @@ CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpret
|
||||||
unwind_on_error = true;
|
unwind_on_error = true;
|
||||||
show_types = true;
|
show_types = true;
|
||||||
show_summary = true;
|
show_summary = true;
|
||||||
|
try_all_threads = true;
|
||||||
|
timeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OptionDefinition*
|
const OptionDefinition*
|
||||||
|
@ -146,7 +174,13 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete
|
||||||
m_expr_lines ()
|
m_expr_lines ()
|
||||||
{
|
{
|
||||||
SetHelpLong(
|
SetHelpLong(
|
||||||
"Examples: \n\
|
"Timeouts:\n\
|
||||||
|
If the expression can be evaluated statically (without runnning code) then it will be.\n\
|
||||||
|
Otherwise, by default the expression will run on the current thread with a short timeout:\n\
|
||||||
|
currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\
|
||||||
|
and resumed with all threads running. You can use the -a option to disable retrying on all\n\
|
||||||
|
threads. You can use the -t option to set a shorter timeout.\n\
|
||||||
|
Examples: \n\
|
||||||
\n\
|
\n\
|
||||||
expr my_struct->a = my_array[3] \n\
|
expr my_struct->a = my_array[3] \n\
|
||||||
expr -f bin -- (index * 8) + 5 \n\
|
expr -f bin -- (index * 8) + 5 \n\
|
||||||
|
@ -298,12 +332,13 @@ CommandObjectExpression::EvaluateExpression
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(m_command_options.print_object)
|
options.SetCoerceToId(m_command_options.print_object)
|
||||||
.SetUnwindOnError(m_command_options.unwind_on_error)
|
.SetUnwindOnError(m_command_options.unwind_on_error)
|
||||||
.SetKeepInMemory(keep_in_memory)
|
.SetKeepInMemory(keep_in_memory)
|
||||||
.SetUseDynamic(use_dynamic)
|
.SetUseDynamic(use_dynamic)
|
||||||
.SetSingleThreadTimeoutUsec(0);
|
.SetRunOthers(m_command_options.try_all_threads)
|
||||||
|
.SetTimeoutUsec(m_command_options.timeout);
|
||||||
|
|
||||||
exe_results = target->EvaluateExpression (expr,
|
exe_results = target->EvaluateExpression (expr,
|
||||||
m_interpreter.GetExecutionContext().GetFramePtr(),
|
m_interpreter.GetExecutionContext().GetFramePtr(),
|
||||||
|
|
|
@ -55,6 +55,8 @@ public:
|
||||||
bool unwind_on_error;
|
bool unwind_on_error;
|
||||||
bool show_types;
|
bool show_types;
|
||||||
bool show_summary;
|
bool show_summary;
|
||||||
|
uint32_t timeout;
|
||||||
|
bool try_all_threads;
|
||||||
};
|
};
|
||||||
|
|
||||||
CommandObjectExpression (CommandInterpreter &interpreter);
|
CommandObjectExpression (CommandInterpreter &interpreter);
|
||||||
|
|
|
@ -1314,7 +1314,7 @@ protected:
|
||||||
if (command && command[0] != '\0')
|
if (command && command[0] != '\0')
|
||||||
{
|
{
|
||||||
Target *target = exe_ctx.GetTargetPtr();
|
Target *target = exe_ctx.GetTargetPtr();
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
|
|
||||||
options.SetUnwindOnError(true);
|
options.SetUnwindOnError(true);
|
||||||
options.SetUseDynamic(eNoDynamicValues);
|
options.SetUseDynamic(eNoDynamicValues);
|
||||||
|
|
|
@ -1234,11 +1234,12 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use expression evaluation to arrive at the address to watch.
|
// Use expression evaluation to arrive at the address to watch.
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(false)
|
options.SetCoerceToId(false)
|
||||||
.SetUnwindOnError(true)
|
.SetUnwindOnError(true)
|
||||||
.SetKeepInMemory(false)
|
.SetKeepInMemory(false)
|
||||||
.SetSingleThreadTimeoutUsec(0);
|
.SetRunOthers(true)
|
||||||
|
.SetTimeoutUsec(0);
|
||||||
|
|
||||||
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
|
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
|
||||||
frame,
|
frame,
|
||||||
|
|
|
@ -47,7 +47,7 @@ lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
|
||||||
if (!target || !stack_frame)
|
if (!target || !stack_frame)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(false)
|
options.SetCoerceToId(false)
|
||||||
.SetUnwindOnError(true)
|
.SetUnwindOnError(true)
|
||||||
.SetKeepInMemory(true)
|
.SetKeepInMemory(true)
|
||||||
|
@ -85,7 +85,7 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
|
||||||
if (!target || !stack_frame)
|
if (!target || !stack_frame)
|
||||||
return valobj_sp;
|
return valobj_sp;
|
||||||
|
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(false)
|
options.SetCoerceToId(false)
|
||||||
.SetUnwindOnError(true)
|
.SetUnwindOnError(true)
|
||||||
.SetKeepInMemory(true)
|
.SetKeepInMemory(true)
|
||||||
|
@ -122,7 +122,7 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
|
||||||
if (!target || !stack_frame)
|
if (!target || !stack_frame)
|
||||||
return valobj_sp;
|
return valobj_sp;
|
||||||
|
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(false)
|
options.SetCoerceToId(false)
|
||||||
.SetUnwindOnError(true)
|
.SetUnwindOnError(true)
|
||||||
.SetKeepInMemory(true)
|
.SetKeepInMemory(true)
|
||||||
|
@ -459,7 +459,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream&
|
||||||
if (!target || !stack_frame)
|
if (!target || !stack_frame)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(false)
|
options.SetCoerceToId(false)
|
||||||
.SetUnwindOnError(true)
|
.SetUnwindOnError(true)
|
||||||
.SetKeepInMemory(true)
|
.SetKeepInMemory(true)
|
||||||
|
@ -1055,7 +1055,7 @@ lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIn
|
||||||
object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
|
object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
|
||||||
lldb::ValueObjectSP child_sp;
|
lldb::ValueObjectSP child_sp;
|
||||||
m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
|
m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
|
||||||
Target::EvaluateExpressionOptions().SetKeepInMemory(true));
|
EvaluateExpressionOptions().SetKeepInMemory(true));
|
||||||
if (child_sp)
|
if (child_sp)
|
||||||
child_sp->SetName(ConstString(idx_name.GetData()));
|
child_sp->SetName(ConstString(idx_name.GetData()));
|
||||||
return child_sp;
|
return child_sp;
|
||||||
|
|
|
@ -485,13 +485,13 @@ ExecutionResults
|
||||||
ClangFunction::ExecuteFunction(
|
ClangFunction::ExecuteFunction(
|
||||||
ExecutionContext &exe_ctx,
|
ExecutionContext &exe_ctx,
|
||||||
Stream &errors,
|
Stream &errors,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
bool try_all_threads,
|
bool try_all_threads,
|
||||||
Value &results)
|
Value &results)
|
||||||
{
|
{
|
||||||
const bool stop_others = true;
|
const bool stop_others = true;
|
||||||
const bool discard_on_error = true;
|
const bool discard_on_error = true;
|
||||||
return ExecuteFunction (exe_ctx, NULL, errors, stop_others, single_thread_timeout_usec,
|
return ExecuteFunction (exe_ctx, NULL, errors, stop_others, timeout_usec,
|
||||||
try_all_threads, discard_on_error, results);
|
try_all_threads, discard_on_error, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ ClangFunction::ExecuteFunction (
|
||||||
bool stop_others,
|
bool stop_others,
|
||||||
bool try_all_threads,
|
bool try_all_threads,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
Stream &errors,
|
Stream &errors,
|
||||||
lldb::addr_t *this_arg)
|
lldb::addr_t *this_arg)
|
||||||
{
|
{
|
||||||
|
@ -529,7 +529,7 @@ ClangFunction::ExecuteFunction (
|
||||||
stop_others,
|
stop_others,
|
||||||
try_all_threads,
|
try_all_threads,
|
||||||
discard_on_error,
|
discard_on_error,
|
||||||
single_thread_timeout_usec,
|
timeout_usec,
|
||||||
errors);
|
errors);
|
||||||
|
|
||||||
if (exe_ctx.GetProcessPtr())
|
if (exe_ctx.GetProcessPtr())
|
||||||
|
@ -544,7 +544,7 @@ ClangFunction::ExecuteFunction(
|
||||||
lldb::addr_t *args_addr_ptr,
|
lldb::addr_t *args_addr_ptr,
|
||||||
Stream &errors,
|
Stream &errors,
|
||||||
bool stop_others,
|
bool stop_others,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
bool try_all_threads,
|
bool try_all_threads,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
Value &results)
|
Value &results)
|
||||||
|
@ -574,7 +574,7 @@ ClangFunction::ExecuteFunction(
|
||||||
stop_others,
|
stop_others,
|
||||||
try_all_threads,
|
try_all_threads,
|
||||||
discard_on_error,
|
discard_on_error,
|
||||||
single_thread_timeout_usec,
|
timeout_usec,
|
||||||
errors);
|
errors);
|
||||||
|
|
||||||
if (args_addr_ptr != NULL)
|
if (args_addr_ptr != NULL)
|
||||||
|
|
|
@ -544,7 +544,8 @@ ClangUserExpression::Execute (Stream &error_stream,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
|
ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
|
||||||
lldb::ClangExpressionVariableSP &result,
|
lldb::ClangExpressionVariableSP &result,
|
||||||
uint32_t single_thread_timeout_usec)
|
bool run_others,
|
||||||
|
uint32_t timeout_usec)
|
||||||
{
|
{
|
||||||
// The expression log is quite verbose, and if you're just tracking the execution of the
|
// The expression log is quite verbose, and if you're just tracking the execution of the
|
||||||
// expression, it's quite convenient to have these logs come out with the STEP log as well.
|
// expression, it's quite convenient to have these logs come out with the STEP log as well.
|
||||||
|
@ -594,7 +595,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
||||||
stop_others,
|
stop_others,
|
||||||
try_all_threads,
|
try_all_threads,
|
||||||
discard_on_error,
|
discard_on_error,
|
||||||
single_thread_timeout_usec,
|
timeout_usec,
|
||||||
error_stream);
|
error_stream);
|
||||||
|
|
||||||
if (exe_ctx.GetProcessPtr())
|
if (exe_ctx.GetProcessPtr())
|
||||||
|
@ -655,10 +656,21 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
||||||
const char *expr_cstr,
|
const char *expr_cstr,
|
||||||
const char *expr_prefix,
|
const char *expr_prefix,
|
||||||
lldb::ValueObjectSP &result_valobj_sp,
|
lldb::ValueObjectSP &result_valobj_sp,
|
||||||
uint32_t single_thread_timeout_usec)
|
bool run_others,
|
||||||
|
uint32_t timeout_usec)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
return EvaluateWithError (exe_ctx, execution_policy, language, desired_type, discard_on_error, expr_cstr, expr_prefix, result_valobj_sp, error, single_thread_timeout_usec);
|
return EvaluateWithError (exe_ctx,
|
||||||
|
execution_policy,
|
||||||
|
language,
|
||||||
|
desired_type,
|
||||||
|
discard_on_error,
|
||||||
|
expr_cstr,
|
||||||
|
expr_prefix,
|
||||||
|
result_valobj_sp,
|
||||||
|
error,
|
||||||
|
run_others,
|
||||||
|
timeout_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionResults
|
ExecutionResults
|
||||||
|
@ -671,7 +683,8 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
|
||||||
const char *expr_prefix,
|
const char *expr_prefix,
|
||||||
lldb::ValueObjectSP &result_valobj_sp,
|
lldb::ValueObjectSP &result_valobj_sp,
|
||||||
Error &error,
|
Error &error,
|
||||||
uint32_t single_thread_timeout_usec)
|
bool run_others,
|
||||||
|
uint32_t timeout_usec)
|
||||||
{
|
{
|
||||||
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
|
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
|
||||||
|
|
||||||
|
@ -747,7 +760,8 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
|
||||||
discard_on_error,
|
discard_on_error,
|
||||||
user_expression_sp,
|
user_expression_sp,
|
||||||
expr_result,
|
expr_result,
|
||||||
single_thread_timeout_usec);
|
run_others,
|
||||||
|
timeout_usec);
|
||||||
|
|
||||||
if (execution_results != eExecutionCompleted)
|
if (execution_results != eExecutionCompleted)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1308,11 +1308,12 @@ CommandInterpreter::PreprocessCommand (std::string &command)
|
||||||
{
|
{
|
||||||
ValueObjectSP expr_result_valobj_sp;
|
ValueObjectSP expr_result_valobj_sp;
|
||||||
|
|
||||||
Target::EvaluateExpressionOptions options;
|
EvaluateExpressionOptions options;
|
||||||
options.SetCoerceToId(false)
|
options.SetCoerceToId(false)
|
||||||
.SetUnwindOnError(true)
|
.SetUnwindOnError(true)
|
||||||
.SetKeepInMemory(false)
|
.SetKeepInMemory(false)
|
||||||
.SetSingleThreadTimeoutUsec(0);
|
.SetRunOthers(true)
|
||||||
|
.SetTimeoutUsec(0);
|
||||||
|
|
||||||
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
|
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
|
||||||
exe_ctx.GetFramePtr(),
|
exe_ctx.GetFramePtr(),
|
||||||
|
|
|
@ -50,7 +50,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
|
||||||
const bool stop_other_threads = true;
|
const bool stop_other_threads = true;
|
||||||
const bool discard_on_error = true;
|
const bool discard_on_error = true;
|
||||||
const bool try_all_threads = true;
|
const bool try_all_threads = true;
|
||||||
const uint32_t single_thread_timeout_usec = 500000;
|
const uint32_t timeout_usec = 500000;
|
||||||
|
|
||||||
addr_t prot_arg, flags_arg = 0;
|
addr_t prot_arg, flags_arg = 0;
|
||||||
if (prot == eMmapProtNone)
|
if (prot == eMmapProtNone)
|
||||||
|
@ -105,7 +105,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
|
||||||
stop_other_threads,
|
stop_other_threads,
|
||||||
try_all_threads,
|
try_all_threads,
|
||||||
discard_on_error,
|
discard_on_error,
|
||||||
single_thread_timeout_usec,
|
timeout_usec,
|
||||||
error_strm);
|
error_strm);
|
||||||
if (result == eExecutionCompleted)
|
if (result == eExecutionCompleted)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +154,7 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
|
||||||
const bool stop_other_threads = true;
|
const bool stop_other_threads = true;
|
||||||
const bool discard_on_error = true;
|
const bool discard_on_error = true;
|
||||||
const bool try_all_threads = true;
|
const bool try_all_threads = true;
|
||||||
const uint32_t single_thread_timeout_usec = 500000;
|
const uint32_t timeout_usec = 500000;
|
||||||
|
|
||||||
AddressRange munmap_range;
|
AddressRange munmap_range;
|
||||||
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
|
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
|
||||||
|
@ -183,7 +183,7 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
|
||||||
stop_other_threads,
|
stop_other_threads,
|
||||||
try_all_threads,
|
try_all_threads,
|
||||||
discard_on_error,
|
discard_on_error,
|
||||||
single_thread_timeout_usec,
|
timeout_usec,
|
||||||
error_strm);
|
error_strm);
|
||||||
if (result == eExecutionCompleted)
|
if (result == eExecutionCompleted)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4133,9 +4133,9 @@ ExecutionResults
|
||||||
Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
lldb::ThreadPlanSP &thread_plan_sp,
|
lldb::ThreadPlanSP &thread_plan_sp,
|
||||||
bool stop_others,
|
bool stop_others,
|
||||||
bool try_all_threads,
|
bool run_others,
|
||||||
bool discard_on_error,
|
bool discard_on_error,
|
||||||
uint32_t single_thread_timeout_usec,
|
uint32_t timeout_usec,
|
||||||
Stream &errors)
|
Stream &errors)
|
||||||
{
|
{
|
||||||
ExecutionResults return_value = eExecutionSetupError;
|
ExecutionResults return_value = eExecutionSetupError;
|
||||||
|
@ -4260,6 +4260,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
|
|
||||||
bool first_timeout = true;
|
bool first_timeout = true;
|
||||||
bool do_resume = true;
|
bool do_resume = true;
|
||||||
|
const uint64_t default_one_thread_timeout_usec = 250000;
|
||||||
|
uint64_t computed_timeout = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -4298,9 +4300,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
if (stop_state != eStateRunning)
|
if (stop_state != eStateRunning)
|
||||||
{
|
{
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf("Process::RunThreadPlan(): didn't get running event after initial resume, got %s instead.", StateAsCString(stop_state));
|
log->Printf("Process::RunThreadPlan(): didn't get running event after "
|
||||||
|
"initial resume, got %s instead.",
|
||||||
|
StateAsCString(stop_state));
|
||||||
|
|
||||||
errors.Printf("Didn't get running event after initial resume, got %s instead.", StateAsCString(stop_state));
|
errors.Printf("Didn't get running event after initial resume, got %s instead.",
|
||||||
|
StateAsCString(stop_state));
|
||||||
return_value = eExecutionSetupError;
|
return_value = eExecutionSetupError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4313,28 +4318,45 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
// We set the timeout AFTER the resume, since the resume takes some time and we
|
// We set the timeout AFTER the resume, since the resume takes some time and we
|
||||||
// don't want to charge that to the timeout.
|
// don't want to charge that to the timeout.
|
||||||
|
|
||||||
if (single_thread_timeout_usec != 0)
|
if (first_timeout)
|
||||||
|
{
|
||||||
|
if (run_others)
|
||||||
|
{
|
||||||
|
// If we are running all threads then we take half the time to run all threads, bounded by
|
||||||
|
// .25 sec.
|
||||||
|
if (timeout_usec == 0)
|
||||||
|
computed_timeout = default_one_thread_timeout_usec;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
computed_timeout = timeout_usec / 2;
|
||||||
|
if (computed_timeout > default_one_thread_timeout_usec)
|
||||||
|
{
|
||||||
|
computed_timeout = default_one_thread_timeout_usec;
|
||||||
|
}
|
||||||
|
timeout_usec -= computed_timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
computed_timeout = timeout_usec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
computed_timeout = timeout_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (computed_timeout != 0)
|
||||||
{
|
{
|
||||||
// we have a > 0 timeout, let us set it so that we stop after the deadline
|
// we have a > 0 timeout, let us set it so that we stop after the deadline
|
||||||
real_timeout = TimeValue::Now();
|
real_timeout = TimeValue::Now();
|
||||||
real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
|
real_timeout.OffsetWithMicroSeconds(computed_timeout);
|
||||||
|
|
||||||
timeout_ptr = &real_timeout;
|
timeout_ptr = &real_timeout;
|
||||||
}
|
}
|
||||||
else if (first_timeout)
|
|
||||||
{
|
|
||||||
// if we are willing to wait "forever" we still need to have an initial timeout
|
|
||||||
// this timeout is going to induce all threads to run when hit. we do this so that
|
|
||||||
// we can avoid ending locked up because of multithreaded contention issues
|
|
||||||
real_timeout = TimeValue::Now();
|
|
||||||
real_timeout.OffsetWithNanoSeconds(500000000UL);
|
|
||||||
timeout_ptr = &real_timeout;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timeout_ptr = NULL; // if we are in a no-timeout scenario, then we only need a fake timeout the first time through
|
timeout_ptr = NULL;
|
||||||
// at this point in the code, all threads will be running so we are willing to wait forever, and do not
|
|
||||||
// need a timeout
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4471,21 +4493,21 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
// Not really sure what to do if Halt fails here...
|
// Not really sure what to do if Halt fails here...
|
||||||
|
|
||||||
if (log) {
|
if (log) {
|
||||||
if (try_all_threads)
|
if (run_others)
|
||||||
{
|
{
|
||||||
if (first_timeout)
|
if (first_timeout)
|
||||||
log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, "
|
log->Printf ("Process::RunThreadPlan(): Running function with timeout: %lld timed out, "
|
||||||
"trying with all threads enabled.",
|
"trying for %d usec with all threads enabled.",
|
||||||
single_thread_timeout_usec);
|
computed_timeout, timeout_usec);
|
||||||
else
|
else
|
||||||
log->Printf ("Process::RunThreadPlan(): Restarting function with all threads enabled "
|
log->Printf ("Process::RunThreadPlan(): Restarting function with all threads enabled "
|
||||||
"and timeout: %d timed out.",
|
"and timeout: %d timed out, abandoning execution.",
|
||||||
single_thread_timeout_usec);
|
timeout_usec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, "
|
log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, "
|
||||||
"halt and abandoning execution.",
|
"abandoning execution.",
|
||||||
single_thread_timeout_usec);
|
timeout_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error halt_error = Halt();
|
Error halt_error = Halt();
|
||||||
|
@ -4526,7 +4548,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!try_all_threads)
|
if (!run_others)
|
||||||
{
|
{
|
||||||
if (log)
|
if (log)
|
||||||
log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
|
log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
|
||||||
|
|
|
@ -1747,7 +1747,8 @@ Target::EvaluateExpression
|
||||||
expr_cstr,
|
expr_cstr,
|
||||||
prefix,
|
prefix,
|
||||||
result_valobj_sp,
|
result_valobj_sp,
|
||||||
options.GetSingleThreadTimeoutUsec());
|
options.GetRunOthers(),
|
||||||
|
options.GetTimeoutUsec());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
LEVEL = ../../make
|
||||||
|
|
||||||
|
C_SOURCES := wait-a-while.c
|
||||||
|
|
||||||
|
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,94 @@
|
||||||
|
"""
|
||||||
|
Test calling a function that waits a while, and make sure the timeout option to expr works.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import unittest2
|
||||||
|
import lldb
|
||||||
|
import lldbutil
|
||||||
|
from lldbtest import *
|
||||||
|
|
||||||
|
class ExprCommandWithTimeoutsTestCase(TestBase):
|
||||||
|
|
||||||
|
mydir = os.path.join("expression_command", "timeout")
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Call super's setUp().
|
||||||
|
TestBase.setUp(self)
|
||||||
|
|
||||||
|
self.main_source = "wait-a-while.c"
|
||||||
|
self.main_source_spec = lldb.SBFileSpec (self.main_source)
|
||||||
|
|
||||||
|
|
||||||
|
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||||
|
@dsym_test
|
||||||
|
def test_with_dsym(self):
|
||||||
|
"""Test calling std::String member function."""
|
||||||
|
self.buildDsym()
|
||||||
|
self.call_function()
|
||||||
|
|
||||||
|
@dwarf_test
|
||||||
|
def test_with_dwarf(self):
|
||||||
|
"""Test calling std::String member function."""
|
||||||
|
self.buildDsym()
|
||||||
|
self.call_function()
|
||||||
|
|
||||||
|
def call_function(self):
|
||||||
|
"""Test calling function with timeout."""
|
||||||
|
exe_name = "a.out"
|
||||||
|
exe = os.path.join(os.getcwd(), exe_name)
|
||||||
|
|
||||||
|
target = self.dbg.CreateTarget(exe)
|
||||||
|
self.assertTrue(target, VALID_TARGET)
|
||||||
|
|
||||||
|
breakpoint = target.BreakpointCreateBySourceRegex('stop here in main.',self.main_source_spec)
|
||||||
|
self.assertTrue(breakpoint, VALID_BREAKPOINT)
|
||||||
|
self.runCmd("breakpoint list")
|
||||||
|
|
||||||
|
# Launch the process, and do not stop at the entry point.
|
||||||
|
process = target.LaunchSimple(None, None, os.getcwd())
|
||||||
|
|
||||||
|
self.assertTrue(process, PROCESS_IS_VALID)
|
||||||
|
|
||||||
|
# Frame #0 should be on self.step_out_of_malloc.
|
||||||
|
threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
|
||||||
|
|
||||||
|
self.assertTrue(len(threads) == 1)
|
||||||
|
thread = threads[0]
|
||||||
|
|
||||||
|
# First set the timeout too short, and make sure we fail.
|
||||||
|
options = lldb.SBExpressionOptions()
|
||||||
|
options.SetTimeoutUsec(100)
|
||||||
|
options.SetUnwindOnError(True)
|
||||||
|
|
||||||
|
frame = thread.GetFrameAtIndex(0)
|
||||||
|
|
||||||
|
value = frame.EvaluateExpression ("wait_a_while (10000)", options)
|
||||||
|
self.assertTrue (value.IsValid())
|
||||||
|
self.assertTrue (value.GetError().Success() == False)
|
||||||
|
|
||||||
|
# Now do the same thing with the command line command, and make sure it works too.
|
||||||
|
interp = self.dbg.GetCommandInterpreter()
|
||||||
|
|
||||||
|
result = lldb.SBCommandReturnObject()
|
||||||
|
return_value = interp.HandleCommand ("expr -t 100 -u true -- wait_a_while(10000)", result)
|
||||||
|
self.assertTrue (return_value == lldb.eReturnStatusFailed)
|
||||||
|
|
||||||
|
# Okay, now do it again with long enough time outs:
|
||||||
|
|
||||||
|
options.SetTimeoutUsec(1000000)
|
||||||
|
value = frame.EvaluateExpression ("wait_a_while (1000)", options)
|
||||||
|
self.assertTrue(value.IsValid())
|
||||||
|
self.assertTrue (value.GetError().Success() == True)
|
||||||
|
|
||||||
|
# Now do the same thingwith the command line command, and make sure it works too.
|
||||||
|
interp = self.dbg.GetCommandInterpreter()
|
||||||
|
|
||||||
|
result = lldb.SBCommandReturnObject()
|
||||||
|
return_value = interp.HandleCommand ("expr -t 1000000 -u true -- wait_a_while(1000)", result)
|
||||||
|
self.assertTrue(return_value == lldb.eReturnStatusSuccessFinishResult)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import atexit
|
||||||
|
lldb.SBDebugger.Initialize()
|
||||||
|
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
||||||
|
unittest2.main()
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
wait_a_while (useconds_t interval)
|
||||||
|
{
|
||||||
|
int num_times = 0;
|
||||||
|
int return_value = 1;
|
||||||
|
|
||||||
|
struct timeval start_time;
|
||||||
|
gettimeofday(&start_time, NULL);
|
||||||
|
uint64_t target = start_time.tv_sec * 1000000 + start_time.tv_usec + interval;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
num_times++;
|
||||||
|
return_value = usleep (interval);
|
||||||
|
if (return_value != 0)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
interval = target - now.tv_sec * 1000000 + now.tv_usec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return num_times;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
printf ("stop here in main.\n");
|
||||||
|
int num_times = wait_a_while (argc * 1000);
|
||||||
|
printf ("Done, took %d times.\n", num_times);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue