diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/API/SBExpressionOptions.cpp | 142 | ||||
-rw-r--r-- | lldb/source/API/SBFrame.cpp | 30 | ||||
-rw-r--r-- | lldb/source/API/SBValue.cpp | 27 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 45 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.h | 2 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectThread.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectWatchpoint.cpp | 5 | ||||
-rw-r--r-- | lldb/source/Core/CXXFormatterFunctions.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Expression/ClangFunction.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 26 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 5 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 76 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 3 |
14 files changed, 318 insertions, 75 deletions
diff --git a/lldb/source/API/SBExpressionOptions.cpp b/lldb/source/API/SBExpressionOptions.cpp new file mode 100644 index 00000000000..2a4b9f564b2 --- /dev/null +++ b/lldb/source/API/SBExpressionOptions.cpp @@ -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()); +} diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index b94a0ce9267..f89c25b27e1 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -40,6 +40,7 @@ #include "lldb/API/SBDebugger.h" #include "lldb/API/SBValue.h" #include "lldb/API/SBAddress.h" +#include "lldb/API/SBExpressionOptions.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBSymbolContext.h" #include "lldb/API/SBThread.h" @@ -1040,8 +1041,11 @@ SBFrame::EvaluateExpression (const char *expr) Target *target = exe_ctx.GetTargetPtr(); if (frame && target) { - lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); - result = EvaluateExpression (expr, use_dynamic); + SBExpressionOptions options; + lldb::DynamicValueType fetch_dynamic_value = frame->CalculateTarget()->GetPreferDynamicValue(); + options.SetUseDynamic (fetch_dynamic_value); + options.SetUnwindOnError (true); + return EvaluateExpression (expr, options); } return result; } @@ -1049,12 +1053,24 @@ SBFrame::EvaluateExpression (const char *expr) SBValue 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 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 expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1080,16 +1096,12 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna StreamString frame_description; frame->DumpUsingSettingsFormat (&frame_description); 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 - Target::EvaluateExpressionOptions options; - options.SetUnwindOnError(unwind_on_error) - .SetUseDynamic(fetch_dynamic_value); - exe_results = target->EvaluateExpression (expr, frame, expr_value_sp, - options); + options.ref()); expr_result.SetSP(expr_value_sp); #ifdef LLDB_CONFIGURATION_DEBUG Host::SetCrashDescription (NULL); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 913a447aba5..0aa01a6c9cc 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -40,11 +40,12 @@ #include "lldb/Target/Target.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/SBTarget.h" #include "lldb/API/SBThread.h" -#include "lldb/API/SBFrame.h" -#include "lldb/API/SBDebugger.h" using namespace lldb; using namespace lldb_private; @@ -694,9 +695,12 @@ SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) if (log) { 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 - log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", + value_sp.get()); } return sb_value; } @@ -715,6 +719,14 @@ SBValue::Cast (SBType type) lldb::SBValue 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)); lldb::SBValue sb_value; lldb::ValueObjectSP value_sp(GetSP()); @@ -734,12 +746,11 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression) Target* target = exe_ctx.GetTargetPtr(); if (target) { - Target::EvaluateExpressionOptions options; options.SetKeepInMemory(true); target->EvaluateExpression (expression, exe_ctx.GetFramePtr(), new_value_sp, - options); + options.ref()); if (new_value_sp) { new_value_sp->SetName(ConstString(name)); @@ -1617,7 +1628,9 @@ SBValue::GetAddress() } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 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)); } diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 23c9dc10373..ee053608e7c 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -50,7 +50,9 @@ CommandObjectExpression::CommandOptions::~CommandOptions () OptionDefinition 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, "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_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; - case 'o': - print_object = true; + case 'a': + { + 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; case 'd': @@ -101,6 +111,22 @@ CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &int } 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': { bool success; @@ -125,6 +151,8 @@ CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpret unwind_on_error = true; show_types = true; show_summary = true; + try_all_threads = true; + timeout = 0; } const OptionDefinition* @@ -146,7 +174,13 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete m_expr_lines () { 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\ expr my_struct->a = my_array[3] \n\ expr -f bin -- (index * 8) + 5 \n\ @@ -298,12 +332,13 @@ CommandObjectExpression::EvaluateExpression break; } - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(m_command_options.print_object) .SetUnwindOnError(m_command_options.unwind_on_error) .SetKeepInMemory(keep_in_memory) .SetUseDynamic(use_dynamic) - .SetSingleThreadTimeoutUsec(0); + .SetRunOthers(m_command_options.try_all_threads) + .SetTimeoutUsec(m_command_options.timeout); exe_results = target->EvaluateExpression (expr, m_interpreter.GetExecutionContext().GetFramePtr(), diff --git a/lldb/source/Commands/CommandObjectExpression.h b/lldb/source/Commands/CommandObjectExpression.h index 7c15aa1da83..4ccadfcd8c1 100644 --- a/lldb/source/Commands/CommandObjectExpression.h +++ b/lldb/source/Commands/CommandObjectExpression.h @@ -55,6 +55,8 @@ public: bool unwind_on_error; bool show_types; bool show_summary; + uint32_t timeout; + bool try_all_threads; }; CommandObjectExpression (CommandInterpreter &interpreter); diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 8c2be3792e7..0547d38fe4d 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -1314,7 +1314,7 @@ protected: if (command && command[0] != '\0') { Target *target = exe_ctx.GetTargetPtr(); - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetUseDynamic(eNoDynamicValues); diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 8a74471914f..63275f9d303 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -1234,11 +1234,12 @@ protected: } // Use expression evaluation to arrive at the address to watch. - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(false) .SetUnwindOnError(true) .SetKeepInMemory(false) - .SetSingleThreadTimeoutUsec(0); + .SetRunOthers(true) + .SetTimeoutUsec(0); ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), frame, diff --git a/lldb/source/Core/CXXFormatterFunctions.cpp b/lldb/source/Core/CXXFormatterFunctions.cpp index d8b929e2fe9..67f769805ea 100644 --- a/lldb/source/Core/CXXFormatterFunctions.cpp +++ b/lldb/source/Core/CXXFormatterFunctions.cpp @@ -47,7 +47,7 @@ lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj, if (!target || !stack_frame) return false; - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(false) .SetUnwindOnError(true) .SetKeepInMemory(true) @@ -85,7 +85,7 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj, if (!target || !stack_frame) return valobj_sp; - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(false) .SetUnwindOnError(true) .SetKeepInMemory(true) @@ -122,7 +122,7 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj, if (!target || !stack_frame) return valobj_sp; - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(false) .SetUnwindOnError(true) .SetKeepInMemory(true) @@ -459,7 +459,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& if (!target || !stack_frame) return false; - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(false) .SetUnwindOnError(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()); lldb::ValueObjectSP 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) child_sp->SetName(ConstString(idx_name.GetData())); return child_sp; diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp index 62e4e8a8903..1909dc2c848 100644 --- a/lldb/source/Expression/ClangFunction.cpp +++ b/lldb/source/Expression/ClangFunction.cpp @@ -485,13 +485,13 @@ ExecutionResults ClangFunction::ExecuteFunction( ExecutionContext &exe_ctx, Stream &errors, - uint32_t single_thread_timeout_usec, + uint32_t timeout_usec, bool try_all_threads, Value &results) { const bool stop_others = 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); } @@ -504,7 +504,7 @@ ClangFunction::ExecuteFunction ( bool stop_others, bool try_all_threads, bool discard_on_error, - uint32_t single_thread_timeout_usec, + uint32_t timeout_usec, Stream &errors, lldb::addr_t *this_arg) { @@ -529,7 +529,7 @@ ClangFunction::ExecuteFunction ( stop_others, try_all_threads, discard_on_error, - single_thread_timeout_usec, + timeout_usec, errors); if (exe_ctx.GetProcessPtr()) @@ -544,7 +544,7 @@ ClangFunction::ExecuteFunction( lldb::addr_t *args_addr_ptr, Stream &errors, bool stop_others, - uint32_t single_thread_timeout_usec, + uint32_t timeout_usec, bool try_all_threads, bool discard_on_error, Value &results) @@ -574,7 +574,7 @@ ClangFunction::ExecuteFunction( stop_others, try_all_threads, discard_on_error, - single_thread_timeout_usec, + timeout_usec, errors); if (args_addr_ptr != NULL) diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index c037d0238f9..450728272e6 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -544,7 +544,8 @@ ClangUserExpression::Execute (Stream &error_stream, bool discard_on_error, ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, 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 // 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, try_all_threads, discard_on_error, - single_thread_timeout_usec, + timeout_usec, error_stream); if (exe_ctx.GetProcessPtr()) @@ -655,10 +656,21 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, - uint32_t single_thread_timeout_usec) + bool run_others, + uint32_t timeout_usec) { 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 @@ -671,7 +683,8 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, 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)); @@ -747,7 +760,8 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx, discard_on_error, user_expression_sp, expr_result, - single_thread_timeout_usec); + run_others, + timeout_usec); if (execution_results != eExecutionCompleted) { diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 453004d860e..461f82167fe 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -1308,11 +1308,12 @@ CommandInterpreter::PreprocessCommand (std::string &command) { ValueObjectSP expr_result_valobj_sp; - Target::EvaluateExpressionOptions options; + EvaluateExpressionOptions options; options.SetCoerceToId(false) .SetUnwindOnError(true) .SetKeepInMemory(false) - .SetSingleThreadTimeoutUsec(0); + .SetRunOthers(true) + .SetTimeoutUsec(0); ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), exe_ctx.GetFramePtr(), diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 4d634f421e7..040058b952f 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -50,7 +50,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, const bool stop_other_threads = true; const bool discard_on_error = 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; if (prot == eMmapProtNone) @@ -105,7 +105,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, stop_other_threads, try_all_threads, discard_on_error, - single_thread_timeout_usec, + timeout_usec, error_strm); if (result == eExecutionCompleted) { @@ -154,7 +154,7 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, const bool stop_other_threads = true; const bool discard_on_error = true; const bool try_all_threads = true; - const uint32_t single_thread_timeout_usec = 500000; + const uint32_t timeout_usec = 500000; AddressRange 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, try_all_threads, discard_on_error, - single_thread_timeout_usec, + timeout_usec, error_strm); if (result == eExecutionCompleted) { diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 3b37796f8d1..e77a898e614 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4133,9 +4133,9 @@ ExecutionResults Process::RunThreadPlan (ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, bool stop_others, - bool try_all_threads, + bool run_others, bool discard_on_error, - uint32_t single_thread_timeout_usec, + uint32_t timeout_usec, Stream &errors) { ExecutionResults return_value = eExecutionSetupError; @@ -4260,6 +4260,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, bool first_timeout = true; bool do_resume = true; + const uint64_t default_one_thread_timeout_usec = 250000; + uint64_t computed_timeout = 0; while (1) { @@ -4298,9 +4300,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (stop_state != eStateRunning) { 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; 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 // don't want to charge that to the timeout. - if (single_thread_timeout_usec != 0) + if (first_timeout) { - // we have a > 0 timeout, let us set it so that we stop after the deadline - real_timeout = TimeValue::Now(); - real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec); - - timeout_ptr = &real_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; } - else if (first_timeout) + + if (computed_timeout != 0) { - // 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 + // we have a > 0 timeout, let us set it so that we stop after the deadline real_timeout = TimeValue::Now(); - real_timeout.OffsetWithNanoSeconds(500000000UL); + real_timeout.OffsetWithMicroSeconds(computed_timeout); + timeout_ptr = &real_timeout; } else { - timeout_ptr = NULL; // if we are in a no-timeout scenario, then we only need a fake timeout the first time through - // at this point in the code, all threads will be running so we are willing to wait forever, and do not - // need a timeout + timeout_ptr = NULL; } } else @@ -4471,21 +4493,21 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // Not really sure what to do if Halt fails here... if (log) { - if (try_all_threads) + if (run_others) { if (first_timeout) - log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, " - "trying with all threads enabled.", - single_thread_timeout_usec); + log->Printf ("Process::RunThreadPlan(): Running function with timeout: %lld timed out, " + "trying for %d usec with all threads enabled.", + computed_timeout, timeout_usec); else log->Printf ("Process::RunThreadPlan(): Restarting function with all threads enabled " - "and timeout: %d timed out.", - single_thread_timeout_usec); + "and timeout: %d timed out, abandoning execution.", + timeout_usec); } else log->Printf ("Process::RunThreadPlan(): Running function with timeout: %d timed out, " - "halt and abandoning execution.", - single_thread_timeout_usec); + "abandoning execution.", + timeout_usec); } Error halt_error = Halt(); @@ -4526,7 +4548,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, break; } - if (!try_all_threads) + if (!run_others) { if (log) log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting."); diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 8a896875498..0dd34631da7 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1747,7 +1747,8 @@ Target::EvaluateExpression expr_cstr, prefix, result_valobj_sp, - options.GetSingleThreadTimeoutUsec()); + options.GetRunOthers(), + options.GetTimeoutUsec()); } } |