summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h2
-rw-r--r--lldb/include/lldb/Expression/ClangFunction.h12
-rw-r--r--lldb/include/lldb/Symbol/TaggedASTType.h43
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj10
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp207
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp19
-rw-r--r--lldb/source/Expression/ClangFunction.cpp184
7 files changed, 323 insertions, 154 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
index 366067ff859..abe21710e59 100644
--- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
+++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -21,7 +21,7 @@
// Project includes
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
-#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/TaggedASTType.h"
namespace llvm {
class Value;
diff --git a/lldb/include/lldb/Expression/ClangFunction.h b/lldb/include/lldb/Expression/ClangFunction.h
index f0555bc916a..1ee55a79c81 100644
--- a/lldb/include/lldb/Expression/ClangFunction.h
+++ b/lldb/include/lldb/Expression/ClangFunction.h
@@ -91,6 +91,9 @@ public:
// This variant writes down function_address and arg_value.
bool WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors);
+ // Run a function at a particular address, with a given address passed on the stack.
+ static ExecutionResults ExecuteFunction (ExecutionContext &exe_ctx, lldb::addr_t function_address, lldb::addr_t &void_arg, bool stop_others, bool try_all_threads, uint32_t single_thread_timeout_usec, Stream &errors);
+
//------------------------------------------------------------------
/// Run the function this ClangFunction was created with.
///
@@ -198,7 +201,14 @@ public:
ExecutionResults ExecuteFunction(ExecutionContext &context, lldb::addr_t *args_addr_ptr, Stream &errors, bool stop_others, uint32_t single_thread_timeout_usec, bool try_all_threads, Value &results);
ExecutionResults ExecuteFunctionWithABI(ExecutionContext &context, Stream &errors, Value &results);
- ThreadPlan *GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors, bool stop_others, bool discard_on_error = true);
+ static ThreadPlan *
+ GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t func_addr, lldb::addr_t &args_addr_ref, Stream &errors, bool stop_others, bool discard_on_error = true);
+
+ ThreadPlan *
+ GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors, bool stop_others, bool discard_on_error = true)
+ {
+ return ClangFunction::GetThreadPlanToCallFunction (exc_context, m_wrapper_function_addr, args_addr_ref, errors, stop_others, discard_on_error);
+ }
bool FetchFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr, Value &ret_value);
void DeallocateFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr);
diff --git a/lldb/include/lldb/Symbol/TaggedASTType.h b/lldb/include/lldb/Symbol/TaggedASTType.h
new file mode 100644
index 00000000000..6a5061dbf05
--- /dev/null
+++ b/lldb/include/lldb/Symbol/TaggedASTType.h
@@ -0,0 +1,43 @@
+//===-- TaggedASTType.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TaggedASTType_h_
+#define liblldb_TaggedASTType_h_
+
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private
+{
+
+// For cases in which there are multiple classes of types that are not
+// interchangeable, to allow static type checking.
+template <unsigned int C> class TaggedASTType : public ClangASTType
+{
+public:
+ TaggedASTType (void *type, clang::ASTContext *ast_context) :
+ ClangASTType(type, ast_context) { }
+
+ TaggedASTType (const TaggedASTType<C> &tw) :
+ ClangASTType(tw) { }
+
+ TaggedASTType () :
+ ClangASTType() { }
+
+ ~TaggedASTType() { }
+
+ TaggedASTType<C> &operator= (const TaggedASTType<C> &tw)
+ {
+ ClangASTType::operator= (tw);
+ return *this;
+ }
+};
+
+}
+
+#endif
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 6c8863448c2..7de6d01eef2 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -331,6 +331,7 @@
49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 49307AB111DEA4F20081F992 /* IRForTarget.h */; };
49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; };
49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; };
+ 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; };
49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; };
49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; };
49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */; };
@@ -906,6 +907,7 @@
499F381F11A5B3F300F5CE02 /* CommandObjectArgs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectArgs.cpp; path = source/Commands/CommandObjectArgs.cpp; sourceTree = "<group>"; };
49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangResultSynthesizer.cpp; path = source/Expression/ClangResultSynthesizer.cpp; sourceTree = "<group>"; };
49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangResultSynthesizer.h; path = include/lldb/Expression/ClangResultSynthesizer.h; sourceTree = "<group>"; };
+ 49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = "<group>"; };
49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = "<group>"; };
49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = "<group>"; };
49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = "<group>"; };
@@ -1700,6 +1702,7 @@
26BC7C6310F1B6E900F91463 /* SymbolVendor.h */,
26BC7C6410F1B6E900F91463 /* Symtab.h */,
26BC7F1F10F1B8EC00F91463 /* Symtab.cpp */,
+ 49BB309511F79450001A4197 /* TaggedASTType.h */,
26BC7C6510F1B6E900F91463 /* Type.h */,
26BC7F2010F1B8EC00F91463 /* Type.cpp */,
26BC7C6610F1B6E900F91463 /* TypeList.h */,
@@ -2202,6 +2205,7 @@
4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */,
26D27CA011ED3A4E0024D721 /* ELFHeader.h in Headers */,
49E45FAA11F660DC008F7B28 /* ClangASTType.h in Headers */,
+ 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2764,7 +2768,7 @@
"$(LLVM_BUILD_DIR)",
);
LLVM_BUILD_DIR = "$(SRCROOT)/llvm";
- LLVM_CONFIGURATION = Release;
+ LLVM_CONFIGURATION = "Debug+Asserts";
OTHER_CFLAGS = (
"-DFOR_DYLD=0",
"-DSUPPORT_REMOTE_UNWINDING",
@@ -2817,7 +2821,7 @@
"$(LLVM_BUILD_DIR)",
);
LLVM_BUILD_DIR = "$(SRCROOT)/llvm";
- LLVM_CONFIGURATION = Release;
+ LLVM_CONFIGURATION = "Debug+Asserts";
OTHER_CFLAGS = (
"-DFOR_DYLD=0",
"-DSUPPORT_REMOTE_UNWINDING",
@@ -2927,7 +2931,7 @@
"$(LLVM_BUILD_DIR)",
);
LLVM_BUILD_DIR = "$(DERIVED_FILE_DIR)/llvm.build";
- LLVM_CONFIGURATION = Release;
+ LLVM_CONFIGURATION = "Debug+Asserts";
OTHER_CFLAGS = (
"-DFOR_DYLD=0",
"-DSUPPORT_REMOTE_UNWINDING",
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 4135ed82cc0..303ca17cc56 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -12,26 +12,25 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-
// Project includes
-#include "lldb/Core/Debugger.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/InputReader.h"
#include "lldb/Expression/ClangExpression.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/CLangFunction.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Host/Host.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
@@ -256,6 +255,10 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
bool success;
bool canInterpret = false;
+ clang::ASTContext *ast_context = clang_expr.GetASTContext ();
+ Value expr_result;
+ Error expr_error;
+
if (m_options.use_ir)
{
canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes);
@@ -306,21 +309,56 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
return false;
}
- Error err;
lldb::addr_t struct_address;
- if (!expr_decl_map.Materialize(&m_exe_ctx, struct_address, err))
+ if (!expr_decl_map.Materialize(&m_exe_ctx, struct_address, expr_error))
{
- error_stream.Printf ("Couldn't materialize struct: %s\n", err.AsCString("unknown error"));
+ error_stream.Printf ("Couldn't materialize struct: %s\n", expr_error.AsCString("unknown error"));
return false;
}
- log->Printf("Function address : 0x%llx", (uint64_t)function_address);
- log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
+ if (log)
+ {
+ log->Printf("Function address : 0x%llx", (uint64_t)function_address);
+ log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
+ }
+
+ ClangFunction::ExecutionResults execution_result =
+ ClangFunction::ExecuteFunction (m_exe_ctx, function_address, struct_address, true, true, 10000, error_stream);
+
+ if (execution_result != ClangFunction::eExecutionCompleted)
+ {
+ const char *result_name;
+
+ switch (execution_result)
+ {
+ case ClangFunction::eExecutionCompleted:
+ result_name = "eExecutionCompleted";
+ break;
+ case ClangFunction::eExecutionDiscarded:
+ result_name = "eExecutionDiscarded";
+ break;
+ case ClangFunction::eExecutionInterrupted:
+ result_name = "eExecutionInterrupted";
+ break;
+ case ClangFunction::eExecutionSetupError:
+ result_name = "eExecutionSetupError";
+ break;
+ case ClangFunction::eExecutionTimedOut:
+ result_name = "eExecutionTimedOut";
+ break;
+ }
+
+ error_stream.Printf ("Couldn't execute function; result was %s\n", result_name);
+ return false;
+ }
+
+ if (!expr_decl_map.Dematerialize(&m_exe_ctx, expr_result, expr_error))
+ {
+ error_stream.Printf ("Couldn't dematerialize struct: %s\n", expr_error.AsCString("unknown error"));
+ return false;
+ }
}
-
- return true;
-
}
else
{
@@ -356,9 +394,6 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
log->PutCString (stream_string.GetString ().c_str ());
}
- clang::ASTContext *ast_context = clang_expr.GetASTContext ();
- Value expr_result;
- Error expr_error;
success = dwarf_expr.Evaluate (&m_exe_ctx, ast_context, NULL, expr_result, &expr_error);
if (!success)
@@ -366,81 +401,77 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
error_stream.Printf ("error: couldn't evaluate DWARF expression: %s\n", expr_error.AsCString ());
return false;
}
+ }
- ///////////////////////////////////////
- // Interpret the result and print it
- //
-
- lldb::Format format = m_options.format;
-
- // Resolve any values that are possible
- expr_result.ResolveValue (&m_exe_ctx, ast_context);
-
- if (expr_result.GetContextType () == Value::eContextTypeInvalid &&
- expr_result.GetValueType () == Value::eValueTypeScalar &&
- format == eFormatDefault)
- {
- // The expression result is just a scalar with no special formatting
- expr_result.GetScalar ().GetValue (&output_stream, m_options.show_types);
- output_stream.EOL ();
- return true;
- }
-
- // The expression result is more complext and requires special handling
- DataExtractor data;
- expr_error = expr_result.GetValueAsData (&m_exe_ctx, ast_context, data, 0);
-
- if (!expr_error.Success ())
- {
- error_stream.Printf ("error: couldn't resolve result value: %s\n", expr_error.AsCString ());
- return false;
- }
-
- if (format == eFormatDefault)
- format = expr_result.GetValueDefaultFormat ();
-
- void *clang_type = expr_result.GetValueOpaqueClangQualType ();
-
- if (clang_type)
- {
- if (m_options.show_types)
- {
- ConstString type_name(ClangASTType::GetClangTypeName (clang_type));
- if (type_name)
- output_stream.Printf("(%s) ", type_name.AsCString("<invalid>"));
- }
-
- ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to
- clang_type, // The opaque clang type we want to dump that value of
- &m_exe_ctx, // The execution context for memory and variable access
- &output_stream, // Stream to dump to
- format, // Format to use when dumping
- data, // A buffer containing the bytes for the clang type
- 0, // Byte offset within "data" where value is
- data.GetByteSize (), // Size in bytes of the value we are dumping
- 0, // Bitfield bit size
- 0, // Bitfield bit offset
- m_options.show_types, // Show types?
- m_options.show_summary, // Show summary?
- m_options.debug, // Debug logging output?
- UINT32_MAX); // Depth to dump in case this is an aggregate type
- }
- else
- {
- data.Dump (&output_stream, // Stream to dump to
- 0, // Byte offset within "data"
- format, // Format to use when dumping
- data.GetByteSize (), // Size in bytes of each item we are dumping
- 1, // Number of items to dump
- UINT32_MAX, // Number of items per line
- LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
- 0, // Bitfield bit size
- 0); // Bitfield bit offset
- }
- output_stream.EOL();
-
+ ///////////////////////////////////////
+ // Interpret the result and print it
+ //
+
+ lldb::Format format = m_options.format;
+
+ // Resolve any values that are possible
+ expr_result.ResolveValue (&m_exe_ctx, ast_context);
+
+ if (expr_result.GetContextType () == Value::eContextTypeInvalid &&
+ expr_result.GetValueType () == Value::eValueTypeScalar &&
+ format == eFormatDefault)
+ {
+ // The expression result is just a scalar with no special formatting
+ expr_result.GetScalar ().GetValue (&output_stream, m_options.show_types);
+ output_stream.EOL ();
return true;
}
+
+ // The expression result is more complext and requires special handling
+ DataExtractor data;
+ expr_error = expr_result.GetValueAsData (&m_exe_ctx, ast_context, data, 0);
+
+ if (!expr_error.Success ())
+ {
+ error_stream.Printf ("error: couldn't resolve result value: %s\n", expr_error.AsCString ());
+ return false;
+ }
+
+ if (format == eFormatDefault)
+ format = expr_result.GetValueDefaultFormat ();
+
+ void *clang_type = expr_result.GetValueOpaqueClangQualType ();
+
+ if (clang_type)
+ {
+ if (m_options.show_types)
+ output_stream.PutCString(ClangASTType::GetClangTypeName (clang_type).GetCString());
+
+ ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to
+ clang_type, // The opaque clang type we want to dump that value of
+ &m_exe_ctx, // The execution context for memory and variable access
+ &output_stream, // Stream to dump to
+ format, // Format to use when dumping
+ data, // A buffer containing the bytes for the clang type
+ 0, // Byte offset within "data" where value is
+ data.GetByteSize (), // Size in bytes of the value we are dumping
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ m_options.show_types, // Show types?
+ m_options.show_summary, // Show summary?
+ m_options.debug, // Debug logging output?
+ UINT32_MAX); // Depth to dump in case this is an aggregate type
+ }
+ else
+ {
+ data.Dump (&output_stream, // Stream to dump to
+ 0, // Byte offset within "data"
+ format, // Format to use when dumping
+ data.GetByteSize (), // Size in bytes of each item we are dumping
+ 1, // Number of items to dump
+ UINT32_MAX, // Number of items per line
+ LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
+ 0, // Bitfield bit size
+ 0); // Bitfield bit offset
+ }
+ output_stream.EOL();
+
+ return true;
}
bool
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 54bfad5772a..1a9e57f0aa7 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -295,8 +295,10 @@ ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
iter->m_parser_type.GetOpaqueQualType()),
context);
- result_value->SetContext(Value::eContextTypeOpaqueClangQualType,
- copied_type.GetOpaqueQualType());
+ result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType());
+
+ result_value->SetValueType(Value::eValueTypeLoadAddress);
+ result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset;
}
continue;
@@ -330,10 +332,8 @@ ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
return false;
}
- log->Printf("%s %s with type %p",
- (dematerialize ? "Dematerializing" : "Materializing"),
- name,
- type.GetOpaqueQualType());
+ if (log)
+ log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
var,
@@ -349,8 +349,7 @@ ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
{
lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
- size_t bit_size = ClangASTContext::GetTypeBitSize (type.GetASTContext(),
- type.GetOpaqueQualType());
+ size_t bit_size = ClangASTContext::GetTypeBitSize(type.GetASTContext(), type.GetOpaqueQualType());
size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
DataBufferHeap data;
@@ -493,9 +492,7 @@ ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
if (type->GetASTContext() == var->GetType()->GetClangAST())
{
- if (!ClangASTContext::AreTypesSame(type->GetASTContext(),
- type->GetOpaqueQualType(),
- var->GetType()->GetOpaqueClangQualType()))
+ if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
return NULL;
}
else
diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp
index 7e1160dfbef..b5a580c5935 100644
--- a/lldb/source/Expression/ClangFunction.cpp
+++ b/lldb/source/Expression/ClangFunction.cpp
@@ -32,6 +32,7 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
@@ -385,7 +386,7 @@ ClangFunction::InsertFunction (ExecutionContext &exc_context, lldb::addr_t &args
}
ThreadPlan *
-ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error)
+ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t func_addr, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error)
{
// FIXME: Use the errors Stream for better error reporting.
@@ -399,7 +400,7 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb:
// Okay, now run the function:
- Address wrapper_address (NULL, m_wrapper_function_addr);
+ Address wrapper_address (NULL, func_addr);
ThreadPlan *new_plan = new ThreadPlanCallFunction (*exc_context.thread,
wrapper_address,
args_addr,
@@ -473,86 +474,68 @@ ClangFunction::ExecuteFunction(
return ExecuteFunction (exc_context, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
}
-ClangFunction::ExecutionResults
-ClangFunction::ExecuteFunction(
+// This is the static function
+ClangFunction::ExecutionResults
+ClangFunction::ExecuteFunction (
ExecutionContext &exc_context,
- lldb::addr_t *args_addr_ptr,
- Stream &errors,
- bool stop_others,
- uint32_t single_thread_timeout_usec,
- bool try_all_threads,
- Value &results)
+ lldb::addr_t function_address,
+ lldb::addr_t &void_arg,
+ bool stop_others,
+ bool try_all_threads,
+ uint32_t single_thread_timeout_usec,
+ Stream &errors)
{
- using namespace clang;
- ExecutionResults return_value = eExecutionSetupError;
- Process *process = exc_context.process;
-
- lldb::addr_t args_addr;
-
- if (args_addr_ptr != NULL)
- args_addr = *args_addr_ptr;
- else
- args_addr = LLDB_INVALID_ADDRESS;
-
- if (CompileFunction(errors) != 0)
- return eExecutionSetupError;
-
- if (args_addr == LLDB_INVALID_ADDRESS)
- {
- if (!InsertFunction(exc_context, args_addr, errors))
- return eExecutionSetupError;
- }
-
+ ClangFunction::ExecutionResults return_value = eExecutionSetupError;
- lldb::ThreadPlanSP call_plan_sp(GetThreadPlanToCallFunction(exc_context, args_addr, errors, stop_others, false));
+ lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exc_context, function_address, void_arg, errors, stop_others, false));
ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
- if (args_addr_ptr != NULL)
- *args_addr_ptr = args_addr;
-
if (call_plan_sp == NULL)
- return return_value;
-
+ return eExecutionSetupError;
+
call_plan_sp->SetPrivate(true);
exc_context.thread->QueueThreadPlan(call_plan_sp, true);
-
+
// We need to call the function synchronously, so spin waiting for it to return.
// If we get interrupted while executing, we're going to lose our context, and
// won't be able to gather the result at this point.
-
+
TimeValue* timeout_ptr = NULL;
TimeValue real_timeout;
+
if (single_thread_timeout_usec != 0)
{
real_timeout = TimeValue::Now();
real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
timeout_ptr = &real_timeout;
}
- process->Resume ();
-
+
+ exc_context.process->Resume ();
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
while (1)
{
lldb::EventSP event_sp;
-
+
// Now wait for the process to stop again:
// FIXME: Probably want a time out.
- lldb::StateType stop_state = process->WaitForStateChangedEvents (timeout_ptr, event_sp);
+ lldb::StateType stop_state = exc_context.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
+
if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
{
// Right now this is the only way to tell we've timed out...
// We should interrupt the process here...
// Not really sure what to do if Halt fails here...
- Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
if (log)
log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec);
-
- if (process->Halt().Success())
+
+ if (exc_context.process->Halt().Success())
{
timeout_ptr = NULL;
- stop_state = process->WaitForStateChangedEvents (timeout_ptr, event_sp);
+ stop_state = exc_context.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
if (stop_state == lldb::eStateInvalid)
{
errors.Printf ("Got an invalid stop state after halt.");
@@ -574,10 +557,9 @@ ClangFunction::ExecuteFunction(
return_value = eExecutionCompleted;
break;
}
-
-
+
call_plan_ptr->SetStopOthers (false);
- process->Resume();
+ exc_context.process->Resume();
continue;
}
else
@@ -586,7 +568,7 @@ ClangFunction::ExecuteFunction(
}
if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
continue;
-
+
if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get()))
{
return_value = eExecutionCompleted;
@@ -599,12 +581,114 @@ ClangFunction::ExecuteFunction(
}
else
{
+ if (log)
+ {
+ StreamString s;
+ event_sp->Dump (&s);
+ StreamString ts;
+
+ const char *event_explanation;
+
+ do
+ {
+ const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
+
+ if (!event_data)
+ {
+ event_explanation = "<no event data>";
+ break;
+ }
+
+ Process *process = event_data->GetProcessSP().get();
+
+ if (!process)
+ {
+ event_explanation = "<no process>";
+ break;
+ }
+
+ ThreadList &thread_list = process->GetThreadList();
+
+ uint32_t num_threads = thread_list.GetSize();
+ uint32_t thread_index;
+
+ ts.Printf("<%u threads> ", num_threads);
+
+ for (thread_index = 0;
+ thread_index < num_threads;
+ ++thread_index)
+ {
+ Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
+
+ if (!thread)
+ {
+ ts.Printf("<?> ");
+ continue;
+ }
+
+ Thread::StopInfo stop_info;
+ thread->GetStopInfo(&stop_info);
+
+ ts.Printf("<");
+ RegisterContext *register_context = thread->GetRegisterContext();
+
+ if (register_context)
+ ts.Printf("[ip 0x%llx] ", register_context->GetPC());
+ else
+ ts.Printf("[ip unknown] ");
+
+ stop_info.Dump(&ts);
+ ts.Printf(">");
+ }
+
+ event_explanation = ts.GetData();
+ } while (0);
+
+ log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
+ }
+
return_value = eExecutionInterrupted;
break;
}
+ }
+
+ return return_value;
+}
+ClangFunction::ExecutionResults
+ClangFunction::ExecuteFunction(
+ ExecutionContext &exc_context,
+ lldb::addr_t *args_addr_ptr,
+ Stream &errors,
+ bool stop_others,
+ uint32_t single_thread_timeout_usec,
+ bool try_all_threads,
+ Value &results)
+{
+ using namespace clang;
+ ExecutionResults return_value = eExecutionSetupError;
+
+ lldb::addr_t args_addr;
+
+ if (args_addr_ptr != NULL)
+ args_addr = *args_addr_ptr;
+ else
+ args_addr = LLDB_INVALID_ADDRESS;
+
+ if (CompileFunction(errors) != 0)
+ return eExecutionSetupError;
+
+ if (args_addr == LLDB_INVALID_ADDRESS)
+ {
+ if (!InsertFunction(exc_context, args_addr, errors))
+ return eExecutionSetupError;
}
+
+ return_value = ClangFunction::ExecuteFunction(exc_context, m_wrapper_function_addr, args_addr, stop_others, try_all_threads, single_thread_timeout_usec, errors);
+ if (args_addr_ptr != NULL)
+ *args_addr_ptr = args_addr;
+
if (return_value != eExecutionCompleted)
return return_value;
OpenPOWER on IntegriCloud