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>


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@166062 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 23c9dc1..ee05360 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -50,7 +50,9 @@
 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 @@
       //}
       //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 @@
         }
         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 @@
     unwind_on_error = true;
     show_types = true;
     show_summary = true;
+    try_all_threads = true;
+    timeout = 0;
 }
 
 const OptionDefinition*
@@ -146,7 +174,13 @@
     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 @@
             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/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h
index 7c15aa1..4ccadfc 100644
--- a/source/Commands/CommandObjectExpression.h
+++ b/source/Commands/CommandObjectExpression.h
@@ -55,6 +55,8 @@
         bool        unwind_on_error;
         bool        show_types;
         bool        show_summary;
+        uint32_t    timeout;
+        bool        try_all_threads;
     };
 
     CommandObjectExpression (CommandInterpreter &interpreter);
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 8c2be37..0547d38 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -1314,7 +1314,7 @@
         if (command && command[0] != '\0')
         {
             Target *target = exe_ctx.GetTargetPtr();
-            Target::EvaluateExpressionOptions options;
+            EvaluateExpressionOptions options;
 
             options.SetUnwindOnError(true);
             options.SetUseDynamic(eNoDynamicValues);
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index 8a74471..63275f9 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -1234,11 +1234,12 @@
         }
 
         // 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,